whoami7 - Manager
:
/
var
/
tmp
/
Upload File:
files >> //var/tmp/php5kRi7f
<?php /** * Locale API * * @package WordPress * @subpackage i18n * @since 1.2.0 * @deprecated 4.7.0 */ _deprecated_file( basename( __FILE__ ), '4.7.0' ); <?php /** * WordPress API for media display. * * @package WordPress * @subpackage Media */ // Don't load directly. if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } /** * Retrieves additional image sizes. * * @since 4.7.0 * * @global array $_wp_additional_image_sizes * * @return array Additional images size data. */ function wp_get_additional_image_sizes() { global $_wp_additional_image_sizes; if ( ! $_wp_additional_image_sizes ) { $_wp_additional_image_sizes = array(); } return $_wp_additional_image_sizes; } /** * Scales down the default size of an image. * * This is so that the image is a better fit for the editor and theme. * * The `$size` parameter accepts either an array or a string. The supported string * values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at * 128 width and 96 height in pixels. Also supported for the string value is * 'medium', 'medium_large' and 'full'. The 'full' isn't actually supported, but any value other * than the supported will result in the content_width size or 500 if that is * not set. * * Finally, there is a filter named {@see 'editor_max_image_size'}, that will be * called on the calculated array for width and height, respectively. * * @since 2.5.0 * * @global int $content_width * * @param int $width Width of the image in pixels. * @param int $height Height of the image in pixels. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'medium'. * @param string $context Optional. Could be 'display' (like in a theme) or 'edit' * (like inserting into an editor). Default null. * @return int[] { * An array of width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } */ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) { global $content_width; $_wp_additional_image_sizes = wp_get_additional_image_sizes(); if ( ! $context ) { $context = is_admin() ? 'edit' : 'display'; } if ( is_array( $size ) ) { $max_width = $size[0]; $max_height = $size[1]; } elseif ( 'thumb' === $size || 'thumbnail' === $size ) { $max_width = (int) get_option( 'thumbnail_size_w' ); $max_height = (int) get_option( 'thumbnail_size_h' ); // Last chance thumbnail size defaults. if ( ! $max_width && ! $max_height ) { $max_width = 128; $max_height = 96; } } elseif ( 'medium' === $size ) { $max_width = (int) get_option( 'medium_size_w' ); $max_height = (int) get_option( 'medium_size_h' ); } elseif ( 'medium_large' === $size ) { $max_width = (int) get_option( 'medium_large_size_w' ); $max_height = (int) get_option( 'medium_large_size_h' ); if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } } elseif ( 'large' === $size ) { /* * We're inserting a large size image into the editor. If it's a really * big image we'll scale it down to fit reasonably within the editor * itself, and within the theme's content width if it's known. The user * can resize it in the editor if they wish. */ $max_width = (int) get_option( 'large_size_w' ); $max_height = (int) get_option( 'large_size_h' ); 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 ) ) { $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. if ( (int) $content_width > 0 && 'edit' === $context ) { $max_width = min( (int) $content_width, $max_width ); } } else { // $size === 'full' has no constraint. $max_width = $width; $max_height = $height; } /** * Filters the maximum image size dimensions for the editor. * * @since 2.5.0 * * @param int[] $max_image_size { * An array of width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string $context The context the image is being resized for. * Possible values are 'display' (like in a theme) * or 'edit' (like inserting into an editor). */ list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context ); return wp_constrain_dimensions( $width, $height, $max_width, $max_height ); } /** * Retrieves width and height attributes using given width and height values. * * Both attributes are required in the sense that both parameters must have a * value, but are optional in that if you set them to false or null, then they * will not be added to the returned string. * * You can set the value using a string, but it will only take numeric values. * If you wish to put 'px' after the numbers, then it will be stripped out of * the return. * * @since 2.5.0 * * @param int|string $width Image width in pixels. * @param int|string $height Image height in pixels. * @return string HTML attributes for width and, or height. */ function image_hwstring( $width, $height ) { $out = ''; if ( $width ) { $out .= 'width="' . (int) $width . '" '; } if ( $height ) { $out .= 'height="' . (int) $height . '" '; } return $out; } /** * Scales an image to fit a particular size (such as 'thumb' or 'medium'). * * The URL might be the original image, or it might be a resized version. This * function won't create a new resized copy, it will just return an already * resized one if it exists. * * A plugin may use the {@see 'image_downsize'} filter to hook into and offer image * resizing services for images. The hook must return an array with the same * elements that are normally returned from the function. * * @since 2.5.0 * * @param int $id Attachment ID for image. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'medium'. * @return array|false { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } */ function image_downsize( $id, $size = 'medium' ) { $is_image = wp_attachment_is_image( $id ); /** * Filters whether to preempt the output of image_downsize(). * * Returning a truthy value from the filter will effectively short-circuit * down-sizing the image, returning that value instead. * * @since 2.5.0 * * @param bool|array $downsize Whether to short-circuit the image downsize. * @param int $id Attachment ID for image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $out = apply_filters( 'image_downsize', false, $id, $size ); if ( $out ) { return $out; } $img_url = wp_get_attachment_url( $id ); $meta = wp_get_attachment_metadata( $id ); $width = 0; $height = 0; $is_intermediate = false; $img_url_basename = wp_basename( $img_url ); /* * If the file isn't an image, attempt to replace its URL with a rendered image from its meta. * Otherwise, a non-image type could be returned. */ if ( ! $is_image ) { if ( ! empty( $meta['sizes']['full'] ) ) { $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url ); $img_url_basename = $meta['sizes']['full']['file']; $width = $meta['sizes']['full']['width']; $height = $meta['sizes']['full']['height']; } else { return false; } } // Try for a new style intermediate size. $intermediate = image_get_intermediate_size( $id, $size ); if ( $intermediate ) { $img_url = str_replace( $img_url_basename, $intermediate['file'], $img_url ); $width = $intermediate['width']; $height = $intermediate['height']; $is_intermediate = true; } elseif ( 'thumbnail' === $size && ! empty( $meta['thumb'] ) && is_string( $meta['thumb'] ) ) { // Fall back to the old thumbnail. $imagefile = get_attached_file( $id ); $thumbfile = str_replace( wp_basename( $imagefile ), wp_basename( $meta['thumb'] ), $imagefile ); if ( file_exists( $thumbfile ) ) { $info = wp_getimagesize( $thumbfile ); if ( $info ) { $img_url = str_replace( $img_url_basename, wp_basename( $thumbfile ), $img_url ); $width = $info[0]; $height = $info[1]; $is_intermediate = true; } } } if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) { // Any other type: use the real image. $width = $meta['width']; $height = $meta['height']; } if ( $img_url ) { // We have the actual image size, but might need to further constrain it if content_width is narrower. list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size ); return array( $img_url, $width, $height, $is_intermediate ); } return false; } /** * Registers a new image size. * * @since 2.9.0 * * @global array $_wp_additional_image_sizes Associative array of additional image sizes. * * @param string $name Image size identifier. * @param int $width Optional. Image width in pixels. Default 0. * @param int $height Optional. Image height in pixels. Default 0. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } */ function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { global $_wp_additional_image_sizes; $_wp_additional_image_sizes[ $name ] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => $crop, ); } /** * Checks if an image size exists. * * @since 3.9.0 * * @param string $name The image size to check. * @return bool True if the image size exists, false if not. */ function has_image_size( $name ) { $sizes = wp_get_additional_image_sizes(); return isset( $sizes[ $name ] ); } /** * Removes a new image size. * * @since 3.9.0 * * @global array $_wp_additional_image_sizes * * @param string $name The image size to remove. * @return bool True if the image size was successfully removed, false on failure. */ function remove_image_size( $name ) { global $_wp_additional_image_sizes; if ( isset( $_wp_additional_image_sizes[ $name ] ) ) { unset( $_wp_additional_image_sizes[ $name ] ); return true; } return false; } /** * Registers an image size for the post thumbnail. * * @since 2.9.0 * * @see add_image_size() for details on cropping behavior. * * @param int $width Image width in pixels. * @param int $height Image height in pixels. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } */ function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { add_image_size( 'post-thumbnail', $width, $height, $crop ); } /** * Gets an img tag for an image attachment, scaling it down if requested. * * The {@see 'get_image_tag_class'} filter allows for changing the class name for the * image without having to use regular expressions on the HTML content. The * parameters are: what WordPress will use for the class, the Attachment ID, * image align value, and the size the image should be. * * The second filter, {@see 'get_image_tag'}, has the HTML content, which can then be * further manipulated by a plugin to change all attribute values and even HTML * content. * * @since 2.5.0 * * @param int $id Attachment ID. * @param string $alt Image description for the alt attribute. * @param string $title Image description for the title attribute. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @return string HTML IMG element for given image attachment. */ function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) { list( $img_src, $width, $height ) = image_downsize( $id, $size ); $hwstring = image_hwstring( $width, $height ); $title = $title ? 'title="' . esc_attr( $title ) . '" ' : ''; $size_class = is_array( $size ) ? implode( 'x', $size ) : $size; $class = 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size_class ) . ' wp-image-' . $id; /** * Filters the value of the attachment's image tag class attribute. * * @since 2.6.0 * * @param string $class CSS class name or space-separated list of classes. * @param int $id Attachment ID. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size ); $html = '<img src="' . esc_url( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />'; /** * Filters the HTML content for the image tag. * * @since 2.6.0 * * @param string $html HTML content for the image. * @param int $id Attachment ID. * @param string $alt Image description for the alt attribute. * @param string $title Image description for the title attribute. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ return apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); } /** * Calculates the new dimensions for a down-sampled image. * * If either width or height are empty, no constraint is applied on * that dimension. * * @since 2.5.0 * * @param int $current_width Current width of the image. * @param int $current_height Current height of the image. * @param int $max_width Optional. Max width in pixels to constrain to. Default 0. * @param int $max_height Optional. Max height in pixels to constrain to. Default 0. * @return int[] { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } */ function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) { if ( ! $max_width && ! $max_height ) { return array( $current_width, $current_height ); } $width_ratio = 1.0; $height_ratio = 1.0; $did_width = false; $did_height = false; if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { $width_ratio = $max_width / $current_width; $did_width = true; } if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) { $height_ratio = $max_height / $current_height; $did_height = true; } // Calculate the larger/smaller ratios. $smaller_ratio = min( $width_ratio, $height_ratio ); $larger_ratio = max( $width_ratio, $height_ratio ); if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) { // The larger ratio is too big. It would result in an overflow. $ratio = $smaller_ratio; } else { // The larger ratio fits, and is likely to be a more "snug" fit. $ratio = $larger_ratio; } // Very small dimensions may result in 0, 1 should be the minimum. $w = max( 1, (int) round( $current_width * $ratio ) ); $h = max( 1, (int) round( $current_height * $ratio ) ); /* * Sometimes, due to rounding, we'll end up with a result like this: * 465x700 in a 177x177 box is 117x176... a pixel short. * We also have issues with recursive calls resulting in an ever-changing result. * Constraining to the result of a constraint should yield the original result. * Thus we look for dimensions that are one pixel shy of the max value and bump them up. */ // Note: $did_width means it is possible $smaller_ratio == $width_ratio. if ( $did_width && $w === $max_width - 1 ) { $w = $max_width; // Round it up. } // Note: $did_height means it is possible $smaller_ratio == $height_ratio. if ( $did_height && $h === $max_height - 1 ) { $h = $max_height; // Round it up. } /** * Filters dimensions to constrain down-sampled images to. * * @since 4.1.0 * * @param int[] $dimensions { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param int $current_width The current width of the image. * @param int $current_height The current height of the image. * @param int $max_width The maximum width permitted. * @param int $max_height The maximum height permitted. */ return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height ); } /** * Retrieves calculated resize dimensions for use in WP_Image_Editor. * * Calculates dimensions and coordinates for a resized image that fits * within a specified width and height. * * @since 2.5.0 * * @param int $orig_w Original width in pixels. * @param int $orig_h Original height in pixels. * @param int $dest_w New width in pixels. * @param int $dest_h New height in pixels. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } * @return array|false Returned array matches parameters for `imagecopyresampled()`. False on failure. */ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) { if ( $orig_w <= 0 || $orig_h <= 0 ) { return false; } // At least one of $dest_w or $dest_h must be specific. if ( $dest_w <= 0 && $dest_h <= 0 ) { return false; } /** * Filters whether to preempt calculating the image resize dimensions. * * Returning a non-null value from the filter will effectively short-circuit * image_resize_dimensions(), returning that value instead. * * @since 3.4.0 * * @param null|mixed $null Whether to preempt output of the resize dimensions. * @param int $orig_w Original width in pixels. * @param int $orig_h Original height in pixels. * @param int $dest_w New width in pixels. * @param int $dest_h New height in pixels. * @param bool|array $crop Whether to crop image to specified width and height or resize. * An array can specify positioning of the crop area. Default false. */ $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); if ( null !== $output ) { return $output; } // Stop if the destination size is larger than the original image dimensions. if ( empty( $dest_h ) ) { if ( $orig_w < $dest_w ) { return false; } } elseif ( empty( $dest_w ) ) { if ( $orig_h < $dest_h ) { return false; } } else { if ( $orig_w < $dest_w && $orig_h < $dest_h ) { return false; } } if ( $crop ) { /* * Crop the largest possible portion of the original image that we can size to $dest_w x $dest_h. * Note that the requested crop dimensions are used as a maximum bounding box for the original image. * If the original image's width or height is less than the requested width or height * only the greater one will be cropped. * For example when the original image is 600x300, and the requested crop dimensions are 400x400, * the resulting image will be 400x300. */ $aspect_ratio = $orig_w / $orig_h; $new_w = min( $dest_w, $orig_w ); $new_h = min( $dest_h, $orig_h ); if ( ! $new_w ) { $new_w = (int) round( $new_h * $aspect_ratio ); } if ( ! $new_h ) { $new_h = (int) round( $new_w / $aspect_ratio ); } $size_ratio = max( $new_w / $orig_w, $new_h / $orig_h ); $crop_w = round( $new_w / $size_ratio ); $crop_h = round( $new_h / $size_ratio ); if ( ! is_array( $crop ) || count( $crop ) !== 2 ) { $crop = array( 'center', 'center' ); } list( $x, $y ) = $crop; if ( 'left' === $x ) { $s_x = 0; } elseif ( 'right' === $x ) { $s_x = $orig_w - $crop_w; } else { $s_x = floor( ( $orig_w - $crop_w ) / 2 ); } if ( 'top' === $y ) { $s_y = 0; } elseif ( 'bottom' === $y ) { $s_y = $orig_h - $crop_h; } else { $s_y = floor( ( $orig_h - $crop_h ) / 2 ); } } else { // Resize using $dest_w x $dest_h as a maximum bounding box. $crop_w = $orig_w; $crop_h = $orig_h; $s_x = 0; $s_y = 0; list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h ); } if ( wp_fuzzy_number_match( $new_w, $orig_w ) && wp_fuzzy_number_match( $new_h, $orig_h ) ) { // The new size has virtually the same dimensions as the original image. /** * Filters whether to proceed with making an image sub-size with identical dimensions * with the original/source image. Differences of 1px may be due to rounding and are ignored. * * @since 5.3.0 * * @param bool $proceed The filtered value. * @param int $orig_w Original image width. * @param int $orig_h Original image height. */ $proceed = (bool) apply_filters( 'wp_image_resize_identical_dimensions', false, $orig_w, $orig_h ); if ( ! $proceed ) { return false; } } /* * The return array matches the parameters to imagecopyresampled(). * int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h */ return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); } /** * Resizes an image to make a thumbnail or intermediate size. * * The returned array has the file size, the image width, and image height. The * {@see 'image_make_intermediate_size'} filter can be used to hook in and change the * values of the returned array. The only parameter is the resized file path. * * @since 2.5.0 * * @param string $file File path. * @param int $width Image width. * @param int $height Image height. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left', 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } * @return array|false Metadata array on success. False if no image was created. */ function image_make_intermediate_size( $file, $width, $height, $crop = false ) { if ( $width || $height ) { $editor = wp_get_image_editor( $file ); if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) { return false; } $resized_file = $editor->save(); if ( ! is_wp_error( $resized_file ) && $resized_file ) { unset( $resized_file['path'] ); return $resized_file; } } return false; } /** * Helper function to test if aspect ratios for two images match. * * @since 4.6.0 * * @param int $source_width Width of the first image in pixels. * @param int $source_height Height of the first image in pixels. * @param int $target_width Width of the second image in pixels. * @param int $target_height Height of the second image in pixels. * @return bool True if aspect ratios match within 1px. False if not. */ function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) { /* * To test for varying crops, we constrain the dimensions of the larger image * to the dimensions of the smaller image and see if they match. */ if ( $source_width > $target_width ) { $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width ); $expected_size = array( $target_width, $target_height ); } else { $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width ); $expected_size = array( $source_width, $source_height ); } // If the image dimensions are within 1px of the expected size, we consider it a match. $matched = ( wp_fuzzy_number_match( $constrained_size[0], $expected_size[0] ) && wp_fuzzy_number_match( $constrained_size[1], $expected_size[1] ) ); return $matched; } /** * Retrieves the image's intermediate size (resized) path, width, and height. * * The $size parameter can be an array with the width and height respectively. * If the size matches the 'sizes' metadata array for width and height, then it * will be used. If there is no direct match, then the nearest image size larger * than the specified size will be used. If nothing is found, then the function * will break out and return false. * * The metadata 'sizes' is used for compatible sizes that can be used for the * parameter $size value. * * The url path will be given, when the $size parameter is a string. * * If you are passing an array for the $size, you should consider using * add_image_size() so that a cropped version is generated. It's much more * efficient than having to find the closest-sized image and then having the * browser scale down the image. * * @since 2.5.0 * * @param int $post_id Attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @return array|false { * Array of file relative path, width, and height on success. Additionally includes absolute * path and URL if registered size is passed to `$size` parameter. False on failure. * * @type string $file Filename of image. * @type int $width Width of image in pixels. * @type int $height Height of image in pixels. * @type string $path Path of image relative to uploads directory. * @type string $url URL of image. * } */ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { $imagedata = wp_get_attachment_metadata( $post_id ); if ( ! $size || ! is_array( $imagedata ) || empty( $imagedata['sizes'] ) ) { return false; } $data = array(); // Find the best match when '$size' is an array. if ( is_array( $size ) ) { $candidates = array(); if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) { $imagedata['height'] = $imagedata['sizes']['full']['height']; $imagedata['width'] = $imagedata['sizes']['full']['width']; } foreach ( $imagedata['sizes'] as $_size => $data ) { // If there's an exact match to an existing image size, short circuit. if ( (int) $data['width'] === (int) $size[0] && (int) $data['height'] === (int) $size[1] ) { $candidates[ $data['width'] * $data['height'] ] = $data; break; } // If it's not an exact match, consider larger sizes with the same aspect ratio. if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { // If '0' is passed to either size, we test ratios against the original file. if ( 0 === $size[0] || 0 === $size[1] ) { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] ); } else { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ); } if ( $same_ratio ) { $candidates[ $data['width'] * $data['height'] ] = $data; } } } if ( ! empty( $candidates ) ) { // Sort the array by size if we have more than one candidate. if ( 1 < count( $candidates ) ) { ksort( $candidates ); } $data = array_shift( $candidates ); /* * When the size requested is smaller than the thumbnail dimensions, we * fall back to the thumbnail size to maintain backward compatibility with * pre 4.6 versions of WordPress. */ } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) { $data = $imagedata['sizes']['thumbnail']; } else { return false; } // Constrain the width and height attributes to the requested values. list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size ); } elseif ( ! empty( $imagedata['sizes'][ $size ] ) ) { $data = $imagedata['sizes'][ $size ]; } // If we still don't have a match at this point, return false. if ( empty( $data ) ) { return false; } // Include the full filesystem path of the intermediate file. if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) { $file_url = wp_get_attachment_url( $post_id ); $data['path'] = path_join( dirname( $imagedata['file'] ), $data['file'] ); $data['url'] = path_join( dirname( $file_url ), $data['file'] ); } /** * Filters the output of image_get_intermediate_size() * * @since 4.4.0 * * @see image_get_intermediate_size() * * @param array $data Array of file relative path, width, and height on success. May also include * file absolute path and URL. * @param int $post_id The ID of the image attachment. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); } /** * Gets the available intermediate image size names. * * @since 3.0.0 * * @return string[] An array of image size names. */ function get_intermediate_image_sizes() { $default_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' ); $additional_sizes = wp_get_additional_image_sizes(); if ( ! empty( $additional_sizes ) ) { $default_sizes = array_merge( $default_sizes, array_keys( $additional_sizes ) ); } /** * Filters the list of intermediate image sizes. * * @since 2.5.0 * * @param string[] $default_sizes An array of intermediate image size names. Defaults * are 'thumbnail', 'medium', 'medium_large', 'large'. */ return apply_filters( 'intermediate_image_sizes', $default_sizes ); } /** * Returns a normalized list of all currently registered image sub-sizes. * * @since 5.3.0 * @uses wp_get_additional_image_sizes() * @uses get_intermediate_image_sizes() * * @return array[] Associative array of arrays of image sub-size information, * keyed by image size name. */ function wp_get_registered_image_subsizes() { $additional_sizes = wp_get_additional_image_sizes(); $all_sizes = array(); foreach ( get_intermediate_image_sizes() as $size_name ) { $size_data = array( 'width' => 0, 'height' => 0, 'crop' => false, ); if ( isset( $additional_sizes[ $size_name ]['width'] ) ) { // For sizes added by plugins and themes. $size_data['width'] = (int) $additional_sizes[ $size_name ]['width']; } else { // For default sizes set in options. $size_data['width'] = (int) get_option( "{$size_name}_size_w" ); } if ( isset( $additional_sizes[ $size_name ]['height'] ) ) { $size_data['height'] = (int) $additional_sizes[ $size_name ]['height']; } else { $size_data['height'] = (int) get_option( "{$size_name}_size_h" ); } if ( empty( $size_data['width'] ) && empty( $size_data['height'] ) ) { // This size isn't set. continue; } if ( isset( $additional_sizes[ $size_name ]['crop'] ) ) { $size_data['crop'] = $additional_sizes[ $size_name ]['crop']; } else { $size_data['crop'] = get_option( "{$size_name}_crop" ); } if ( ! is_array( $size_data['crop'] ) || empty( $size_data['crop'] ) ) { $size_data['crop'] = (bool) $size_data['crop']; } $all_sizes[ $size_name ] = $size_data; } return $all_sizes; } /** * Retrieves an image to represent an attachment. * * @since 2.5.0 * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should fall back to a mime type icon. Default false. * @return array|false { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } */ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) { // Get a thumbnail or intermediate image if there is one. $image = image_downsize( $attachment_id, $size ); if ( ! $image ) { $src = false; if ( $icon ) { $src = wp_mime_type_icon( $attachment_id, '.svg' ); if ( $src ) { /** This filter is documented in wp-includes/post.php */ $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); $src_file = $icon_dir . '/' . wp_basename( $src ); list( $width, $height ) = wp_getimagesize( $src_file ); $ext = strtolower( substr( $src_file, -4 ) ); if ( '.svg' === $ext ) { // SVG does not have true dimensions, so this assigns width and height directly. $width = 48; $height = 64; } else { list( $width, $height ) = wp_getimagesize( $src_file ); } } } if ( $src && $width && $height ) { $image = array( $src, $width, $height, false ); } } /** * Filters the attachment image source result. * * @since 4.3.0 * * @param array|false $image { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } * @param int $attachment_id Image attachment ID. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param bool $icon Whether the image should be treated as an icon. */ return apply_filters( 'wp_get_attachment_image_src', $image, $attachment_id, $size, $icon ); } /** * Gets an HTML img element representing an image attachment. * * While `$size` will accept an array, it is better to register a size with * add_image_size() so that a cropped version is generated. It's much more * efficient than having to find the closest-sized image and then having the * browser scale down the image. * * @since 2.5.0 * @since 4.4.0 The `$srcset` and `$sizes` attributes were added. * @since 5.5.0 The `$loading` attribute was added. * @since 6.1.0 The `$decoding` attribute was added. * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should be treated as an icon. Default false. * @param string|array $attr { * Optional. Attributes for the image markup. * * @type string $src Image attachment URL. * @type string $class CSS class name or space-separated list of classes. * Default `attachment-$size_class size-$size_class`, * where `$size_class` is the image size being requested. * @type string $alt Image description for the alt attribute. * @type string $srcset The 'srcset' attribute value. * @type string $sizes The 'sizes' attribute value. * @type string|false $loading The 'loading' attribute value. Passing a value of false * will result in the attribute being omitted for the image. * Default determined by {@see wp_get_loading_optimization_attributes()}. * @type string $decoding The 'decoding' attribute value. Possible values are * 'async' (default), 'sync', or 'auto'. Passing false or an empty * string will result in the attribute being omitted. * @type string $fetchpriority The 'fetchpriority' attribute value, whether `high`, `low`, or `auto`. * Default determined by {@see wp_get_loading_optimization_attributes()}. * } * @return string HTML img element or empty string on failure. */ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) { $html = ''; $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); if ( $image ) { list( $src, $width, $height ) = $image; $attachment = get_post( $attachment_id ); $size_class = $size; if ( is_array( $size_class ) ) { $size_class = implode( 'x', $size_class ); } $default_attr = array( 'src' => $src, 'class' => "attachment-$size_class size-$size_class", 'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), ); /** * Filters the context in which wp_get_attachment_image() is used. * * @since 6.3.0 * * @param string $context The context. Default 'wp_get_attachment_image'. */ $context = apply_filters( 'wp_get_attachment_image_context', 'wp_get_attachment_image' ); $attr = wp_parse_args( $attr, $default_attr ); $attr['width'] = $width; $attr['height'] = $height; $loading_optimization_attr = wp_get_loading_optimization_attributes( 'img', $attr, $context ); // Add loading optimization attributes if not available. $attr = array_merge( $attr, $loading_optimization_attr ); // Omit the `decoding` attribute if the value is invalid according to the spec. if ( empty( $attr['decoding'] ) || ! in_array( $attr['decoding'], array( 'async', 'sync', 'auto' ), true ) ) { unset( $attr['decoding'] ); } /* * If the default value of `lazy` for the `loading` attribute is overridden * to omit the attribute for this image, ensure it is not included. */ if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } // If the `fetchpriority` attribute is overridden and set to false or an empty string. if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } // Generate 'srcset' and 'sizes' if not already present. if ( empty( $attr['srcset'] ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( is_array( $image_meta ) ) { $size_array = array( absint( $width ), absint( $height ) ); $srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id ); $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id ); if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) { $attr['srcset'] = $srcset; if ( empty( $attr['sizes'] ) ) { $attr['sizes'] = $sizes; } } } } /** This filter is documented in wp-includes/media.php */ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); // Adds 'auto' to the sizes attribute if applicable. if ( $add_auto_sizes && isset( $attr['loading'] ) && 'lazy' === $attr['loading'] && isset( $attr['sizes'] ) && ! wp_sizes_attribute_includes_valid_auto( $attr['sizes'] ) ) { $attr['sizes'] = 'auto, ' . $attr['sizes']; } /** * Filters the list of attachment image attributes. * * @since 2.8.0 * * @param string[] $attr Array of attribute values for the image markup, keyed by attribute name. * See wp_get_attachment_image(). * @param WP_Post $attachment Image attachment post. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size ); if ( isset( $attr['height'] ) && is_numeric( $attr['height'] ) ) { $height = absint( $attr['height'] ); } if ( isset( $attr['width'] ) && is_numeric( $attr['width'] ) ) { $width = absint( $attr['width'] ); } unset( $attr['height'], $attr['width'] ); $attr = array_map( 'esc_attr', $attr ); $hwstring = image_hwstring( $width, $height ); $html = rtrim( "<img $hwstring" ); foreach ( $attr as $name => $value ) { $html .= " $name=" . '"' . $value . '"'; } $html .= ' />'; } /** * Filters the HTML img element representing an image attachment. * * @since 5.6.0 * * @param string $html HTML img element or empty string on failure. * @param int $attachment_id Image attachment ID. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param bool $icon Whether the image should be treated as an icon. * @param string[] $attr Array of attribute values for the image markup, keyed by attribute name. * See wp_get_attachment_image(). */ return apply_filters( 'wp_get_attachment_image', $html, $attachment_id, $size, $icon, $attr ); } /** * Gets the URL of an image attachment. * * @since 4.4.0 * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should be treated as an icon. Default false. * @return string|false Attachment URL or false if no image is available. If `$size` does not match * any registered image size, the original image URL will be returned. */ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) { $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); return isset( $image[0] ) ? $image[0] : false; } /** * Gets the attachment path relative to the upload directory. * * @since 4.4.1 * @access private * * @param string $file Attachment file name. * @return string Attachment path relative to the upload directory. */ function _wp_get_attachment_relative_path( $file ) { $dirname = dirname( $file ); if ( '.' === $dirname ) { return ''; } if ( str_contains( $dirname, 'wp-content/uploads' ) ) { // Get the directory name relative to the upload directory (back compat for pre-2.7 uploads). $dirname = substr( $dirname, strpos( $dirname, 'wp-content/uploads' ) + 18 ); $dirname = ltrim( $dirname, '/' ); } return $dirname; } /** * Gets the image size as array from its meta data. * * Used for responsive images. * * @since 4.4.0 * @access private * * @param string $size_name Image size. Accepts any registered image size name. * @param array $image_meta The image meta data. * @return array|false { * Array of width and height or false if the size isn't present in the meta data. * * @type int $0 Image width. * @type int $1 Image height. * } */ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { if ( 'full' === $size_name ) { return array( absint( $image_meta['width'] ), absint( $image_meta['height'] ), ); } elseif ( ! empty( $image_meta['sizes'][ $size_name ] ) ) { return array( absint( $image_meta['sizes'][ $size_name ]['width'] ), absint( $image_meta['sizes'][ $size_name ]['height'] ), ); } return false; } /** * Retrieves the value for an image attachment's 'srcset' attribute. * * @since 4.4.0 * * @see wp_calculate_image_srcset() * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @return string|false A 'srcset' value string or false. */ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size ); if ( ! $image ) { return false; } if ( ! is_array( $image_meta ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; $size_array = array( absint( $image[1] ), absint( $image[2] ), ); return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id ); } /** * A helper function to calculate the image sources to include in a 'srcset' attribute. * * @since 4.4.0 * * @param int[] $size_array { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return string|false The 'srcset' attribute value. False on error or when only one source exists. */ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) { /** * Pre-filters the image meta to be able to fix inconsistencies in the stored data. * * @since 4.5.0 * * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int[] $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param int $attachment_id The image attachment ID or 0 if not supplied. */ $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id ); if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) { return false; } $image_sizes = $image_meta['sizes']; // Get the width and height of the image. $image_width = (int) $size_array[0]; $image_height = (int) $size_array[1]; // Bail early if error/no width. if ( $image_width < 1 ) { return false; } $image_basename = wp_basename( $image_meta['file'] ); /* * WordPress flattens animated GIFs into one frame when generating intermediate sizes. * To avoid hiding animation in user content, if src is a full size GIF, a srcset attribute is not generated. * If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated. */ if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) { $image_sizes[] = array( 'width' => $image_meta['width'], 'height' => $image_meta['height'], 'file' => $image_basename, ); } elseif ( str_contains( $image_src, $image_meta['file'] ) ) { return false; } // Retrieve the uploads sub-directory from the full size image. $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); if ( $dirname ) { $dirname = trailingslashit( $dirname ); } $upload_dir = wp_get_upload_dir(); $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname; /* * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain * (which is to say, when they share the domain name of the current request). */ if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) ) { /* * Since the `Host:` header might contain a port, it should * be compared against the image URL using the same port. */ $parsed = parse_url( $image_baseurl ); $domain = isset( $parsed['host'] ) ? $parsed['host'] : ''; if ( isset( $parsed['port'] ) ) { $domain .= ':' . $parsed['port']; } if ( $_SERVER['HTTP_HOST'] === $domain ) { $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); } } /* * Images that have been edited in WordPress after being uploaded will * contain a unique hash. Look for that hash and use it later to filter * out images that are leftovers from previous versions. */ $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash ); /** * Filters the maximum image width to be included in a 'srcset' attribute. * * @since 4.4.0 * * @param int $max_width The maximum image width to be included in the 'srcset'. Default '2048'. * @param int[] $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } */ $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 2048, $size_array ); // Array to hold URL candidates. $sources = array(); /** * To make sure the ID matches our image src, we will check to see if any sizes in our attachment * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving * an incorrect image. See #35045. */ $src_matched = false; /* * Loop through available images. Only use images that are resized * versions of the same edit. */ foreach ( $image_sizes as $image ) { $is_src = false; // Check if image meta isn't corrupted. if ( ! is_array( $image ) ) { continue; } // If the file name is part of the `src`, we've confirmed a match. if ( ! $src_matched && str_contains( $image_src, $dirname . $image['file'] ) ) { $src_matched = true; $is_src = true; } // Filter out images that are from previous edits. if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { continue; } /* * Filters out images that are wider than '$max_srcset_image_width' unless * that file is in the 'src' attribute. */ if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) { continue; } // If the image dimensions are within 1px of the expected size, use it. if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) { // Add the URL, descriptor, and value to the sources array to be returned. $source = array( 'url' => $image_baseurl . $image['file'], 'descriptor' => 'w', 'value' => $image['width'], ); // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030. if ( $is_src ) { $sources = array( $image['width'] => $source ) + $sources; } else { $sources[ $image['width'] ] = $source; } } } /** * Filters an image's 'srcset' sources. * * @since 4.4.0 * * @param array $sources { * One or more arrays of source data to include in the 'srcset'. * * @type array $width { * @type string $url The URL of an image source. * @type string $descriptor The descriptor type used in the image candidate string, * either 'w' or 'x'. * @type int $value The source width if paired with a 'w' descriptor, or a * pixel density value if paired with an 'x' descriptor. * } * } * @param array $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID or 0. */ $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id ); // Only return a 'srcset' value if there is more than one source. if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) { return false; } $srcset = ''; foreach ( $sources as $source ) { $srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', '; } return rtrim( $srcset, ', ' ); } /** * Retrieves the value for an image attachment's 'sizes' attribute. * * @since 4.4.0 * * @see wp_calculate_image_sizes() * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @return string|false A valid source size value for use in a 'sizes' attribute or false. */ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size ); if ( ! $image ) { return false; } if ( ! is_array( $image_meta ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } $image_src = $image[0]; $size_array = array( absint( $image[1] ), absint( $image[2] ), ); return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id ); } /** * Creates a 'sizes' attribute value for an image. * * @since 4.4.0 * * @param string|int[] $size Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). * @param string|null $image_src Optional. The URL to the image file. Default null. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` * is needed when using the image size name as argument for `$size`. Default 0. * @return string|false A valid source size value for use in a 'sizes' attribute or false. */ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0 ) { $width = 0; if ( is_array( $size ) ) { $width = absint( $size[0] ); } elseif ( is_string( $size ) ) { if ( ! $image_meta && $attachment_id ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); } if ( is_array( $image_meta ) ) { $size_array = _wp_get_image_size_from_meta( $size, $image_meta ); if ( $size_array ) { $width = absint( $size_array[0] ); } } } if ( ! $width ) { return false; } // Setup the default 'sizes' attribute. $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width ); /** * Filters the output of 'wp_calculate_image_sizes()'. * * @since 4.4.0 * * @param string $sizes A source size value for use in a 'sizes' attribute. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string|null $image_src The URL to the image file or null. * @param array|null $image_meta The image meta data as returned by wp_get_attachment_metadata() or null. * @param int $attachment_id Image attachment ID of the original image or 0. */ return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id ); } /** * Determines if the image meta data is for the image source file. * * The image meta data is retrieved by attachment post ID. In some cases the post IDs may change. * For example when the website is exported and imported at another website. Then the * attachment post IDs that are in post_content for the exported website may not match * the same attachments at the new website. * * @since 5.5.0 * * @param string $image_location The full path or URI to the image file. * @param array $image_meta The attachment meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return bool Whether the image meta is for this image file. */ function wp_image_file_matches_image_meta( $image_location, $image_meta, $attachment_id = 0 ) { $match = false; // Ensure the $image_meta is valid. if ( isset( $image_meta['file'] ) && strlen( $image_meta['file'] ) > 4 ) { // Remove query args in image URI. list( $image_location ) = explode( '?', $image_location ); // Check if the relative image path from the image meta is at the end of $image_location. if ( strrpos( $image_location, $image_meta['file'] ) === strlen( $image_location ) - strlen( $image_meta['file'] ) ) { $match = true; } else { // Retrieve the uploads sub-directory from the full size image. $dirname = _wp_get_attachment_relative_path( $image_meta['file'] ); if ( $dirname ) { $dirname = trailingslashit( $dirname ); } if ( ! empty( $image_meta['original_image'] ) ) { $relative_path = $dirname . $image_meta['original_image']; if ( strrpos( $image_location, $relative_path ) === strlen( $image_location ) - strlen( $relative_path ) ) { $match = true; } } if ( ! $match && ! empty( $image_meta['sizes'] ) ) { foreach ( $image_meta['sizes'] as $image_size_data ) { $relative_path = $dirname . $image_size_data['file']; if ( strrpos( $image_location, $relative_path ) === strlen( $image_location ) - strlen( $relative_path ) ) { $match = true; break; } } } } } /** * Filters whether an image path or URI matches image meta. * * @since 5.5.0 * * @param bool $match Whether the image relative path from the image meta * matches the end of the URI or path to the image file. * @param string $image_location Full path or URI to the tested image file. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id The image attachment ID or 0 if not supplied. */ return apply_filters( 'wp_image_file_matches_image_meta', $match, $image_location, $image_meta, $attachment_id ); } /** * Determines an image's width and height dimensions based on the source file. * * @since 5.5.0 * * @param string $image_src The image source file. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return array|false Array with first element being the width and second element being the height, * or false if dimensions cannot be determined. */ function wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id = 0 ) { $dimensions = false; // Is it a full size image? if ( isset( $image_meta['file'] ) && str_contains( $image_src, wp_basename( $image_meta['file'] ) ) ) { $dimensions = array( (int) $image_meta['width'], (int) $image_meta['height'], ); } if ( ! $dimensions && ! empty( $image_meta['sizes'] ) ) { $src_filename = wp_basename( $image_src ); foreach ( $image_meta['sizes'] as $image_size_data ) { if ( $src_filename === $image_size_data['file'] ) { $dimensions = array( (int) $image_size_data['width'], (int) $image_size_data['height'], ); break; } } } /** * Filters the 'wp_image_src_get_dimensions' value. * * @since 5.7.0 * * @param array|false $dimensions Array with first element being the width * and second element being the height, or * false if dimensions could not be determined. * @param string $image_src The image source file. * @param array $image_meta The image meta data as returned by * 'wp_get_attachment_metadata()'. * @param int $attachment_id The image attachment ID. Default 0. */ return apply_filters( 'wp_image_src_get_dimensions', $dimensions, $image_src, $image_meta, $attachment_id ); } /** * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. * * @since 4.4.0 * * @see wp_calculate_image_srcset() * @see wp_calculate_image_sizes() * * @param string $image An HTML 'img' element to be filtered. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. */ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { // Ensure the image meta exists. if ( empty( $image_meta['sizes'] ) ) { return $image; } $image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; list( $image_src ) = explode( '?', $image_src ); // Return early if we couldn't get the image source. if ( ! $image_src ) { return $image; } // Bail early if an image has been inserted and later edited. if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && ! str_contains( wp_basename( $image_src ), $img_edit_hash[0] ) ) { return $image; } $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; if ( $width && $height ) { $size_array = array( $width, $height ); } else { $size_array = wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id ); if ( ! $size_array ) { return $image; } } $srcset = wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id ); if ( $srcset ) { // Check if there is already a 'sizes' attribute. $sizes = strpos( $image, ' sizes=' ); if ( ! $sizes ) { $sizes = wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id ); } } if ( $srcset && $sizes ) { // Format the 'srcset' and 'sizes' string and escape attributes. $attr = sprintf( ' srcset="%s"', esc_attr( $srcset ) ); if ( is_string( $sizes ) ) { $attr .= sprintf( ' sizes="%s"', esc_attr( $sizes ) ); } // Add the srcset and sizes attributes to the image markup. return preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $attr . ' />', $image ); } return $image; } /** * Determines whether to add the `loading` attribute to the specified tag in the specified context. * * @since 5.5.0 * @since 5.7.0 Now returns `true` by default for `iframe` tags. * * @param string $tag_name The tag name. * @param string $context Additional context, like the current filter name * or the function name from where this was called. * @return bool Whether to add the attribute. */ function wp_lazy_loading_enabled( $tag_name, $context ) { /* * By default add to all 'img' and 'iframe' tags. * See https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-loading * See https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-loading */ $default = ( 'img' === $tag_name || 'iframe' === $tag_name ); /** * Filters whether to add the `loading` attribute to the specified tag in the specified context. * * @since 5.5.0 * * @param bool $default Default value. * @param string $tag_name The tag name. * @param string $context Additional context, like the current filter name * or the function name from where this was called. */ return (bool) apply_filters( 'wp_lazy_loading_enabled', $default, $tag_name, $context ); } /** * Filters specific tags in post content and modifies their markup. * * Modifies HTML tags in post content to include new browser and HTML technologies * that may not have existed at the time of post creation. These modifications currently * include adding `srcset`, `sizes`, and `loading` attributes to `img` HTML tags, as well * as adding `loading` attributes to `iframe` HTML tags. * Future similar optimizations should be added/expected here. * * @since 5.5.0 * @since 5.7.0 Now supports adding `loading` attributes to `iframe` tags. * * @see wp_img_tag_add_width_and_height_attr() * @see wp_img_tag_add_srcset_and_sizes_attr() * @see wp_img_tag_add_loading_optimization_attrs() * @see wp_iframe_tag_add_loading_attr() * * @param string $content The HTML content to be filtered. * @param string $context Optional. Additional context to pass to the filters. * Defaults to `current_filter()` when not set. * @return string Converted content with images modified. */ function wp_filter_content_tags( $content, $context = null ) { if ( null === $context ) { $context = current_filter(); } $add_iframe_loading_attr = wp_lazy_loading_enabled( 'iframe', $context ); if ( ! preg_match_all( '/<(img|iframe)\s[^>]+>/', $content, $matches, PREG_SET_ORDER ) ) { return $content; } // List of the unique `img` tags found in $content. $images = array(); // List of the unique `iframe` tags found in $content. $iframes = array(); foreach ( $matches as $match ) { list( $tag, $tag_name ) = $match; switch ( $tag_name ) { case 'img': if ( preg_match( '/wp-image-([0-9]+)/i', $tag, $class_id ) ) { $attachment_id = absint( $class_id[1] ); if ( $attachment_id ) { /* * If exactly the same image tag is used more than once, overwrite it. * All identical tags will be replaced later with 'str_replace()'. */ $images[ $tag ] = $attachment_id; break; } } $images[ $tag ] = 0; break; case 'iframe': $iframes[ $tag ] = 0; break; } } // Reduce the array to unique attachment IDs. $attachment_ids = array_unique( array_filter( array_values( $images ) ) ); if ( count( $attachment_ids ) > 1 ) { /* * Warm the object cache with post and meta information for all found * images to avoid making individual database calls. */ _prime_post_caches( $attachment_ids, false, true ); } // Iterate through the matches in order of occurrence as it is relevant for whether or not to lazy-load. foreach ( $matches as $match ) { // Filter an image match. if ( isset( $images[ $match[0] ] ) ) { $filtered_image = $match[0]; $attachment_id = $images[ $match[0] ]; // Add 'width' and 'height' attributes if applicable. if ( $attachment_id > 0 && ! str_contains( $filtered_image, ' width=' ) && ! str_contains( $filtered_image, ' height=' ) ) { $filtered_image = wp_img_tag_add_width_and_height_attr( $filtered_image, $context, $attachment_id ); } // Add 'srcset' and 'sizes' attributes if applicable. if ( $attachment_id > 0 && ! str_contains( $filtered_image, ' srcset=' ) ) { $filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id ); } // Add loading optimization attributes if applicable. $filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context ); // Adds 'auto' to the sizes attribute if applicable. $filtered_image = wp_img_tag_add_auto_sizes( $filtered_image ); /** * Filters an img tag within the content for a given context. * * @since 6.0.0 * * @param string $filtered_image Full img tag with attributes that will replace the source img tag. * @param string $context Additional context, like the current filter name or the function name from where this was called. * @param int $attachment_id The image attachment ID. May be 0 in case the image is not an attachment. */ $filtered_image = apply_filters( 'wp_content_img_tag', $filtered_image, $context, $attachment_id ); if ( $filtered_image !== $match[0] ) { $content = str_replace( $match[0], $filtered_image, $content ); } /* * Unset image lookup to not run the same logic again unnecessarily if the same image tag is used more than * once in the same blob of content. */ unset( $images[ $match[0] ] ); } // Filter an iframe match. if ( isset( $iframes[ $match[0] ] ) ) { $filtered_iframe = $match[0]; // Add 'loading' attribute if applicable. if ( $add_iframe_loading_attr && ! str_contains( $filtered_iframe, ' loading=' ) ) { $filtered_iframe = wp_iframe_tag_add_loading_attr( $filtered_iframe, $context ); } if ( $filtered_iframe !== $match[0] ) { $content = str_replace( $match[0], $filtered_iframe, $content ); } /* * Unset iframe lookup to not run the same logic again unnecessarily if the same iframe tag is used more * than once in the same blob of content. */ unset( $iframes[ $match[0] ] ); } } return $content; } /** * Adds 'auto' to the sizes attribute to the image, if the image is lazy loaded and does not already include it. * * @since 6.7.0 * * @param string $image The image tag markup being filtered. * @return string The filtered image tag markup. */ function wp_img_tag_add_auto_sizes( string $image ): string { /** * Filters whether auto-sizes for lazy loaded images is enabled. * * @since 6.7.1 * * @param boolean $enabled Whether auto-sizes for lazy loaded images is enabled. */ if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) { return $image; } $processor = new WP_HTML_Tag_Processor( $image ); // Bail if there is no IMG tag. if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) { return $image; } // Bail early if the image is not lazy-loaded. $loading = $processor->get_attribute( 'loading' ); if ( ! is_string( $loading ) || 'lazy' !== strtolower( trim( $loading, " \t\f\r\n" ) ) ) { return $image; } /* * Bail early if the image doesn't have a width attribute. * Per WordPress Core itself, lazy-loaded images should always have a width attribute. * However, it is possible that lazy-loading could be added by a plugin, where we don't have that guarantee. * As such, it still makes sense to ensure presence of a width attribute here in order to use `sizes=auto`. */ $width = $processor->get_attribute( 'width' ); if ( ! is_string( $width ) || '' === $width ) { return $image; } $sizes = $processor->get_attribute( 'sizes' ); // Bail early if the image is not responsive. if ( ! is_string( $sizes ) ) { return $image; } // Don't add 'auto' to the sizes attribute if it already exists. if ( wp_sizes_attribute_includes_valid_auto( $sizes ) ) { return $image; } $processor->set_attribute( 'sizes', "auto, $sizes" ); return $processor->get_updated_html(); } /** * Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list. * * Per the HTML spec, if present it must be the first entry. * * @since 6.7.0 * * @param string $sizes_attr The 'sizes' attribute value. * @return bool True if the 'auto' keyword is present, false otherwise. */ function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool { list( $first_size ) = explode( ',', $sizes_attr, 2 ); return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) ); } /** * Prints a CSS rule to fix potential visual issues with images using `sizes=auto`. * * This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g. * `width: auto` or `width: fit-content` to appear smaller. * * @since 6.7.1 * @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size * @see https://core.trac.wordpress.org/ticket/62413 */ function wp_print_auto_sizes_contain_css_fix() { /** This filter is documented in wp-includes/media.php */ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); if ( ! $add_auto_sizes ) { return; } ?> <style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style> <?php } /** * Adds optimization attributes to an `img` HTML tag. * * @since 6.3.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @return string Converted `img` tag with optimization attributes added. */ function wp_img_tag_add_loading_optimization_attrs( $image, $context ) { $src = preg_match( '/ src=["\']?([^"\']*)/i', $image, $matche_src ) ? $matche_src[1] : null; $width = preg_match( '/ width=["\']([0-9]+)["\']/', $image, $match_width ) ? (int) $match_width[1] : null; $height = preg_match( '/ height=["\']([0-9]+)["\']/', $image, $match_height ) ? (int) $match_height[1] : null; $loading_val = preg_match( '/ loading=["\']([A-Za-z]+)["\']/', $image, $match_loading ) ? $match_loading[1] : null; $fetchpriority_val = preg_match( '/ fetchpriority=["\']([A-Za-z]+)["\']/', $image, $match_fetchpriority ) ? $match_fetchpriority[1] : null; $decoding_val = preg_match( '/ decoding=["\']([A-Za-z]+)["\']/', $image, $match_decoding ) ? $match_decoding[1] : null; /* * Get loading optimization attributes to use. * This must occur before the conditional check below so that even images * that are ineligible for being lazy-loaded are considered. */ $optimization_attrs = wp_get_loading_optimization_attributes( 'img', array( 'src' => $src, 'width' => $width, 'height' => $height, 'loading' => $loading_val, 'fetchpriority' => $fetchpriority_val, 'decoding' => $decoding_val, ), $context ); // Images should have source for the loading optimization attributes to be added. if ( ! str_contains( $image, ' src="' ) ) { return $image; } if ( empty( $decoding_val ) ) { /** * Filters the `decoding` attribute value to add to an image. Default `async`. * * Returning a falsey value will omit the attribute. * * @since 6.1.0 * * @param string|false|null $value The `decoding` attribute value. Returning a falsey value * will result in the attribute being omitted for the image. * Otherwise, it may be: 'async', 'sync', or 'auto'. Defaults to false. * @param string $image The HTML `img` tag to be filtered. * @param string $context Additional context about how the function was called * or where the img tag is. */ $filtered_decoding_attr = apply_filters( 'wp_img_tag_add_decoding_attr', isset( $optimization_attrs['decoding'] ) ? $optimization_attrs['decoding'] : false, $image, $context ); // Validate the values after filtering. if ( isset( $optimization_attrs['decoding'] ) && ! $filtered_decoding_attr ) { // Unset `decoding` attribute if `$filtered_decoding_attr` is set to `false`. unset( $optimization_attrs['decoding'] ); } elseif ( in_array( $filtered_decoding_attr, array( 'async', 'sync', 'auto' ), true ) ) { $optimization_attrs['decoding'] = $filtered_decoding_attr; } if ( ! empty( $optimization_attrs['decoding'] ) ) { $image = str_replace( '<img', '<img decoding="' . esc_attr( $optimization_attrs['decoding'] ) . '"', $image ); } } // Images should have dimension attributes for the 'loading' and 'fetchpriority' attributes to be added. if ( ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) { return $image; } // Retained for backward compatibility. $loading_attrs_enabled = wp_lazy_loading_enabled( 'img', $context ); if ( empty( $loading_val ) && $loading_attrs_enabled ) { /** * Filters the `loading` attribute value to add to an image. Default `lazy`. * * Returning `false` or an empty string will not add the attribute. * Returning `true` will add the default value. * * @since 5.5.0 * * @param string|bool $value The `loading` attribute value. Returning a falsey value will result in * the attribute being omitted for the image. * @param string $image The HTML `img` tag to be filtered. * @param string $context Additional context about how the function was called or where the img tag is. */ $filtered_loading_attr = apply_filters( 'wp_img_tag_add_loading_attr', isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false, $image, $context ); // Validate the values after filtering. if ( isset( $optimization_attrs['loading'] ) && ! $filtered_loading_attr ) { // Unset `loading` attributes if `$filtered_loading_attr` is set to `false`. unset( $optimization_attrs['loading'] ); } elseif ( in_array( $filtered_loading_attr, array( 'lazy', 'eager' ), true ) ) { /* * If the filter changed the loading attribute to "lazy" when a fetchpriority attribute * with value "high" is already present, trigger a warning since those two attribute * values should be mutually exclusive. * * The same warning is present in `wp_get_loading_optimization_attributes()`, and here it * is only intended for the specific scenario where the above filtered caused the problem. */ if ( isset( $optimization_attrs['fetchpriority'] ) && 'high' === $optimization_attrs['fetchpriority'] && ( isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false ) !== $filtered_loading_attr && 'lazy' === $filtered_loading_attr ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); } // The filtered value will still be respected. $optimization_attrs['loading'] = $filtered_loading_attr; } if ( ! empty( $optimization_attrs['loading'] ) ) { $image = str_replace( '<img', '<img loading="' . esc_attr( $optimization_attrs['loading'] ) . '"', $image ); } } if ( empty( $fetchpriority_val ) && ! empty( $optimization_attrs['fetchpriority'] ) ) { $image = str_replace( '<img', '<img fetchpriority="' . esc_attr( $optimization_attrs['fetchpriority'] ) . '"', $image ); } return $image; } /** * Adds `width` and `height` attributes to an `img` HTML tag. * * @since 5.5.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'width' and 'height' attributes added. */ function wp_img_tag_add_width_and_height_attr( $image, $context, $attachment_id ) { $image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; list( $image_src ) = explode( '?', $image_src ); // Return early if we couldn't get the image source. if ( ! $image_src ) { return $image; } /** * Filters whether to add the missing `width` and `height` HTML attributes to the img tag. Default `true`. * * Returning anything else than `true` will not add the attributes. * * @since 5.5.0 * * @param bool $value The filtered value, defaults to `true`. * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context about how the function was called or where the img tag is. * @param int $attachment_id The image attachment ID. */ $add = apply_filters( 'wp_img_tag_add_width_and_height_attr', true, $image, $context, $attachment_id ); if ( true === $add ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); $size_array = wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id ); if ( $size_array && $size_array[0] && $size_array[1] ) { // If the width is enforced through style (e.g. in an inline image), calculate the dimension attributes. $style_width = preg_match( '/style="width:\s*(\d+)px;"/', $image, $match_width ) ? (int) $match_width[1] : 0; if ( $style_width ) { $size_array[1] = (int) round( $size_array[1] * $style_width / $size_array[0] ); $size_array[0] = $style_width; } $hw = trim( image_hwstring( $size_array[0], $size_array[1] ) ); return str_replace( '<img', "<img {$hw}", $image ); } } return $image; } /** * Adds `srcset` and `sizes` attributes to an existing `img` HTML tag. * * @since 5.5.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'loading' attribute added. */ function wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id ) { /** * Filters whether to add the `srcset` and `sizes` HTML attributes to the img tag. Default `true`. * * Returning anything else than `true` will not add the attributes. * * @since 5.5.0 * * @param bool $value The filtered value, defaults to `true`. * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context about how the function was called or where the img tag is. * @param int $attachment_id The image attachment ID. */ $add = apply_filters( 'wp_img_tag_add_srcset_and_sizes_attr', true, $image, $context, $attachment_id ); if ( true === $add ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); return wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ); } return $image; } /** * Adds `loading` attribute to an `iframe` HTML tag. * * @since 5.7.0 * * @param string $iframe The HTML `iframe` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @return string Converted `iframe` tag with `loading` attribute added. */ function wp_iframe_tag_add_loading_attr( $iframe, $context ) { /* * Get loading attribute value to use. This must occur before the conditional check below so that even iframes that * are ineligible for being lazy-loaded are considered. */ $optimization_attrs = wp_get_loading_optimization_attributes( 'iframe', array( /* * The concrete values for width and height are not important here for now * since fetchpriority is not yet supported for iframes. * TODO: Use WP_HTML_Tag_Processor to extract actual values once support is * added. */ 'width' => str_contains( $iframe, ' width="' ) ? 100 : null, 'height' => str_contains( $iframe, ' height="' ) ? 100 : null, // This function is never called when a 'loading' attribute is already present. 'loading' => null, ), $context ); // Iframes should have source and dimension attributes for the `loading` attribute to be added. if ( ! str_contains( $iframe, ' src="' ) || ! str_contains( $iframe, ' width="' ) || ! str_contains( $iframe, ' height="' ) ) { return $iframe; } $value = isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false; /** * Filters the `loading` attribute value to add to an iframe. Default `lazy`. * * Returning `false` or an empty string will not add the attribute. * Returning `true` will add the default value. * * @since 5.7.0 * * @param string|bool $value The `loading` attribute value. Returning a falsey value will result in * the attribute being omitted for the iframe. * @param string $iframe The HTML `iframe` tag to be filtered. * @param string $context Additional context about how the function was called or where the iframe tag is. */ $value = apply_filters( 'wp_iframe_tag_add_loading_attr', $value, $iframe, $context ); if ( $value ) { if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) { $value = 'lazy'; } return str_replace( '<iframe', '<iframe loading="' . esc_attr( $value ) . '"', $iframe ); } return $iframe; } /** * Adds a 'wp-post-image' class to post thumbnails. Internal use only. * * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'} * action hooks to dynamically add/remove itself so as to only filter post thumbnails. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. * @return string[] Modified array of attributes including the new 'wp-post-image' class. */ function _wp_post_thumbnail_class_filter( $attr ) { $attr['class'] .= ' wp-post-image'; return $attr; } /** * Adds '_wp_post_thumbnail_class_filter' callback to the 'wp_get_attachment_image_attributes' * filter hook. Internal use only. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. */ function _wp_post_thumbnail_class_filter_add( $attr ) { add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); } /** * Removes the '_wp_post_thumbnail_class_filter' callback from the 'wp_get_attachment_image_attributes' * filter hook. Internal use only. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. */ function _wp_post_thumbnail_class_filter_remove( $attr ) { remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); } /** * Overrides the context used in {@see wp_get_attachment_image()}. Internal use only. * * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'} * action hooks to dynamically add/remove itself so as to only filter post thumbnails. * * @ignore * @since 6.3.0 * @access private * * @param string $context The context for rendering an attachment image. * @return string Modified context set to 'the_post_thumbnail'. */ function _wp_post_thumbnail_context_filter( $context ) { return 'the_post_thumbnail'; } /** * Adds the '_wp_post_thumbnail_context_filter' callback to the 'wp_get_attachment_image_context' * filter hook. Internal use only. * * @ignore * @since 6.3.0 * @access private */ function _wp_post_thumbnail_context_filter_add() { add_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); } /** * Removes the '_wp_post_thumbnail_context_filter' callback from the 'wp_get_attachment_image_context' * filter hook. Internal use only. * * @ignore * @since 6.3.0 * @access private */ function _wp_post_thumbnail_context_filter_remove() { remove_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); } add_shortcode( 'wp_caption', 'img_caption_shortcode' ); add_shortcode( 'caption', 'img_caption_shortcode' ); /** * Builds the Caption shortcode output. * * Allows a plugin to replace the content that would otherwise be returned. The * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr * parameter and the content parameter values. * * The supported attributes for the shortcode are 'id', 'caption_id', 'align', * 'width', 'caption', and 'class'. * * @since 2.6.0 * @since 3.9.0 The `class` attribute was added. * @since 5.1.0 The `caption_id` attribute was added. * @since 5.9.0 The `$content` parameter default value changed from `null` to `''`. * * @param array $attr { * Attributes of the caption shortcode. * * @type string $id ID of the image and caption container element, i.e. `<figure>` or `<div>`. * @type string $caption_id ID of the caption element, i.e. `<figcaption>` or `<p>`. * @type string $align Class name that aligns the caption. Default 'alignnone'. Accepts 'alignleft', * 'aligncenter', alignright', 'alignnone'. * @type int $width The width of the caption, in pixels. * @type string $caption The caption text. * @type string $class Additional class name(s) added to the caption container. * } * @param string $content Optional. Shortcode content. Default empty string. * @return string HTML content to display the caption. */ function img_caption_shortcode( $attr, $content = '' ) { // New-style shortcode with the caption inside the shortcode with the link and image tags. if ( ! isset( $attr['caption'] ) ) { if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) { $content = $matches[1]; $attr['caption'] = trim( $matches[2] ); } } elseif ( str_contains( $attr['caption'], '<' ) ) { $attr['caption'] = wp_kses( $attr['caption'], 'post' ); } /** * Filters the default caption shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default caption template. * * @since 2.6.0 * * @see img_caption_shortcode() * * @param string $output The caption output. Default empty. * @param array $attr Attributes of the caption shortcode. * @param string $content The image element, possibly wrapped in a hyperlink. */ $output = apply_filters( 'img_caption_shortcode', '', $attr, $content ); if ( ! empty( $output ) ) { return $output; } $atts = shortcode_atts( array( 'id' => '', 'caption_id' => '', 'align' => 'alignnone', 'width' => '', 'caption' => '', 'class' => '', ), $attr, 'caption' ); $atts['width'] = (int) $atts['width']; if ( $atts['width'] < 1 || empty( $atts['caption'] ) ) { return $content; } $id = ''; $caption_id = ''; $describedby = ''; if ( $atts['id'] ) { $atts['id'] = sanitize_html_class( $atts['id'] ); $id = 'id="' . esc_attr( $atts['id'] ) . '" '; } if ( $atts['caption_id'] ) { $atts['caption_id'] = sanitize_html_class( $atts['caption_id'] ); } elseif ( $atts['id'] ) { $atts['caption_id'] = 'caption-' . str_replace( '_', '-', $atts['id'] ); } if ( $atts['caption_id'] ) { $caption_id = 'id="' . esc_attr( $atts['caption_id'] ) . '" '; $describedby = 'aria-describedby="' . esc_attr( $atts['caption_id'] ) . '" '; } $class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] ); $html5 = current_theme_supports( 'html5', 'caption' ); // HTML5 captions never added the extra 10px to the image width. $width = $html5 ? $atts['width'] : ( 10 + $atts['width'] ); /** * Filters the width of an image's caption. * * By default, the caption is 10 pixels greater than the width of the image, * to prevent post content from running up against a floated image. * * @since 3.7.0 * * @see img_caption_shortcode() * * @param int $width Width of the caption in pixels. To remove this inline style, * return zero. * @param array $atts Attributes of the caption shortcode. * @param string $content The image element, possibly wrapped in a hyperlink. */ $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content ); $style = ''; if ( $caption_width ) { $style = 'style="width: ' . (int) $caption_width . 'px" '; } if ( $html5 ) { $html = sprintf( '<figure %s%s%sclass="%s">%s%s</figure>', $id, $describedby, $style, esc_attr( $class ), do_shortcode( $content ), sprintf( '<figcaption %sclass="wp-caption-text">%s</figcaption>', $caption_id, $atts['caption'] ) ); } else { $html = sprintf( '<div %s%sclass="%s">%s%s</div>', $id, $style, esc_attr( $class ), str_replace( '<img ', '<img ' . $describedby, do_shortcode( $content ) ), sprintf( '<p %sclass="wp-caption-text">%s</p>', $caption_id, $atts['caption'] ) ); } return $html; } add_shortcode( 'gallery', 'gallery_shortcode' ); /** * Builds the Gallery shortcode output. * * This implements the functionality of the Gallery Shortcode for displaying * WordPress images on a post. * * @since 2.5.0 * @since 2.8.0 Added the `$attr` parameter to set the shortcode output. New attributes included * such as `size`, `itemtag`, `icontag`, `captiontag`, and columns. Changed markup from * `div` tags to `dl`, `dt` and `dd` tags. Support more than one gallery on the * same page. * @since 2.9.0 Added support for `include` and `exclude` to shortcode. * @since 3.5.0 Use get_post() instead of global `$post`. Handle mapping of `ids` to `include` * and `orderby`. * @since 3.6.0 Added validation for tags used in gallery shortcode. Add orientation information to items. * @since 3.7.0 Introduced the `link` attribute. * @since 3.9.0 `html5` gallery support, accepting 'itemtag', 'icontag', and 'captiontag' attributes. * @since 4.0.0 Removed use of `extract()`. * @since 4.1.0 Added attribute to `wp_get_attachment_link()` to output `aria-describedby`. * @since 4.2.0 Passed the shortcode instance ID to `post_gallery` and `post_playlist` filters. * @since 4.6.0 Standardized filter docs to match documentation standards for PHP. * @since 5.1.0 Code cleanup for WPCS 1.0.0 coding standards. * @since 5.3.0 Saved progress of intermediate image creation after upload. * @since 5.5.0 Ensured that galleries can be output as a list of links in feeds. * @since 5.6.0 Replaced order-style PHP type conversion functions with typecasts. Fix logic for * an array of image dimensions. * * @param array $attr { * Attributes of the gallery shortcode. * * @type string $order Order of the images in the gallery. Default 'ASC'. Accepts 'ASC', 'DESC'. * @type string $orderby The field to use when ordering the images. Default 'menu_order ID'. * Accepts any valid SQL ORDERBY statement. * @type int $id Post ID. * @type string $itemtag HTML tag to use for each image in the gallery. * Default 'dl', or 'figure' when the theme registers HTML5 gallery support. * @type string $icontag HTML tag to use for each image's icon. * Default 'dt', or 'div' when the theme registers HTML5 gallery support. * @type string $captiontag HTML tag to use for each image's caption. * Default 'dd', or 'figcaption' when the theme registers HTML5 gallery support. * @type int $columns Number of columns of images to display. Default 3. * @type string|int[] $size Size of the images to display. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @type string $ids A comma-separated list of IDs of attachments to display. Default empty. * @type string $include A comma-separated list of IDs of attachments to include. Default empty. * @type string $exclude A comma-separated list of IDs of attachments to exclude. Default empty. * @type string $link What to link each image to. Default empty (links to the attachment page). * Accepts 'file', 'none'. * } * @return string HTML content to display gallery. */ function gallery_shortcode( $attr ) { $post = get_post(); static $instance = 0; ++$instance; if ( ! empty( $attr['ids'] ) ) { // 'ids' is explicitly ordered, unless you specify otherwise. if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; } /** * Filters the default gallery shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default gallery template. * * @since 2.5.0 * @since 4.2.0 The `$instance` parameter was added. * * @see gallery_shortcode() * * @param string $output The gallery output. Default empty. * @param array $attr Attributes of the gallery shortcode. * @param int $instance Unique numeric ID of this gallery shortcode instance. */ $output = apply_filters( 'post_gallery', '', $attr, $instance ); if ( ! empty( $output ) ) { return $output; } $html5 = current_theme_supports( 'html5', 'gallery' ); $atts = shortcode_atts( array( 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post ? $post->ID : 0, 'itemtag' => $html5 ? 'figure' : 'dl', 'icontag' => $html5 ? 'div' : 'dt', 'captiontag' => $html5 ? 'figcaption' : 'dd', 'columns' => 3, 'size' => 'thumbnail', 'include' => '', 'exclude' => '', 'link' => '', ), $attr, 'gallery' ); $id = (int) $atts['id']; if ( ! empty( $atts['include'] ) ) { $_attachments = get_posts( array( 'include' => $atts['include'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[ $val->ID ] = $_attachments[ $key ]; } } elseif ( ! empty( $atts['exclude'] ) ) { $post_parent_id = $id; $attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); } else { $post_parent_id = $id; $attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'], ) ); } if ( ! empty( $post_parent_id ) ) { $post_parent = get_post( $post_parent_id ); // Terminate the shortcode execution if the user cannot read the post or it is password-protected. if ( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } } if ( empty( $attachments ) ) { return ''; } if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) { if ( ! empty( $atts['link'] ) ) { if ( 'none' === $atts['link'] ) { $output .= wp_get_attachment_image( $att_id, $atts['size'], false, $attr ); } else { $output .= wp_get_attachment_link( $att_id, $atts['size'], false ); } } else { $output .= wp_get_attachment_link( $att_id, $atts['size'], true ); } $output .= "\n"; } return $output; } $itemtag = tag_escape( $atts['itemtag'] ); $captiontag = tag_escape( $atts['captiontag'] ); $icontag = tag_escape( $atts['icontag'] ); $valid_tags = wp_kses_allowed_html( 'post' ); if ( ! isset( $valid_tags[ $itemtag ] ) ) { $itemtag = 'dl'; } if ( ! isset( $valid_tags[ $captiontag ] ) ) { $captiontag = 'dd'; } if ( ! isset( $valid_tags[ $icontag ] ) ) { $icontag = 'dt'; } $columns = (int) $atts['columns']; $itemwidth = $columns > 0 ? floor( 100 / $columns ) : 100; $float = is_rtl() ? 'right' : 'left'; $selector = "gallery-{$instance}"; $gallery_style = ''; /** * Filters whether to print default gallery styles. * * @since 3.1.0 * * @param bool $print Whether to print default gallery styles. * Defaults to false if the theme supports HTML5 galleries. * Otherwise, defaults to true. */ if ( apply_filters( 'use_default_gallery_style', ! $html5 ) ) { $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; $gallery_style = " <style{$type_attr}> #{$selector} { margin: auto; } #{$selector} .gallery-item { float: {$float}; margin-top: 10px; text-align: center; width: {$itemwidth}%; } #{$selector} img { border: 2px solid #cfcfcf; } #{$selector} .gallery-caption { margin-left: 0; } /* see gallery_shortcode() in wp-includes/media.php */ </style>\n\t\t"; } $size_class = sanitize_html_class( is_array( $atts['size'] ) ? implode( 'x', $atts['size'] ) : $atts['size'] ); $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>"; /** * Filters the default gallery shortcode CSS styles. * * @since 2.5.0 * * @param string $gallery_style Default CSS styles and opening HTML div container * for the gallery shortcode output. */ $output = apply_filters( 'gallery_style', $gallery_style . $gallery_div ); $i = 0; foreach ( $attachments as $id => $attachment ) { $attr = ( trim( $attachment->post_excerpt ) ) ? array( 'aria-describedby' => "$selector-$id" ) : ''; if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) { $image_output = wp_get_attachment_link( $id, $atts['size'], false, false, false, $attr ); } elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) { $image_output = wp_get_attachment_image( $id, $atts['size'], false, $attr ); } else { $image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr ); } $image_meta = wp_get_attachment_metadata( $id ); $orientation = ''; if ( isset( $image_meta['height'], $image_meta['width'] ) ) { $orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape'; } $output .= "<{$itemtag} class='gallery-item'>"; $output .= " <{$icontag} class='gallery-icon {$orientation}'> $image_output </{$icontag}>"; if ( $captiontag && trim( $attachment->post_excerpt ) ) { $output .= " <{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'> " . wptexturize( $attachment->post_excerpt ) . " </{$captiontag}>"; } $output .= "</{$itemtag}>"; if ( ! $html5 && $columns > 0 && 0 === ++$i % $columns ) { $output .= '<br style="clear: both" />'; } } if ( ! $html5 && $columns > 0 && 0 !== $i % $columns ) { $output .= " <br style='clear: both' />"; } $output .= " </div>\n"; return $output; } /** * Outputs the templates used by playlists. * * @since 3.9.0 */ function wp_underscore_playlist_templates() { ?> <script type="text/html" id="tmpl-wp-playlist-current-item"> <# if ( data.thumb && data.thumb.src ) { #> <img src="{{ data.thumb.src }}" alt="" /> <# } #> <div class="wp-playlist-caption"> <span class="wp-playlist-item-meta wp-playlist-item-title"> <# if ( data.meta.album || data.meta.artist ) { #> <?php /* translators: %s: Playlist item title. */ printf( _x( '“%s”', 'playlist item title' ), '{{ data.title }}' ); ?> <# } else { #> {{ data.title }} <# } #> </span> <# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #> <# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #> </div> </script> <script type="text/html" id="tmpl-wp-playlist-item"> <div class="wp-playlist-item"> <a class="wp-playlist-caption" href="{{ data.src }}"> {{ data.index ? ( data.index + '. ' ) : '' }} <# if ( data.caption ) { #> {{ data.caption }} <# } else { #> <# if ( data.artists && data.meta.artist ) { #> <span class="wp-playlist-item-title"> <?php /* translators: %s: Playlist item title. */ printf( _x( '“%s”', 'playlist item title' ), '{{{ data.title }}}' ); ?> </span> <span class="wp-playlist-item-artist"> — {{ data.meta.artist }}</span> <# } else { #> <span class="wp-playlist-item-title">{{{ data.title }}}</span> <# } #> <# } #> </a> <# if ( data.meta.length_formatted ) { #> <div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div> <# } #> </div> </script> <?php } /** * Outputs and enqueues default scripts and styles for playlists. * * @since 3.9.0 * * @param string $type Type of playlist. Accepts 'audio' or 'video'. */ function wp_playlist_scripts( $type ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-playlist' ); ?> <!--[if lt IE 9]><script>document.createElement('<?php echo esc_js( $type ); ?>');</script><![endif]--> <?php add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 ); add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 ); } /** * Builds the Playlist shortcode output. * * This implements the functionality of the playlist shortcode for displaying * a collection of WordPress audio or video files in a post. * * @since 3.9.0 * * @global int $content_width * * @param array $attr { * Array of default playlist attributes. * * @type string $type Type of playlist to display. Accepts 'audio' or 'video'. Default 'audio'. * @type string $order Designates ascending or descending order of items in the playlist. * Accepts 'ASC', 'DESC'. Default 'ASC'. * @type string $orderby Any column, or columns, to sort the playlist. If $ids are * passed, this defaults to the order of the $ids array ('post__in'). * Otherwise default is 'menu_order ID'. * @type int $id If an explicit $ids array is not present, this parameter * will determine which attachments are used for the playlist. * Default is the current post ID. * @type array $ids Create a playlist out of these explicit attachment IDs. If empty, * a playlist will be created from all $type attachments of $id. * Default empty. * @type array $exclude List of specific attachment IDs to exclude from the playlist. Default empty. * @type string $style Playlist style to use. Accepts 'light' or 'dark'. Default 'light'. * @type bool $tracklist Whether to show or hide the playlist. Default true. * @type bool $tracknumbers Whether to show or hide the numbers next to entries in the playlist. Default true. * @type bool $images Show or hide the video or audio thumbnail (Featured Image/post * thumbnail). Default true. * @type bool $artists Whether to show or hide artist name in the playlist. Default true. * } * * @return string Playlist output. Empty string if the passed type is unsupported. */ function wp_playlist_shortcode( $attr ) { global $content_width; $post = get_post(); static $instance = 0; ++$instance; if ( ! empty( $attr['ids'] ) ) { // 'ids' is explicitly ordered, unless you specify otherwise. if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; } /** * Filters the playlist output. * * Returning a non-empty value from the filter will short-circuit generation * of the default playlist output, returning the passed value instead. * * @since 3.9.0 * @since 4.2.0 The `$instance` parameter was added. * * @param string $output Playlist output. Default empty. * @param array $attr An array of shortcode attributes. * @param int $instance Unique numeric ID of this playlist shortcode instance. */ $output = apply_filters( 'post_playlist', '', $attr, $instance ); if ( ! empty( $output ) ) { return $output; } $atts = shortcode_atts( array( 'type' => 'audio', 'order' => 'ASC', 'orderby' => 'menu_order ID', 'id' => $post ? $post->ID : 0, 'include' => '', 'exclude' => '', 'style' => 'light', 'tracklist' => true, 'tracknumbers' => true, 'images' => true, 'artists' => true, ), $attr, 'playlist' ); $id = (int) $atts['id']; if ( 'audio' !== $atts['type'] ) { $atts['type'] = 'video'; } $args = array( 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => $atts['type'], 'order' => $atts['order'], 'orderby' => $atts['orderby'], ); if ( ! empty( $atts['include'] ) ) { $args['include'] = $atts['include']; $_attachments = get_posts( $args ); $attachments = array(); foreach ( $_attachments as $key => $val ) { $attachments[ $val->ID ] = $_attachments[ $key ]; } } elseif ( ! empty( $atts['exclude'] ) ) { $args['post_parent'] = $id; $args['exclude'] = $atts['exclude']; $attachments = get_children( $args ); } else { $args['post_parent'] = $id; $attachments = get_children( $args ); } if ( ! empty( $args['post_parent'] ) ) { $post_parent = get_post( $id ); // Terminate the shortcode execution if the user cannot read the post or it is password-protected. if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } } if ( empty( $attachments ) ) { return ''; } if ( is_feed() ) { $output = "\n"; foreach ( $attachments as $att_id => $attachment ) { $output .= wp_get_attachment_link( $att_id ) . "\n"; } return $output; } $outer = 22; // Default padding and border of wrapper. $default_width = 640; $default_height = 360; $theme_width = empty( $content_width ) ? $default_width : ( $content_width - $outer ); $theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width ); $data = array( 'type' => $atts['type'], // Don't pass strings to JSON, will be truthy in JS. 'tracklist' => wp_validate_boolean( $atts['tracklist'] ), 'tracknumbers' => wp_validate_boolean( $atts['tracknumbers'] ), 'images' => wp_validate_boolean( $atts['images'] ), 'artists' => wp_validate_boolean( $atts['artists'] ), ); $tracks = array(); foreach ( $attachments as $attachment ) { $url = wp_get_attachment_url( $attachment->ID ); $ftype = wp_check_filetype( $url, wp_get_mime_types() ); $track = array( 'src' => $url, 'type' => $ftype['type'], 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, ); $track['meta'] = array(); $meta = wp_get_attachment_metadata( $attachment->ID ); if ( ! empty( $meta ) ) { foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) { if ( ! empty( $meta[ $key ] ) ) { $track['meta'][ $key ] = $meta[ $key ]; } } if ( 'video' === $atts['type'] ) { if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $width = $meta['width']; $height = $meta['height']; $theme_height = round( ( $height * $theme_width ) / $width ); } else { $width = $default_width; $height = $default_height; } $track['dimensions'] = array( 'original' => compact( 'width', 'height' ), 'resized' => array( 'width' => $theme_width, 'height' => $theme_height, ), ); } } if ( $atts['images'] ) { $thumb_id = get_post_thumbnail_id( $attachment->ID ); if ( ! empty( $thumb_id ) ) { list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' ); $track['image'] = compact( 'src', 'width', 'height' ); list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' ); $track['thumb'] = compact( 'src', 'width', 'height' ); } else { $src = wp_mime_type_icon( $attachment->ID, '.svg' ); $width = 48; $height = 64; $track['image'] = compact( 'src', 'width', 'height' ); $track['thumb'] = compact( 'src', 'width', 'height' ); } } $tracks[] = $track; } $data['tracks'] = $tracks; $safe_type = esc_attr( $atts['type'] ); $safe_style = esc_attr( $atts['style'] ); ob_start(); if ( 1 === $instance ) { /** * Prints and enqueues playlist scripts, styles, and JavaScript templates. * * @since 3.9.0 * * @param string $type Type of playlist. Possible values are 'audio' or 'video'. * @param string $style The 'theme' for the playlist. Core provides 'light' and 'dark'. */ do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] ); } ?> <div class="wp-playlist wp-<?php echo $safe_type; ?>-playlist wp-playlist-<?php echo $safe_style; ?>"> <?php if ( 'audio' === $atts['type'] ) : ?> <div class="wp-playlist-current-item"></div> <?php endif; ?> <<?php echo $safe_type; ?> controls="controls" preload="none" width="<?php echo (int) $theme_width; ?>" <?php if ( 'video' === $safe_type ) { echo ' height="', (int) $theme_height, '"'; } ?> ></<?php echo $safe_type; ?>> <div class="wp-playlist-next"></div> <div class="wp-playlist-prev"></div> <noscript> <ol> <?php foreach ( $attachments as $att_id => $attachment ) { printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) ); } ?> </ol> </noscript> <script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data ); ?></script> </div> <?php return ob_get_clean(); } add_shortcode( 'playlist', 'wp_playlist_shortcode' ); /** * Provides a No-JS Flash fallback as a last resort for audio / video. * * @since 3.6.0 * * @param string $url The media element URL. * @return string Fallback HTML. */ function wp_mediaelement_fallback( $url ) { /** * Filters the MediaElement fallback output for no-JS. * * @since 3.6.0 * * @param string $output Fallback output for no-JS. * @param string $url Media file URL. */ return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url ); } /** * Returns a filtered list of supported audio formats. * * @since 3.6.0 * * @return string[] Supported audio formats. */ function wp_get_audio_extensions() { /** * Filters the list of supported audio formats. * * @since 3.6.0 * * @param string[] $extensions An array of supported audio formats. Defaults are * 'mp3', 'ogg', 'flac', 'm4a', 'wav'. */ return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'flac', 'm4a', 'wav' ) ); } /** * Returns useful keys to use to lookup data from an attachment's stored metadata. * * @since 3.9.0 * * @param WP_Post $attachment The current attachment, provided for context. * @param string $context Optional. The context. Accepts 'edit', 'display'. Default 'display'. * @return string[] Key/value pairs of field keys to labels. */ function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) { $fields = array( 'artist' => __( 'Artist' ), 'album' => __( 'Album' ), ); if ( 'display' === $context ) { $fields['genre'] = __( 'Genre' ); $fields['year'] = __( 'Year' ); $fields['length_formatted'] = _x( 'Length', 'video or audio' ); } elseif ( 'js' === $context ) { $fields['bitrate'] = __( 'Bitrate' ); $fields['bitrate_mode'] = __( 'Bitrate Mode' ); } /** * Filters the editable list of keys to look up data from an attachment's metadata. * * @since 3.9.0 * * @param array $fields Key/value pairs of field keys to labels. * @param WP_Post $attachment Attachment object. * @param string $context The context. Accepts 'edit', 'display'. Default 'display'. */ return apply_filters( 'wp_get_attachment_id3_keys', $fields, $attachment, $context ); } /** * Builds the Audio shortcode output. * * This implements the functionality of the Audio Shortcode for displaying * WordPress mp3s in a post. * * @since 3.6.0 * @since 6.8.0 Added the 'muted' attribute. * * @param array $attr { * Attributes of the audio shortcode. * * @type string $src URL to the source of the audio file. Default empty. * @type string $loop The 'loop' attribute for the `<audio>` element. Default empty. * @type string $autoplay The 'autoplay' attribute for the `<audio>` element. Default empty. * @type string $muted The 'muted' attribute for the `<audio>` element. Default 'false'. * @type string $preload The 'preload' attribute for the `<audio>` element. Default 'none'. * @type string $class The 'class' attribute for the `<audio>` element. Default 'wp-audio-shortcode'. * @type string $style The 'style' attribute for the `<audio>` element. Default 'width: 100%;'. * } * @param string $content Shortcode content. * @return string|void HTML content to display audio. */ function wp_audio_shortcode( $attr, $content = '' ) { $post_id = get_post() ? get_the_ID() : 0; static $instance = 0; ++$instance; /** * Filters the default audio shortcode output. * * If the filtered output isn't empty, it will be used instead of generating the default audio template. * * @since 3.6.0 * * @param string $html Empty variable to be replaced with shortcode markup. * @param array $attr Attributes of the shortcode. See {@see wp_audio_shortcode()}. * @param string $content Shortcode content. * @param int $instance Unique numeric ID of this audio shortcode instance. */ $override = apply_filters( 'wp_audio_shortcode_override', '', $attr, $content, $instance ); if ( '' !== $override ) { return $override; } $audio = null; $default_types = wp_get_audio_extensions(); $defaults_atts = array( 'src' => '', 'loop' => '', 'autoplay' => '', 'muted' => 'false', 'preload' => 'none', 'class' => 'wp-audio-shortcode', 'style' => 'width: 100%;', ); foreach ( $default_types as $type ) { $defaults_atts[ $type ] = ''; } $atts = shortcode_atts( $defaults_atts, $attr, 'audio' ); $primary = false; if ( ! empty( $atts['src'] ) ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '<a class="wp-embedded-audio" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } $primary = true; array_unshift( $default_types, 'src' ); } else { foreach ( $default_types as $ext ) { if ( ! empty( $atts[ $ext ] ) ) { $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() ); if ( strtolower( $type['ext'] ) === $ext ) { $primary = true; } } } } if ( ! $primary ) { $audios = get_attached_media( 'audio', $post_id ); if ( empty( $audios ) ) { return; } $audio = reset( $audios ); $atts['src'] = wp_get_attachment_url( $audio->ID ); if ( empty( $atts['src'] ) ) { return; } array_unshift( $default_types, 'src' ); } /** * Filters the media library used for the audio shortcode. * * @since 3.6.0 * * @param string $library Media library used for the audio shortcode. */ $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ); if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); } /** * Filters the class attribute for the audio shortcode output container. * * @since 3.6.0 * @since 4.9.0 The `$atts` parameter was added. * * @param string $class CSS class or list of space-separated classes. * @param array $atts Array of audio shortcode attributes. */ $atts['class'] = apply_filters( 'wp_audio_shortcode_class', $atts['class'], $atts ); $html_atts = array( 'class' => $atts['class'], 'id' => sprintf( 'audio-%d-%d', $post_id, $instance ), 'loop' => wp_validate_boolean( $atts['loop'] ), 'autoplay' => wp_validate_boolean( $atts['autoplay'] ), 'muted' => wp_validate_boolean( $atts['muted'] ), 'preload' => $atts['preload'], 'style' => $atts['style'], ); // These ones should just be omitted altogether if they are blank. foreach ( array( 'loop', 'autoplay', 'preload', 'muted' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } } $attr_strings = array(); foreach ( $html_atts as $attribute_name => $attribute_value ) { if ( in_array( $attribute_name, array( 'loop', 'autoplay', 'muted' ), true ) && true === $attribute_value ) { // Add boolean attributes without a value. $attr_strings[] = esc_attr( $attribute_name ); } elseif ( 'preload' === $attribute_name && ! empty( $attribute_value ) ) { // Handle the preload attribute with specific allowed values. $allowed_preload_values = array( 'none', 'metadata', 'auto' ); if ( in_array( $attribute_value, $allowed_preload_values, true ) ) { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } else { // For other attributes, include the value. $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } $html = ''; if ( 'mediaelement' === $library && 1 === $instance ) { $html .= "<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->\n"; } $html .= sprintf( '<audio %s controls="controls">', implode( ' ', $attr_strings ) ); $fileurl = ''; $source = '<source type="%s" src="%s" />'; foreach ( $default_types as $fallback ) { if ( ! empty( $atts[ $fallback ] ) ) { if ( empty( $fileurl ) ) { $fileurl = $atts[ $fallback ]; } $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() ); $url = add_query_arg( '_', $instance, $atts[ $fallback ] ); $html .= sprintf( $source, $type['type'], esc_url( $url ) ); } } if ( 'mediaelement' === $library ) { $html .= wp_mediaelement_fallback( $fileurl ); } $html .= '</audio>'; /** * Filters the audio shortcode output. * * @since 3.6.0 * * @param string $html Audio shortcode HTML output. * @param array $atts Array of audio shortcode attributes. * @param string $audio Audio file. * @param int $post_id Post ID. * @param string $library Media library used for the audio shortcode. */ return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id, $library ); } add_shortcode( 'audio', 'wp_audio_shortcode' ); /** * Returns a filtered list of supported video formats. * * @since 3.6.0 * * @return string[] List of supported video formats. */ function wp_get_video_extensions() { /** * Filters the list of supported video formats. * * @since 3.6.0 * * @param string[] $extensions An array of supported video formats. Defaults are * 'mp4', 'm4v', 'webm', 'ogv', 'flv'. */ return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'flv' ) ); } /** * Builds the Video shortcode output. * * This implements the functionality of the Video Shortcode for displaying * WordPress mp4s in a post. * * @since 3.6.0 * * @global int $content_width * * @param array $attr { * Attributes of the shortcode. * * @type string $src URL to the source of the video file. Default empty. * @type int $height Height of the video embed in pixels. Default 360. * @type int $width Width of the video embed in pixels. Default $content_width or 640. * @type string $poster The 'poster' attribute for the `<video>` element. Default empty. * @type string $loop The 'loop' attribute for the `<video>` element. Default empty. * @type string $autoplay The 'autoplay' attribute for the `<video>` element. Default empty. * @type string $muted The 'muted' attribute for the `<video>` element. Default false. * @type string $preload The 'preload' attribute for the `<video>` element. * Default 'metadata'. * @type string $class The 'class' attribute for the `<video>` element. * Default 'wp-video-shortcode'. * } * @param string $content Shortcode content. * @return string|void HTML content to display video. */ function wp_video_shortcode( $attr, $content = '' ) { global $content_width; $post_id = get_post() ? get_the_ID() : 0; static $instance = 0; ++$instance; /** * Filters the default video shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default video template. * * @since 3.6.0 * * @see wp_video_shortcode() * * @param string $html Empty variable to be replaced with shortcode markup. * @param array $attr Attributes of the shortcode. See {@see wp_video_shortcode()}. * @param string $content Video shortcode content. * @param int $instance Unique numeric ID of this video shortcode instance. */ $override = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instance ); if ( '' !== $override ) { return $override; } $video = null; $default_types = wp_get_video_extensions(); $defaults_atts = array( 'src' => '', 'poster' => '', 'loop' => '', 'autoplay' => '', 'muted' => 'false', 'preload' => 'metadata', 'width' => 640, 'height' => 360, 'class' => 'wp-video-shortcode', ); foreach ( $default_types as $type ) { $defaults_atts[ $type ] = ''; } $atts = shortcode_atts( $defaults_atts, $attr, 'video' ); if ( is_admin() ) { // Shrink the video so it isn't huge in the admin. if ( $atts['width'] > $defaults_atts['width'] ) { $atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] ); $atts['width'] = $defaults_atts['width']; } } else { // If the video is bigger than the theme. if ( ! empty( $content_width ) && $atts['width'] > $content_width ) { $atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] ); $atts['width'] = $content_width; } } $is_vimeo = false; $is_youtube = false; $yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#'; $vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#'; $primary = false; if ( ! empty( $atts['src'] ) ) { $is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) ); $is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) ); if ( ! $is_youtube && ! $is_vimeo ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } } if ( $is_vimeo ) { wp_enqueue_script( 'mediaelement-vimeo' ); } $primary = true; array_unshift( $default_types, 'src' ); } else { foreach ( $default_types as $ext ) { if ( ! empty( $atts[ $ext ] ) ) { $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() ); if ( strtolower( $type['ext'] ) === $ext ) { $primary = true; } } } } if ( ! $primary ) { $videos = get_attached_media( 'video', $post_id ); if ( empty( $videos ) ) { return; } $video = reset( $videos ); $atts['src'] = wp_get_attachment_url( $video->ID ); if ( empty( $atts['src'] ) ) { return; } array_unshift( $default_types, 'src' ); } /** * Filters the media library used for the video shortcode. * * @since 3.6.0 * * @param string $library Media library used for the video shortcode. */ $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' ); if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); wp_enqueue_script( 'mediaelement-vimeo' ); } /* * MediaElement.js has issues with some URL formats for Vimeo and YouTube, * so update the URL to prevent the ME.js player from breaking. */ if ( 'mediaelement' === $library ) { if ( $is_youtube ) { // Remove `feature` query arg and force SSL - see #40866. $atts['src'] = remove_query_arg( 'feature', $atts['src'] ); $atts['src'] = set_url_scheme( $atts['src'], 'https' ); } elseif ( $is_vimeo ) { // Remove all query arguments and force SSL - see #40866. $parsed_vimeo_url = wp_parse_url( $atts['src'] ); $vimeo_src = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path']; // Add loop param for mejs bug - see #40977, not needed after #39686. $loop = $atts['loop'] ? '1' : '0'; $atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src ); } } /** * Filters the class attribute for the video shortcode output container. * * @since 3.6.0 * @since 4.9.0 The `$atts` parameter was added. * * @param string $class CSS class or list of space-separated classes. * @param array $atts Array of video shortcode attributes. */ $atts['class'] = apply_filters( 'wp_video_shortcode_class', $atts['class'], $atts ); $html_atts = array( 'class' => $atts['class'], 'id' => sprintf( 'video-%d-%d', $post_id, $instance ), 'width' => absint( $atts['width'] ), 'height' => absint( $atts['height'] ), 'poster' => esc_url( $atts['poster'] ), 'loop' => wp_validate_boolean( $atts['loop'] ), 'autoplay' => wp_validate_boolean( $atts['autoplay'] ), 'muted' => wp_validate_boolean( $atts['muted'] ), 'preload' => $atts['preload'], ); // These ones should just be omitted altogether if they are blank. foreach ( array( 'poster', 'loop', 'autoplay', 'preload', 'muted' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } } $attr_strings = array(); foreach ( $html_atts as $attribute_name => $attribute_value ) { if ( in_array( $attribute_name, array( 'loop', 'autoplay', 'muted' ), true ) && true === $attribute_value ) { // Add boolean attributes without their value for true. $attr_strings[] = esc_attr( $attribute_name ); } elseif ( 'preload' === $attribute_name && ! empty( $attribute_value ) ) { // Handle the preload attribute with specific allowed values. $allowed_preload_values = array( 'none', 'metadata', 'auto' ); if ( in_array( $attribute_value, $allowed_preload_values, true ) ) { $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } elseif ( ! empty( $attribute_value ) ) { // For non-boolean attributes, add them with their value. $attr_strings[] = sprintf( '%s="%s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } $html = ''; if ( 'mediaelement' === $library && 1 === $instance ) { $html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n"; } $html .= sprintf( '<video %s controls="controls">', implode( ' ', $attr_strings ) ); $fileurl = ''; $source = '<source type="%s" src="%s" />'; foreach ( $default_types as $fallback ) { if ( ! empty( $atts[ $fallback ] ) ) { if ( empty( $fileurl ) ) { $fileurl = $atts[ $fallback ]; } if ( 'src' === $fallback && $is_youtube ) { $type = array( 'type' => 'video/youtube' ); } elseif ( 'src' === $fallback && $is_vimeo ) { $type = array( 'type' => 'video/vimeo' ); } else { $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() ); } $url = add_query_arg( '_', $instance, $atts[ $fallback ] ); $html .= sprintf( $source, $type['type'], esc_url( $url ) ); } } if ( ! empty( $content ) ) { if ( str_contains( $content, "\n" ) ) { $content = str_replace( array( "\r\n", "\n", "\t" ), '', $content ); } $html .= trim( $content ); } if ( 'mediaelement' === $library ) { $html .= wp_mediaelement_fallback( $fileurl ); } $html .= '</video>'; $width_rule = ''; if ( ! empty( $atts['width'] ) ) { $width_rule = sprintf( 'width: %dpx;', $atts['width'] ); } $output = sprintf( '<div style="%s" class="wp-video">%s</div>', $width_rule, $html ); /** * Filters the output of the video shortcode. * * @since 3.6.0 * * @param string $output Video shortcode HTML output. * @param array $atts Array of video shortcode attributes. * @param string $video Video file. * @param int $post_id Post ID. * @param string $library Media library used for the video shortcode. */ return apply_filters( 'wp_video_shortcode', $output, $atts, $video, $post_id, $library ); } add_shortcode( 'video', 'wp_video_shortcode' ); /** * Gets the previous image link that has the same post parent. * * @since 5.8.0 * * @see get_adjacent_image_link() * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. * @return string Markup for previous image link. */ function get_previous_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( true, $size, $text ); } /** * Displays previous image link that has the same post parent. * * @since 2.5.0 * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. */ function previous_image_link( $size = 'thumbnail', $text = false ) { echo get_previous_image_link( $size, $text ); } /** * Gets the next image link that has the same post parent. * * @since 5.8.0 * * @see get_adjacent_image_link() * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. * @return string Markup for next image link. */ function get_next_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( false, $size, $text ); } /** * Displays next image link that has the same post parent. * * @since 2.5.0 * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. */ function next_image_link( $size = 'thumbnail', $text = false ) { echo get_next_image_link( $size, $text ); } /** * Gets the next or previous image link that has the same post parent. * * Retrieves the current attachment object from the $post global. * * @since 5.8.0 * * @param bool $prev Optional. Whether to display the next (false) or previous (true) link. Default true. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $text Optional. Link text. Default false. * @return string Markup for image link. */ function get_adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { $post = get_post(); $attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID', ) ) ); foreach ( $attachments as $k => $attachment ) { if ( (int) $attachment->ID === (int) $post->ID ) { break; } } $output = ''; $attachment_id = 0; if ( $attachments ) { $k = $prev ? $k - 1 : $k + 1; if ( isset( $attachments[ $k ] ) ) { $attachment_id = $attachments[ $k ]->ID; $attr = array( 'alt' => get_the_title( $attachment_id ) ); $output = wp_get_attachment_link( $attachment_id, $size, true, false, $text, $attr ); } } $adjacent = $prev ? 'previous' : 'next'; /** * Filters the adjacent image link. * * The dynamic portion of the hook name, `$adjacent`, refers to the type of adjacency, * either 'next', or 'previous'. * * Possible hook names include: * * - `next_image_link` * - `previous_image_link` * * @since 3.5.0 * * @param string $output Adjacent image HTML markup. * @param int $attachment_id Attachment ID * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string $text Link text. */ return apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text ); } /** * Displays next or previous image link that has the same post parent. * * Retrieves the current attachment object from the $post global. * * @since 2.5.0 * * @param bool $prev Optional. Whether to display the next (false) or previous (true) link. Default true. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $text Optional. Link text. Default false. */ function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { echo get_adjacent_image_link( $prev, $size, $text ); } /** * Retrieves taxonomies attached to given the attachment. * * @since 2.5.0 * @since 4.7.0 Introduced the `$output` parameter. * * @param int|array|object $attachment Attachment ID, data array, or data object. * @param string $output Output type. 'names' to return an array of taxonomy names, * or 'objects' to return an array of taxonomy objects. * Default is 'names'. * @return string[]|WP_Taxonomy[] List of taxonomies or taxonomy names. Empty array on failure. */ function get_attachment_taxonomies( $attachment, $output = 'names' ) { if ( is_int( $attachment ) ) { $attachment = get_post( $attachment ); } elseif ( is_array( $attachment ) ) { $attachment = (object) $attachment; } if ( ! is_object( $attachment ) ) { return array(); } $file = get_attached_file( $attachment->ID ); $filename = wp_basename( $file ); $objects = array( 'attachment' ); if ( str_contains( $filename, '.' ) ) { $objects[] = 'attachment:' . substr( $filename, strrpos( $filename, '.' ) + 1 ); } if ( ! empty( $attachment->post_mime_type ) ) { $objects[] = 'attachment:' . $attachment->post_mime_type; if ( str_contains( $attachment->post_mime_type, '/' ) ) { foreach ( explode( '/', $attachment->post_mime_type ) as $token ) { if ( ! empty( $token ) ) { $objects[] = "attachment:$token"; } } } } $taxonomies = array(); foreach ( $objects as $object ) { $taxes = get_object_taxonomies( $object, $output ); if ( $taxes ) { $taxonomies = array_merge( $taxonomies, $taxes ); } } if ( 'names' === $output ) { $taxonomies = array_unique( $taxonomies ); } return $taxonomies; } /** * Retrieves all of the taxonomies that are registered for attachments. * * Handles mime-type-specific taxonomies such as attachment:image and attachment:video. * * @since 3.5.0 * * @see get_taxonomies() * * @param string $output Optional. The type of taxonomy output to return. Accepts 'names' or 'objects'. * Default 'names'. * @return string[]|WP_Taxonomy[] Array of names or objects of registered taxonomies for attachments. */ function get_taxonomies_for_attachments( $output = 'names' ) { $taxonomies = array(); foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { foreach ( $taxonomy->object_type as $object_type ) { if ( 'attachment' === $object_type || str_starts_with( $object_type, 'attachment:' ) ) { if ( 'names' === $output ) { $taxonomies[] = $taxonomy->name; } else { $taxonomies[ $taxonomy->name ] = $taxonomy; } break; } } } return $taxonomies; } /** * Determines whether the value is an acceptable type for GD image functions. * * In PHP 8.0, the GD extension uses GdImage objects for its data structures. * This function checks if the passed value is either a GdImage object instance * or a resource of type `gd`. Any other type will return false. * * @since 5.6.0 * * @param resource|GdImage|false $image A value to check the type for. * @return bool True if `$image` is either a GD image resource or a GdImage instance, * false otherwise. */ function is_gd_image( $image ) { if ( $image instanceof GdImage || is_resource( $image ) && 'gd' === get_resource_type( $image ) ) { return true; } return false; } /** * Creates a new GD image resource with transparency support. * * @todo Deprecate if possible. * * @since 2.9.0 * * @param int $width Image width in pixels. * @param int $height Image height in pixels. * @return resource|GdImage|false The GD image resource or GdImage instance on success. * False on failure. */ function wp_imagecreatetruecolor( $width, $height ) { $img = imagecreatetruecolor( $width, $height ); if ( is_gd_image( $img ) && function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) { imagealphablending( $img, false ); imagesavealpha( $img, true ); } return $img; } /** * Based on a supplied width/height example, returns the biggest possible dimensions based on the max width/height. * * @since 2.9.0 * * @see wp_constrain_dimensions() * * @param int $example_width The width of an example embed. * @param int $example_height The height of an example embed. * @param int $max_width The maximum allowed width. * @param int $max_height The maximum allowed height. * @return int[] { * An array of maximum width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } */ function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { $example_width = (int) $example_width; $example_height = (int) $example_height; $max_width = (int) $max_width; $max_height = (int) $max_height; return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height ); } /** * Determines the maximum upload size allowed in php.ini. * * @since 2.5.0 * * @return int Allowed upload size. */ function wp_max_upload_size() { $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); /** * Filters the maximum upload size allowed in php.ini. * * @since 2.5.0 * * @param int $size Max upload size limit in bytes. * @param int $u_bytes Maximum upload filesize in bytes. * @param int $p_bytes Maximum size of POST data in bytes. */ return apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); } /** * Returns a WP_Image_Editor instance and loads file into it. * * @since 3.5.0 * * @param string $path Path to the file to load. * @param array $args Optional. Additional arguments for retrieving the image editor. * Default empty array. * @return WP_Image_Editor|WP_Error The WP_Image_Editor object on success, * a WP_Error object otherwise. */ function wp_get_image_editor( $path, $args = array() ) { $args['path'] = $path; // If the mime type is not set in args, try to extract and set it from the file. if ( ! isset( $args['mime_type'] ) ) { $file_info = wp_check_filetype( $args['path'] ); /* * If $file_info['type'] is false, then we let the editor attempt to * figure out the file type, rather than forcing a failure based on extension. */ if ( isset( $file_info ) && $file_info['type'] ) { $args['mime_type'] = $file_info['type']; } } // Check and set the output mime type mapped to the input type. if ( isset( $args['mime_type'] ) ) { $output_format = wp_get_image_editor_output_format( $path, $args['mime_type'] ); if ( isset( $output_format[ $args['mime_type'] ] ) ) { $args['output_mime_type'] = $output_format[ $args['mime_type'] ]; } } $implementation = _wp_image_editor_choose( $args ); if ( $implementation ) { $editor = new $implementation( $path ); $loaded = $editor->load(); if ( is_wp_error( $loaded ) ) { return $loaded; } return $editor; } return new WP_Error( 'image_no_editor', __( 'No editor could be selected.' ) ); } /** * Tests whether there is an editor that supports a given mime type or methods. * * @since 3.5.0 * * @param string|array $args Optional. Array of arguments to retrieve the image editor supports. * Default empty array. * @return bool True if an eligible editor is found; false otherwise. */ function wp_image_editor_supports( $args = array() ) { return (bool) _wp_image_editor_choose( $args ); } /** * Tests which editors are capable of supporting the request. * * @ignore * @since 3.5.0 * * @param array $args Optional. Array of arguments for choosing a capable editor. Default empty array. * @return string|false Class name for the first editor that claims to support the request. * False if no editor claims to support the request. */ function _wp_image_editor_choose( $args = array() ) { require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; require_once ABSPATH . WPINC . '/class-avif-info.php'; /** * Filters the list of image editing library classes. * * @since 3.5.0 * * @param string[] $image_editors Array of available image editor class names. Defaults are * 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'. */ $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); $editors = wp_cache_get( 'wp_image_editor_choose', 'image_editor' ); if ( ! is_array( $editors ) ) { $editors = array(); } // Cache the chosen editor implementation based on specific args and available implementations. $cache_key = md5( serialize( array( $args, $implementations ) ) ); if ( isset( $editors[ $cache_key ] ) ) { return $editors[ $cache_key ]; } // Assume no support until a capable implementation is identified. $editor = false; foreach ( $implementations as $implementation ) { if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) { continue; } // Implementation should support the passed mime type. if ( isset( $args['mime_type'] ) && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['mime_type'] ) ) { continue; } // Implementation should support requested methods. if ( isset( $args['methods'] ) && array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { continue; } // Implementation should ideally support the output mime type as well if set and different than the passed type. if ( isset( $args['mime_type'] ) && isset( $args['output_mime_type'] ) && $args['mime_type'] !== $args['output_mime_type'] && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['output_mime_type'] ) ) { /* * This implementation supports the input type but not the output type. * Keep looking to see if we can find an implementation that supports both. */ $editor = $implementation; continue; } // Favor the implementation that supports both input and output mime types. $editor = $implementation; break; } $editors[ $cache_key ] = $editor; wp_cache_set( 'wp_image_editor_choose', $editors, 'image_editor', DAY_IN_SECONDS ); return $editor; } /** * Prints default Plupload arguments. * * @since 3.4.0 */ function wp_plupload_default_settings() { $wp_scripts = wp_scripts(); $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); if ( $data && str_contains( $data, '_wpPluploadSettings' ) ) { return; } $max_upload_size = wp_max_upload_size(); $allowed_extensions = array_keys( get_allowed_mime_types() ); $extensions = array(); foreach ( $allowed_extensions as $extension ) { $extensions = array_merge( $extensions, explode( '|', $extension ) ); } /* * Since 4.9 the `runtimes` setting is hardcoded in our version of Plupload to `html5,html4`, * and the `flash_swf_url` and `silverlight_xap_url` are not used. */ $defaults = array( 'file_data_name' => 'async-upload', // Key passed to $_FILE. 'url' => admin_url( 'async-upload.php', 'relative' ), 'filters' => array( 'max_file_size' => $max_upload_size . 'b', 'mime_types' => array( array( 'extensions' => implode( ',', $extensions ) ) ), ), ); /* * Currently only iOS Safari supports multiple files uploading, * but iOS 7.x has a bug that prevents uploading of videos when enabled. * See #29602. */ if ( wp_is_mobile() && str_contains( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) ) { $defaults['multi_selection'] = false; } // Check if WebP images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { $defaults['webp_upload_error'] = true; } // Check if AVIF images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) { $defaults['avif_upload_error'] = true; } // Check if HEIC images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $defaults['heic_upload_error'] = true; } /** * Filters the Plupload default settings. * * @since 3.4.0 * * @param array $defaults Default Plupload settings array. */ $defaults = apply_filters( 'plupload_default_settings', $defaults ); $params = array( 'action' => 'upload-attachment', ); /** * Filters the Plupload default parameters. * * @since 3.4.0 * * @param array $params Default Plupload parameters array. */ $params = apply_filters( 'plupload_default_params', $params ); $params['_wpnonce'] = wp_create_nonce( 'media-form' ); $defaults['multipart_params'] = $params; $settings = array( 'defaults' => $defaults, 'browser' => array( 'mobile' => wp_is_mobile(), 'supported' => _device_can_upload(), ), 'limitExceeded' => is_multisite() && ! is_upload_space_available(), ); $script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings ) . ';'; if ( $data ) { $script = "$data\n$script"; } $wp_scripts->add_data( 'wp-plupload', 'data', $script ); } /** * Prepares an attachment post object for JS, where it is expected * to be JSON-encoded and fit into an Attachment model. * * @since 3.5.0 * * @param int|WP_Post $attachment Attachment ID or object. * @return array|void { * Array of attachment details, or void if the parameter does not correspond to an attachment. * * @type string $alt Alt text of the attachment. * @type string $author ID of the attachment author, as a string. * @type string $authorName Name of the attachment author. * @type string $caption Caption for the attachment. * @type array $compat Containing item and meta. * @type string $context Context, whether it's used as the site icon for example. * @type int $date Uploaded date, timestamp in milliseconds. * @type string $dateFormatted Formatted date (e.g. June 29, 2018). * @type string $description Description of the attachment. * @type string $editLink URL to the edit page for the attachment. * @type string $filename File name of the attachment. * @type string $filesizeHumanReadable Filesize of the attachment in human readable format (e.g. 1 MB). * @type int $filesizeInBytes Filesize of the attachment in bytes. * @type int $height If the attachment is an image, represents the height of the image in pixels. * @type string $icon Icon URL of the attachment (e.g. /wp-includes/images/media/archive.png). * @type int $id ID of the attachment. * @type string $link URL to the attachment. * @type int $menuOrder Menu order of the attachment post. * @type array $meta Meta data for the attachment. * @type string $mime Mime type of the attachment (e.g. image/jpeg or application/zip). * @type int $modified Last modified, timestamp in milliseconds. * @type string $name Name, same as title of the attachment. * @type array $nonces Nonces for update, delete and edit. * @type string $orientation If the attachment is an image, represents the image orientation * (landscape or portrait). * @type array $sizes If the attachment is an image, contains an array of arrays * for the images sizes: thumbnail, medium, large, and full. * @type string $status Post status of the attachment (usually 'inherit'). * @type string $subtype Mime subtype of the attachment (usually the last part, e.g. jpeg or zip). * @type string $title Title of the attachment (usually slugified file name without the extension). * @type string $type Type of the attachment (usually first part of the mime type, e.g. image). * @type int $uploadedTo Parent post to which the attachment was uploaded. * @type string $uploadedToLink URL to the edit page of the parent post of the attachment. * @type string $uploadedToTitle Post title of the parent of the attachment. * @type string $url Direct URL to the attachment file (from wp-content). * @type int $width If the attachment is an image, represents the width of the image in pixels. * } */ function wp_prepare_attachment_for_js( $attachment ) { $attachment = get_post( $attachment ); if ( ! $attachment ) { return; } if ( 'attachment' !== $attachment->post_type ) { return; } $meta = wp_get_attachment_metadata( $attachment->ID ); if ( str_contains( $attachment->post_mime_type, '/' ) ) { list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); } else { list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); } $attachment_url = wp_get_attachment_url( $attachment->ID ); $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); $response = array( 'id' => $attachment->ID, 'title' => $attachment->post_title, 'filename' => wp_basename( get_attached_file( $attachment->ID ) ), 'url' => $attachment_url, 'link' => get_attachment_link( $attachment->ID ), 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), 'author' => $attachment->post_author, 'description' => $attachment->post_content, 'caption' => $attachment->post_excerpt, 'name' => $attachment->post_name, 'status' => $attachment->post_status, 'uploadedTo' => $attachment->post_parent, 'date' => strtotime( $attachment->post_date_gmt ) * 1000, 'modified' => strtotime( $attachment->post_modified_gmt ) * 1000, 'menuOrder' => $attachment->menu_order, 'mime' => $attachment->post_mime_type, 'type' => $type, 'subtype' => $subtype, 'icon' => wp_mime_type_icon( $attachment->ID, '.svg' ), 'dateFormatted' => mysql2date( __( 'F j, Y' ), $attachment->post_date ), 'nonces' => array( 'update' => false, 'delete' => false, 'edit' => false, ), 'editLink' => false, 'meta' => false, ); $author = new WP_User( $attachment->post_author ); if ( $author->exists() ) { $author_name = $author->display_name ? $author->display_name : $author->nickname; $response['authorName'] = html_entity_decode( $author_name, ENT_QUOTES, get_bloginfo( 'charset' ) ); $response['authorLink'] = get_edit_user_link( $author->ID ); } else { $response['authorName'] = __( '(no author)' ); } if ( $attachment->post_parent ) { $post_parent = get_post( $attachment->post_parent ); if ( $post_parent ) { $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' ); $response['uploadedToLink'] = get_edit_post_link( $attachment->post_parent, 'raw' ); } } $attached_file = get_attached_file( $attachment->ID ); if ( isset( $meta['filesize'] ) ) { $bytes = $meta['filesize']; } elseif ( file_exists( $attached_file ) ) { $bytes = wp_filesize( $attached_file ); } else { $bytes = ''; } if ( $bytes ) { $response['filesizeInBytes'] = $bytes; $response['filesizeHumanReadable'] = size_format( $bytes ); } $context = get_post_meta( $attachment->ID, '_wp_attachment_context', true ); $response['context'] = ( $context ) ? $context : ''; if ( current_user_can( 'edit_post', $attachment->ID ) ) { $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); $response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID ); $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); } if ( current_user_can( 'delete_post', $attachment->ID ) ) { $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID ); } if ( $meta && ( 'image' === $type || ! empty( $meta['sizes'] ) ) ) { $sizes = array(); /** This filter is documented in wp-admin/includes/media.php */ $possible_sizes = apply_filters( 'image_size_names_choose', array( 'thumbnail' => __( 'Thumbnail' ), 'medium' => __( 'Medium' ), 'large' => __( 'Large' ), 'full' => __( 'Full Size' ), ) ); unset( $possible_sizes['full'] ); /* * Loop through all potential sizes that may be chosen. Try to do this with some efficiency. * First: run the image_downsize filter. If it returns something, we can use its data. * If the filter does not return something, then image_downsize() is just an expensive way * to check the image metadata, which we do second. */ foreach ( $possible_sizes as $size => $label ) { /** This filter is documented in wp-includes/media.php */ $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ); if ( $downsize ) { if ( empty( $downsize[3] ) ) { continue; } $sizes[ $size ] = array( 'height' => $downsize[2], 'width' => $downsize[1], 'url' => $downsize[0], 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', ); } elseif ( isset( $meta['sizes'][ $size ] ) ) { // Nothing from the filter, so consult image metadata if we have it. $size_meta = $meta['sizes'][ $size ]; /* * We have the actual image size, but might need to further constrain it if content_width is narrower. * Thumbnail, medium, and full sizes are also checked against the site's height/width options. */ list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' ); $sizes[ $size ] = array( 'height' => $height, 'width' => $width, 'url' => $base_url . $size_meta['file'], 'orientation' => $height > $width ? 'portrait' : 'landscape', ); } } if ( 'image' === $type ) { if ( ! empty( $meta['original_image'] ) ) { $response['originalImageURL'] = wp_get_original_image_url( $attachment->ID ); $response['originalImageName'] = wp_basename( wp_get_original_image_path( $attachment->ID ) ); } $sizes['full'] = array( 'url' => $attachment_url ); if ( isset( $meta['height'], $meta['width'] ) ) { $sizes['full']['height'] = $meta['height']; $sizes['full']['width'] = $meta['width']; $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape'; } $response = array_merge( $response, $sizes['full'] ); } elseif ( $meta['sizes']['full']['file'] ) { $sizes['full'] = array( 'url' => $base_url . $meta['sizes']['full']['file'], 'height' => $meta['sizes']['full']['height'], 'width' => $meta['sizes']['full']['width'], 'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape', ); } $response = array_merge( $response, array( 'sizes' => $sizes ) ); } if ( $meta && 'video' === $type ) { if ( isset( $meta['width'] ) ) { $response['width'] = (int) $meta['width']; } if ( isset( $meta['height'] ) ) { $response['height'] = (int) $meta['height']; } } if ( $meta && ( 'audio' === $type || 'video' === $type ) ) { if ( isset( $meta['length_formatted'] ) ) { $response['fileLength'] = $meta['length_formatted']; $response['fileLengthHumanReadable'] = human_readable_duration( $meta['length_formatted'] ); } $response['meta'] = array(); foreach ( wp_get_attachment_id3_keys( $attachment, 'js' ) as $key => $label ) { $response['meta'][ $key ] = false; if ( ! empty( $meta[ $key ] ) ) { $response['meta'][ $key ] = $meta[ $key ]; } } $id = get_post_thumbnail_id( $attachment->ID ); if ( ! empty( $id ) ) { list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' ); $response['image'] = compact( 'src', 'width', 'height' ); list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' ); $response['thumb'] = compact( 'src', 'width', 'height' ); } else { $src = wp_mime_type_icon( $attachment->ID, '.svg' ); $width = 48; $height = 64; $response['image'] = compact( 'src', 'width', 'height' ); $response['thumb'] = compact( 'src', 'width', 'height' ); } } if ( function_exists( 'get_compat_media_markup' ) ) { $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) ); } if ( function_exists( 'get_media_states' ) ) { $media_states = get_media_states( $attachment ); if ( ! empty( $media_states ) ) { $response['mediaStates'] = implode( ', ', $media_states ); } } /** * Filters the attachment data prepared for JavaScript. * * @since 3.5.0 * * @param array $response Array of prepared attachment data. See {@see wp_prepare_attachment_for_js()}. * @param WP_Post $attachment Attachment object. * @param array|false $meta Array of attachment meta data, or false if there is none. */ return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); } /** * Enqueues all scripts, styles, settings, and templates necessary to use * all media JS APIs. * * @since 3.5.0 * * @global int $content_width * @global wpdb $wpdb WordPress database abstraction object. * @global WP_Locale $wp_locale WordPress date and time locale object. * * @param array $args { * Arguments for enqueuing media scripts. * * @type int|WP_Post $post Post ID or post object. * } */ function wp_enqueue_media( $args = array() ) { // Enqueue me just once per page, please. if ( did_action( 'wp_enqueue_media' ) ) { return; } global $content_width, $wpdb, $wp_locale; $defaults = array( 'post' => null, ); $args = wp_parse_args( $args, $defaults ); /* * We're going to pass the old thickbox media tabs to `media_upload_tabs` * to ensure plugins will work. We will then unset those tabs. */ $tabs = array( // handler action suffix => tab label 'type' => '', 'type_url' => '', 'gallery' => '', 'library' => '', ); /** This filter is documented in wp-admin/includes/media.php */ $tabs = apply_filters( 'media_upload_tabs', $tabs ); unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] ); $props = array( 'link' => get_option( 'image_default_link_type' ), // DB default is 'file'. 'align' => get_option( 'image_default_align' ), // Empty default. 'size' => get_option( 'image_default_size' ), // Empty default. ); $exts = array_merge( wp_get_audio_extensions(), wp_get_video_extensions() ); $mimes = get_allowed_mime_types(); $ext_mimes = array(); foreach ( $exts as $ext ) { foreach ( $mimes as $ext_preg => $mime_match ) { if ( preg_match( '#' . $ext . '#i', $ext_preg ) ) { $ext_mimes[ $ext ] = $mime_match; break; } } } /** * Allows showing or hiding the "Create Audio Playlist" button in the media library. * * By default, the "Create Audio Playlist" button will always be shown in * the media library. If this filter returns `null`, a query will be run * to determine whether the media library contains any audio items. This * was the default behavior prior to version 4.8.0, but this query is * expensive for large media libraries. * * @since 4.7.4 * @since 4.8.0 The filter's default value is `true` rather than `null`. * * @link https://core.trac.wordpress.org/ticket/31071 * * @param bool|null $show Whether to show the button, or `null` to decide based * on whether any audio files exist in the media library. */ $show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true ); if ( null === $show_audio_playlist ) { $show_audio_playlist = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'audio%' LIMIT 1" ); } /** * Allows showing or hiding the "Create Video Playlist" button in the media library. * * By default, the "Create Video Playlist" button will always be shown in * the media library. If this filter returns `null`, a query will be run * to determine whether the media library contains any video items. This * was the default behavior prior to version 4.8.0, but this query is * expensive for large media libraries. * * @since 4.7.4 * @since 4.8.0 The filter's default value is `true` rather than `null`. * * @link https://core.trac.wordpress.org/ticket/31071 * * @param bool|null $show Whether to show the button, or `null` to decide based * on whether any video files exist in the media library. */ $show_video_playlist = apply_filters( 'media_library_show_video_playlist', true ); if ( null === $show_video_playlist ) { $show_video_playlist = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'video%' LIMIT 1" ); } /** * Allows overriding the list of months displayed in the media library. * * By default (if this filter does not return an array), a query will be * run to determine the months that have media items. This query can be * expensive for large media libraries, so it may be desirable for sites to * override this behavior. * * @since 4.7.4 * * @link https://core.trac.wordpress.org/ticket/31071 * * @param stdClass[]|null $months An array of objects with `month` and `year` * properties, or `null` for default behavior. */ $months = apply_filters( 'media_library_months_with_files', null ); if ( ! is_array( $months ) ) { $months = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month FROM $wpdb->posts WHERE post_type = %s ORDER BY post_date DESC", 'attachment' ) ); } foreach ( $months as $month_year ) { $month_year->text = sprintf( /* translators: 1: Month, 2: Year. */ __( '%1$s %2$d' ), $wp_locale->get_month( $month_year->month ), $month_year->year ); } /** * Filters whether the Media Library grid has infinite scrolling. Default `false`. * * @since 5.8.0 * * @param bool $infinite Whether the Media Library grid has infinite scrolling. */ $infinite_scrolling = apply_filters( 'media_library_infinite_scrolling', false ); $settings = array( 'tabs' => $tabs, 'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url( 'media-upload.php' ) ), 'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ), /** This filter is documented in wp-admin/includes/media.php */ 'captions' => ! apply_filters( 'disable_captions', '' ), 'nonce' => array( 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ), 'setAttachmentThumbnail' => wp_create_nonce( 'set-attachment-thumbnail' ), ), 'post' => array( 'id' => 0, ), 'defaultProps' => $props, 'attachmentCounts' => array( 'audio' => ( $show_audio_playlist ) ? 1 : 0, 'video' => ( $show_video_playlist ) ? 1 : 0, ), 'oEmbedProxyUrl' => rest_url( 'oembed/1.0/proxy' ), 'embedExts' => $exts, 'embedMimes' => $ext_mimes, 'contentWidth' => $content_width, 'months' => $months, 'mediaTrash' => MEDIA_TRASH ? 1 : 0, 'infiniteScrolling' => ( $infinite_scrolling ) ? 1 : 0, ); $post = null; if ( isset( $args['post'] ) ) { $post = get_post( $args['post'] ); $settings['post'] = array( 'id' => $post->ID, 'nonce' => wp_create_nonce( 'update-post_' . $post->ID ), ); $thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ); if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) { if ( wp_attachment_is( 'audio', $post ) ) { $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ); } elseif ( wp_attachment_is( 'video', $post ) ) { $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ); } } if ( $thumbnail_support ) { $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true ); $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1; } } if ( $post ) { $post_type_object = get_post_type_object( $post->post_type ); } else { $post_type_object = get_post_type_object( 'post' ); } $strings = array( // Generic. 'mediaFrameDefaultTitle' => __( 'Media' ), 'url' => __( 'URL' ), 'addMedia' => __( 'Add media' ), 'search' => __( 'Search' ), 'select' => __( 'Select' ), 'cancel' => __( 'Cancel' ), 'update' => __( 'Update' ), 'replace' => __( 'Replace' ), 'remove' => __( 'Remove' ), 'back' => __( 'Back' ), /* * translators: This is a would-be plural string used in the media manager. * If there is not a word you can use in your language to avoid issues with the * lack of plural support here, turn it into "selected: %d" then translate it. */ 'selected' => __( '%d selected' ), 'dragInfo' => __( 'Drag and drop to reorder media files.' ), // Upload. 'uploadFilesTitle' => __( 'Upload files' ), 'uploadImagesTitle' => __( 'Upload images' ), // Library. 'mediaLibraryTitle' => __( 'Media Library' ), 'insertMediaTitle' => __( 'Add media' ), 'createNewGallery' => __( 'Create a new gallery' ), 'createNewPlaylist' => __( 'Create a new playlist' ), 'createNewVideoPlaylist' => __( 'Create a new video playlist' ), 'returnToLibrary' => __( '← Go to library' ), 'allMediaItems' => __( 'All media items' ), 'allDates' => __( 'All dates' ), 'noItemsFound' => __( 'No items found.' ), 'insertIntoPost' => $post_type_object->labels->insert_into_item, 'unattached' => _x( 'Unattached', 'media items' ), 'mine' => _x( 'Mine', 'media items' ), 'trash' => _x( 'Trash', 'noun' ), 'uploadedToThisPost' => $post_type_object->labels->uploaded_to_this_item, 'warnDelete' => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ), 'warnBulkDelete' => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ), 'warnBulkTrash' => __( "You are about to trash these items.\n 'Cancel' to stop, 'OK' to delete." ), 'bulkSelect' => __( 'Bulk select' ), 'trashSelected' => __( 'Move to Trash' ), 'restoreSelected' => __( 'Restore from Trash' ), 'deletePermanently' => __( 'Delete permanently' ), 'errorDeleting' => __( 'Error in deleting the attachment.' ), 'apply' => __( 'Apply' ), 'filterByDate' => __( 'Filter by date' ), 'filterByType' => __( 'Filter by type' ), 'searchLabel' => __( 'Search media' ), 'searchMediaLabel' => __( 'Search media' ), // Backward compatibility pre-5.3. 'searchMediaPlaceholder' => __( 'Search media items...' ), // Placeholder (no ellipsis), backward compatibility pre-5.3. /* translators: %d: Number of attachments found in a search. */ 'mediaFound' => __( 'Number of media items found: %d' ), 'noMedia' => __( 'No media items found.' ), 'noMediaTryNewSearch' => __( 'No media items found. Try a different search.' ), // Library Details. 'attachmentDetails' => __( 'Attachment details' ), // From URL. 'insertFromUrlTitle' => __( 'Insert from URL' ), // Featured Images. 'setFeaturedImageTitle' => $post_type_object->labels->featured_image, 'setFeaturedImage' => $post_type_object->labels->set_featured_image, // Gallery. 'createGalleryTitle' => __( 'Create gallery' ), 'editGalleryTitle' => __( 'Edit gallery' ), 'cancelGalleryTitle' => __( '← Cancel gallery' ), 'insertGallery' => __( 'Insert gallery' ), 'updateGallery' => __( 'Update gallery' ), 'addToGallery' => __( 'Add to gallery' ), 'addToGalleryTitle' => __( 'Add to gallery' ), 'reverseOrder' => __( 'Reverse order' ), // Edit Image. 'imageDetailsTitle' => __( 'Image details' ), 'imageReplaceTitle' => __( 'Replace image' ), 'imageDetailsCancel' => __( 'Cancel edit' ), 'editImage' => __( 'Edit image' ), // Crop Image. 'chooseImage' => __( 'Choose image' ), 'selectAndCrop' => __( 'Select and crop' ), 'skipCropping' => __( 'Skip cropping' ), 'cropImage' => __( 'Crop image' ), 'cropYourImage' => __( 'Crop your image' ), 'cropping' => __( 'Cropping…' ), /* translators: 1: Suggested width number, 2: Suggested height number. */ 'suggestedDimensions' => __( 'Suggested image dimensions: %1$s by %2$s pixels.' ), 'cropError' => __( 'There has been an error cropping your image.' ), // Edit Audio. 'audioDetailsTitle' => __( 'Audio details' ), 'audioReplaceTitle' => __( 'Replace audio' ), 'audioAddSourceTitle' => __( 'Add audio source' ), 'audioDetailsCancel' => __( 'Cancel edit' ), // Edit Video. 'videoDetailsTitle' => __( 'Video details' ), 'videoReplaceTitle' => __( 'Replace video' ), 'videoAddSourceTitle' => __( 'Add video source' ), 'videoDetailsCancel' => __( 'Cancel edit' ), 'videoSelectPosterImageTitle' => __( 'Select poster image' ), 'videoAddTrackTitle' => __( 'Add subtitles' ), // Playlist. 'playlistDragInfo' => __( 'Drag and drop to reorder tracks.' ), 'createPlaylistTitle' => __( 'Create audio playlist' ), 'editPlaylistTitle' => __( 'Edit audio playlist' ), 'cancelPlaylistTitle' => __( '← Cancel audio playlist' ), 'insertPlaylist' => __( 'Insert audio playlist' ), 'updatePlaylist' => __( 'Update audio playlist' ), 'addToPlaylist' => __( 'Add to audio playlist' ), 'addToPlaylistTitle' => __( 'Add to Audio Playlist' ), // Video Playlist. 'videoPlaylistDragInfo' => __( 'Drag and drop to reorder videos.' ), 'createVideoPlaylistTitle' => __( 'Create video playlist' ), 'editVideoPlaylistTitle' => __( 'Edit video playlist' ), 'cancelVideoPlaylistTitle' => __( '← Cancel video playlist' ), 'insertVideoPlaylist' => __( 'Insert video playlist' ), 'updateVideoPlaylist' => __( 'Update video playlist' ), 'addToVideoPlaylist' => __( 'Add to video playlist' ), 'addToVideoPlaylistTitle' => __( 'Add to video Playlist' ), // Headings. 'filterAttachments' => __( 'Filter media' ), 'attachmentsList' => __( 'Media list' ), ); /** * Filters the media view settings. * * @since 3.5.0 * * @param array $settings List of media view settings. * @param WP_Post $post Post object. */ $settings = apply_filters( 'media_view_settings', $settings, $post ); /** * Filters the media view strings. * * @since 3.5.0 * * @param string[] $strings Array of media view strings keyed by the name they'll be referenced by in JavaScript. * @param WP_Post $post Post object. */ $strings = apply_filters( 'media_view_strings', $strings, $post ); $strings['settings'] = $settings; /* * Ensure we enqueue media-editor first, that way media-views * is registered internally before we try to localize it. See #24724. */ wp_enqueue_script( 'media-editor' ); wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings ); wp_enqueue_script( 'media-audiovideo' ); wp_enqueue_style( 'media-views' ); if ( is_admin() ) { wp_enqueue_script( 'mce-view' ); wp_enqueue_script( 'image-edit' ); } wp_enqueue_style( 'imgareaselect' ); wp_plupload_default_settings(); require_once ABSPATH . WPINC . '/media-template.php'; add_action( 'admin_footer', 'wp_print_media_templates' ); add_action( 'wp_footer', 'wp_print_media_templates' ); add_action( 'customize_controls_print_footer_scripts', 'wp_print_media_templates' ); /** * Fires at the conclusion of wp_enqueue_media(). * * @since 3.5.0 */ do_action( 'wp_enqueue_media' ); } /** * Retrieves media attached to the passed post. * * @since 3.6.0 * * @param string $type Mime type. * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @return WP_Post[] Array of media attached to the given post. */ function get_attached_media( $type, $post = 0 ) { $post = get_post( $post ); if ( ! $post ) { return array(); } $args = array( 'post_parent' => $post->ID, 'post_type' => 'attachment', 'post_mime_type' => $type, 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC', ); /** * Filters arguments used to retrieve media attached to the given post. * * @since 3.6.0 * * @param array $args Post query arguments. * @param string $type Mime type of the desired media. * @param WP_Post $post Post object. */ $args = apply_filters( 'get_attached_media_args', $args, $type, $post ); $children = get_children( $args ); /** * Filters the list of media attached to the given post. * * @since 3.6.0 * * @param WP_Post[] $children Array of media attached to the given post. * @param string $type Mime type of the media desired. * @param WP_Post $post Post object. */ return (array) apply_filters( 'get_attached_media', $children, $type, $post ); } /** * Checks the HTML content for an audio, video, object, embed, or iframe tags. * * @since 3.6.0 * * @param string $content A string of HTML which might contain media elements. * @param string[] $types An array of media types: 'audio', 'video', 'object', 'embed', or 'iframe'. * @return string[] Array of found HTML media elements. */ function get_media_embedded_in_content( $content, $types = null ) { $html = array(); /** * Filters the embedded media types that are allowed to be returned from the content blob. * * @since 4.2.0 * * @param string[] $allowed_media_types An array of allowed media types. Default media types are * 'audio', 'video', 'object', 'embed', and 'iframe'. */ $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe' ) ); if ( ! empty( $types ) ) { if ( ! is_array( $types ) ) { $types = array( $types ); } $allowed_media_types = array_intersect( $allowed_media_types, $types ); } $tags = implode( '|', $allowed_media_types ); if ( preg_match_all( '#<(?P<tag>' . $tags . ')[^<]*?(?:>[\s\S]*?<\/(?P=tag)>|\s*\/>)#', $content, $matches ) ) { foreach ( $matches[0] as $match ) { $html[] = $match; } } return $html; } /** * Retrieves galleries from the passed post's content. * * @since 3.6.0 * * @param int|WP_Post $post Post ID or object. * @param bool $html Optional. Whether to return HTML or data in the array. Default true. * @return array A list of arrays, each containing gallery data and srcs parsed * from the expanded shortcode. */ function get_post_galleries( $post, $html = true ) { $post = get_post( $post ); if ( ! $post ) { return array(); } if ( ! has_shortcode( $post->post_content, 'gallery' ) && ! has_block( 'gallery', $post->post_content ) ) { return array(); } $galleries = array(); if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $shortcode ) { if ( 'gallery' === $shortcode[2] ) { $srcs = array(); $shortcode_attrs = shortcode_parse_atts( $shortcode[3] ); // Specify the post ID of the gallery we're viewing if the shortcode doesn't reference another post already. if ( ! isset( $shortcode_attrs['id'] ) ) { $shortcode[3] .= ' id="' . (int) $post->ID . '"'; } $gallery = do_shortcode_tag( $shortcode ); if ( $html ) { $galleries[] = $gallery; } else { preg_match_all( '#src=([\'"])(.+?)\1#is', $gallery, $src, PREG_SET_ORDER ); if ( ! empty( $src ) ) { foreach ( $src as $s ) { $srcs[] = $s[2]; } } $galleries[] = array_merge( $shortcode_attrs, array( 'src' => array_values( array_unique( $srcs ) ), ) ); } } } } if ( has_block( 'gallery', $post->post_content ) ) { $post_blocks = parse_blocks( $post->post_content ); while ( $block = array_shift( $post_blocks ) ) { $has_inner_blocks = ! empty( $block['innerBlocks'] ); // Skip blocks with no blockName and no innerHTML. if ( ! $block['blockName'] ) { continue; } // Skip non-Gallery blocks. if ( 'core/gallery' !== $block['blockName'] ) { // Move inner blocks into the root array before skipping. if ( $has_inner_blocks ) { array_push( $post_blocks, ...$block['innerBlocks'] ); } continue; } // New Gallery block format as HTML. if ( $has_inner_blocks && $html ) { $block_html = wp_list_pluck( $block['innerBlocks'], 'innerHTML' ); $galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>'; continue; } $srcs = array(); // New Gallery block format as an array. if ( $has_inner_blocks ) { $attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' ); $ids = wp_list_pluck( $attrs, 'id' ); foreach ( $ids as $id ) { $url = wp_get_attachment_url( $id ); if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) { $srcs[] = $url; } } $galleries[] = array( 'ids' => implode( ',', $ids ), 'src' => $srcs, ); continue; } // Old Gallery block format as HTML. if ( $html ) { $galleries[] = $block['innerHTML']; continue; } // Old Gallery block format as an array. $ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array(); // If present, use the image IDs from the JSON blob as canonical. if ( ! empty( $ids ) ) { foreach ( $ids as $id ) { $url = wp_get_attachment_url( $id ); if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) { $srcs[] = $url; } } $galleries[] = array( 'ids' => implode( ',', $ids ), 'src' => $srcs, ); continue; } // Otherwise, extract srcs from the innerHTML. preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER ); if ( ! empty( $found_srcs[0] ) ) { foreach ( $found_srcs as $src ) { if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) { $srcs[] = $src[2]; } } } $galleries[] = array( 'src' => $srcs ); } } /** * Filters the list of all found galleries in the given post. * * @since 3.6.0 * * @param array $galleries Associative array of all found post galleries. * @param WP_Post $post Post object. */ return apply_filters( 'get_post_galleries', $galleries, $post ); } /** * Checks a specified post's content for gallery and, if present, return the first * * @since 3.6.0 * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @param bool $html Optional. Whether to return HTML or data. Default is true. * @return string|array Gallery data and srcs parsed from the expanded shortcode. */ function get_post_gallery( $post = 0, $html = true ) { $galleries = get_post_galleries( $post, $html ); $gallery = reset( $galleries ); /** * Filters the first-found post gallery. * * @since 3.6.0 * * @param array $gallery The first-found post gallery. * @param int|WP_Post $post Post ID or object. * @param array $galleries Associative array of all found post galleries. */ return apply_filters( 'get_post_gallery', $gallery, $post, $galleries ); } /** * Retrieves the image srcs from galleries from a post's content, if present. * * @since 3.6.0 * * @see get_post_galleries() * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global `$post`. * @return array A list of lists, each containing image srcs parsed. * from an expanded shortcode */ function get_post_galleries_images( $post = 0 ) { $galleries = get_post_galleries( $post, false ); return wp_list_pluck( $galleries, 'src' ); } /** * Checks a post's content for galleries and return the image srcs for the first found gallery. * * @since 3.6.0 * * @see get_post_gallery() * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global `$post`. * @return string[] A list of a gallery's image srcs in order. */ function get_post_gallery_images( $post = 0 ) { $gallery = get_post_gallery( $post, false ); return empty( $gallery['src'] ) ? array() : $gallery['src']; } /** * Maybe attempts to generate attachment metadata, if missing. * * @since 3.9.0 * * @param WP_Post $attachment Attachment object. */ function wp_maybe_generate_attachment_metadata( $attachment ) { if ( empty( $attachment ) || empty( $attachment->ID ) ) { return; } $attachment_id = (int) $attachment->ID; $file = get_attached_file( $attachment_id ); $meta = wp_get_attachment_metadata( $attachment_id ); if ( empty( $meta ) && file_exists( $file ) ) { $_meta = get_post_meta( $attachment_id ); $_lock = 'wp_generating_att_' . $attachment_id; if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $_lock ) ) { set_transient( $_lock, $file ); wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); delete_transient( $_lock ); } } } /** * Tries to convert an attachment URL into a post ID. * * @since 4.0.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $url The URL to resolve. * @return int The found post ID, or 0 on failure. */ function attachment_url_to_postid( $url ) { global $wpdb; /** * Filters the attachment ID to allow short-circuit the function. * * Allows plugins to short-circuit attachment ID lookups. Plugins making * use of this function should return: * * - 0 (integer) to indicate the attachment is not found, * - attachment ID (integer) to indicate the attachment ID found, * - null to indicate WordPress should proceed with the lookup. * * Warning: The post ID may be null or zero, both of which cast to a * boolean false. For information about casting to booleans see the * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. * Use the === operator for testing the post ID when developing filters using * this hook. * * @since 6.7.0 * * @param int|null $post_id The result of the post ID lookup. Null to indicate * no lookup has been attempted. Default null. * @param string $url The URL being looked up. */ $post_id = apply_filters( 'pre_attachment_url_to_postid', null, $url ); if ( null !== $post_id ) { return (int) $post_id; } $dir = wp_get_upload_dir(); $path = $url; $site_url = parse_url( $dir['url'] ); $image_path = parse_url( $path ); // Force the protocols to match if needed. if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) { $path = str_replace( $image_path['scheme'], $site_url['scheme'], $path ); } if ( str_starts_with( $path, $dir['baseurl'] . '/' ) ) { $path = substr( $path, strlen( $dir['baseurl'] . '/' ) ); } $sql = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s", $path ); $results = $wpdb->get_results( $sql ); $post_id = null; if ( $results ) { // Use the first available result, but prefer a case-sensitive match, if exists. $post_id = reset( $results )->post_id; if ( count( $results ) > 1 ) { foreach ( $results as $result ) { if ( $path === $result->meta_value ) { $post_id = $result->post_id; break; } } } } /** * Filters an attachment ID found by URL. * * @since 4.2.0 * * @param int|null $post_id The post_id (if any) found by the function. * @param string $url The URL being looked up. */ return (int) apply_filters( 'attachment_url_to_postid', $post_id, $url ); } /** * Returns the URLs for CSS files used in an iframe-sandbox'd TinyMCE media view. * * @since 4.0.0 * * @return string[] The relevant CSS file URLs. */ function wpview_media_sandbox_styles() { $version = 'ver=' . get_bloginfo( 'version' ); $mediaelement = includes_url( "js/mediaelement/mediaelementplayer-legacy.min.css?$version" ); $wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" ); return array( $mediaelement, $wpmediaelement ); } /** * Registers the personal data exporter for media. * * @param array[] $exporters An array of personal data exporters, keyed by their ID. * @return array[] Updated array of personal data exporters. */ function wp_register_media_personal_data_exporter( $exporters ) { $exporters['wordpress-media'] = array( 'exporter_friendly_name' => __( 'WordPress Media' ), 'callback' => 'wp_media_personal_data_exporter', ); return $exporters; } /** * Finds and exports attachments associated with an email address. * * @since 4.9.6 * * @param string $email_address The attachment owner email address. * @param int $page Attachment page number. * @return array { * An array of personal data. * * @type array[] $data An array of personal data arrays. * @type bool $done Whether the exporter is finished. * } */ function wp_media_personal_data_exporter( $email_address, $page = 1 ) { // Limit us to 50 attachments at a time to avoid timing out. $number = 50; $page = (int) $page; $data_to_export = array(); $user = get_user_by( 'email', $email_address ); if ( false === $user ) { return array( 'data' => $data_to_export, 'done' => true, ); } $post_query = new WP_Query( array( 'author' => $user->ID, 'posts_per_page' => $number, 'paged' => $page, 'post_type' => 'attachment', 'post_status' => 'any', 'orderby' => 'ID', 'order' => 'ASC', ) ); foreach ( (array) $post_query->posts as $post ) { $attachment_url = wp_get_attachment_url( $post->ID ); if ( $attachment_url ) { $post_data_to_export = array( array( 'name' => __( 'URL' ), 'value' => $attachment_url, ), ); $data_to_export[] = array( 'group_id' => 'media', 'group_label' => __( 'Media' ), 'group_description' => __( 'User’s media data.' ), 'item_id' => "post-{$post->ID}", 'data' => $post_data_to_export, ); } } $done = $post_query->max_num_pages <= $page; return array( 'data' => $data_to_export, 'done' => $done, ); } /** * Adds additional default image sub-sizes. * * These sizes are meant to enhance the way WordPress displays images on the front-end on larger, * high-density devices. They make it possible to generate more suitable `srcset` and `sizes` attributes * when the users upload large images. * * The sizes can be changed or removed by themes and plugins but that is not recommended. * The size "names" reflect the image dimensions, so changing the sizes would be quite misleading. * * @since 5.3.0 * @access private */ function _wp_add_additional_image_sizes() { // 2x medium_large size. add_image_size( '1536x1536', 1536, 1536 ); // 2x large size. add_image_size( '2048x2048', 2048, 2048 ); } /** * Callback to enable showing of the user error when uploading .heic images. * * @since 5.5.0 * @since 6.7.0 The default behavior is to enable heic uploads as long as the server * supports the format. The uploads are converted to JPEG's by default. * * @param array[] $plupload_settings The settings for Plupload.js. * @return array[] Modified settings for Plupload.js. */ function wp_show_heic_upload_error( $plupload_settings ) { // Check if HEIC images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $plupload_init['heic_upload_error'] = true; } return $plupload_settings; } /** * Allows PHP's getimagesize() to be debuggable when necessary. * * @since 5.7.0 * @since 5.8.0 Added support for WebP images. * @since 6.5.0 Added support for AVIF images. * * @param string $filename The file path. * @param array $image_info Optional. Extended image information (passed by reference). * @return array|false Array of image information or false on failure. */ function wp_getimagesize( $filename, ?array &$image_info = null ) { // Don't silence errors when in debug mode, unless running unit tests. if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) { if ( 2 === func_num_args() ) { $info = getimagesize( $filename, $image_info ); } else { $info = getimagesize( $filename ); } } else { /* * Silencing notice and warning is intentional. * * getimagesize() has a tendency to generate errors, such as * "corrupt JPEG data: 7191 extraneous bytes before marker", * even when it's able to provide image size information. * * See https://core.trac.wordpress.org/ticket/42480 */ if ( 2 === func_num_args() ) { $info = @getimagesize( $filename, $image_info ); } else { $info = @getimagesize( $filename ); } } if ( ! empty( $info ) && // Some PHP versions return 0x0 sizes from `getimagesize` for unrecognized image formats, including AVIFs. ! ( empty( $info[0] ) && empty( $info[1] ) ) ) { return $info; } $image_mime_type = wp_get_image_mime( $filename ); // Not an image? if ( false === $image_mime_type ) { return false; } /* * For PHP versions that don't support WebP images, * extract the image size info from the file headers. */ if ( 'image/webp' === $image_mime_type ) { $webp_info = wp_get_webp_info( $filename ); $width = $webp_info['width']; $height = $webp_info['height']; // Mimic the native return format. if ( $width && $height ) { return array( $width, $height, IMAGETYPE_WEBP, sprintf( 'width="%d" height="%d"', $width, $height ), 'mime' => 'image/webp', ); } } // For PHP versions that don't support AVIF images, extract the image size info from the file headers. if ( 'image/avif' === $image_mime_type ) { $avif_info = wp_get_avif_info( $filename ); $width = $avif_info['width']; $height = $avif_info['height']; // Mimic the native return format. if ( $width && $height ) { return array( $width, $height, IMAGETYPE_AVIF, sprintf( 'width="%d" height="%d"', $width, $height ), 'mime' => 'image/avif', ); } } // For PHP versions that don't support HEIC images, extract the size info using Imagick when available. if ( wp_is_heic_image_mime_type( $image_mime_type ) ) { $editor = wp_get_image_editor( $filename ); if ( is_wp_error( $editor ) ) { return false; } // If the editor for HEICs is Imagick, use it to get the image size. if ( $editor instanceof WP_Image_Editor_Imagick ) { $size = $editor->get_size(); return array( $size['width'], $size['height'], IMAGETYPE_HEIC, sprintf( 'width="%d" height="%d"', $size['width'], $size['height'] ), 'mime' => 'image/heic', ); } } // The image could not be parsed. return false; } /** * Extracts meta information about an AVIF file: width, height, bit depth, and number of channels. * * @since 6.5.0 * * @param string $filename Path to an AVIF file. * @return array { * An array of AVIF image information. * * @type int|false $width Image width on success, false on failure. * @type int|false $height Image height on success, false on failure. * @type int|false $bit_depth Image bit depth on success, false on failure. * @type int|false $num_channels Image number of channels on success, false on failure. * } */ function wp_get_avif_info( $filename ) { $results = array( 'width' => false, 'height' => false, 'bit_depth' => false, 'num_channels' => false, ); if ( 'image/avif' !== wp_get_image_mime( $filename ) ) { return $results; } // Parse the file using libavifinfo's PHP implementation. require_once ABSPATH . WPINC . '/class-avif-info.php'; $handle = fopen( $filename, 'rb' ); if ( $handle ) { $parser = new Avifinfo\Parser( $handle ); $success = $parser->parse_ftyp() && $parser->parse_file(); fclose( $handle ); if ( $success ) { $results = $parser->features->primary_item_features; } } return $results; } /** * Extracts meta information about a WebP file: width, height, and type. * * @since 5.8.0 * * @param string $filename Path to a WebP file. * @return array { * An array of WebP image information. * * @type int|false $width Image width on success, false on failure. * @type int|false $height Image height on success, false on failure. * @type string|false $type The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'. * False on failure. * } */ function wp_get_webp_info( $filename ) { $width = false; $height = false; $type = false; if ( 'image/webp' !== wp_get_image_mime( $filename ) ) { return compact( 'width', 'height', 'type' ); } $magic = file_get_contents( $filename, false, null, 0, 40 ); if ( false === $magic ) { return compact( 'width', 'height', 'type' ); } // Make sure we got enough bytes. if ( strlen( $magic ) < 40 ) { return compact( 'width', 'height', 'type' ); } /* * The headers are a little different for each of the three formats. * Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container. */ switch ( substr( $magic, 12, 4 ) ) { // Lossy WebP. case 'VP8 ': $parts = unpack( 'v2', substr( $magic, 26, 4 ) ); $width = (int) ( $parts[1] & 0x3FFF ); $height = (int) ( $parts[2] & 0x3FFF ); $type = 'lossy'; break; // Lossless WebP. case 'VP8L': $parts = unpack( 'C4', substr( $magic, 21, 4 ) ); $width = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1; $height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1; $type = 'lossless'; break; // Animated/alpha WebP. case 'VP8X': // Pad 24-bit int. $width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" ); $width = (int) ( $width[1] & 0xFFFFFF ) + 1; // Pad 24-bit int. $height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" ); $height = (int) ( $height[1] & 0xFFFFFF ) + 1; $type = 'animated-alpha'; break; } return compact( 'width', 'height', 'type' ); } /** * Gets loading optimization attributes. * * This function returns an array of attributes that should be merged into the given attributes array to optimize * loading performance. Potential attributes returned by this function are: * - `loading` attribute with a value of "lazy" * - `fetchpriority` attribute with a value of "high" * - `decoding` attribute with a value of "async" * * If any of these attributes are already present in the given attributes, they will not be modified. Note that no * element should have both `loading="lazy"` and `fetchpriority="high"`, so the function will trigger a warning in case * both attributes are present with those values. * * @since 6.3.0 * * @global WP_Query $wp_query WordPress Query object. * * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. * @return array Loading optimization attributes. */ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { global $wp_query; /** * Filters whether to short-circuit loading optimization attributes. * * Returning an array from the filter will effectively short-circuit the loading of optimization attributes, * returning that value instead. * * @since 6.4.0 * * @param array|false $loading_attrs False by default, or array of loading optimization attributes to short-circuit. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. */ $loading_attrs = apply_filters( 'pre_wp_get_loading_optimization_attributes', false, $tag_name, $attr, $context ); if ( is_array( $loading_attrs ) ) { return $loading_attrs; } $loading_attrs = array(); /* * Skip lazy-loading for the overall block template, as it is handled more granularly. * The skip is also applicable for `fetchpriority`. */ if ( 'template' === $context ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } // For now this function only supports images and iframes. if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } /* * Skip programmatically created images within content blobs as they need to be handled together with the other * images within the post content or widget content. * Without this clause, they would already be considered within their own context which skews the image count and * can result in the first post content image being lazy-loaded or an image further down the page being marked as a * high priority. */ if ( 'the_content' !== $context && doing_filter( 'the_content' ) || 'widget_text_content' !== $context && doing_filter( 'widget_text_content' ) || 'widget_block_content' !== $context && doing_filter( 'widget_block_content' ) ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } /* * Add `decoding` with a value of "async" for every image unless it has a * conflicting `decoding` attribute already present. */ if ( 'img' === $tag_name ) { if ( isset( $attr['decoding'] ) ) { $loading_attrs['decoding'] = $attr['decoding']; } else { $loading_attrs['decoding'] = 'async'; } } // For any resources, width and height must be provided, to avoid layout shifts. if ( ! isset( $attr['width'], $attr['height'] ) ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } /* * The key function logic starts here. */ $maybe_in_viewport = null; $increase_count = false; $maybe_increase_count = false; // Logic to handle a `loading` attribute that is already provided. if ( isset( $attr['loading'] ) ) { /* * Interpret "lazy" as not in viewport. Any other value can be * interpreted as in viewport (realistically only "eager" or `false` * to force-omit the attribute are other potential values). */ if ( 'lazy' === $attr['loading'] ) { $maybe_in_viewport = false; } else { $maybe_in_viewport = true; } } // Logic to handle a `fetchpriority` attribute that is already provided. if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) { /* * If the image was already determined to not be in the viewport (e.g. * from an already provided `loading` attribute), trigger a warning. * Otherwise, the value can be interpreted as in viewport, since only * the most important in-viewport image should have `fetchpriority` set * to "high". */ if ( false === $maybe_in_viewport ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); /* * Set `fetchpriority` here for backward-compatibility as we should * not override what a developer decided, even though it seems * incorrect. */ $loading_attrs['fetchpriority'] = 'high'; } else { $maybe_in_viewport = true; } } if ( null === $maybe_in_viewport ) { $header_enforced_contexts = array( 'template_part_' . WP_TEMPLATE_PART_AREA_HEADER => true, 'get_header_image_tag' => true, ); /** * Filters the header-specific contexts. * * @since 6.4.0 * * @param array $default_header_enforced_contexts Map of contexts for which elements should be considered * in the header of the page, as $context => $enabled * pairs. The $enabled should always be true. */ $header_enforced_contexts = apply_filters( 'wp_loading_optimization_force_header_contexts', $header_enforced_contexts ); // Consider elements with these header-specific contexts to be in viewport. if ( isset( $header_enforced_contexts[ $context ] ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } elseif ( ! is_admin() && in_the_loop() && is_main_query() ) { /* * Get the content media count, since this is a main query * content element. This is accomplished by "increasing" * the count by zero, as the only way to get the count is * to call this function. * The actual count increase happens further below, based * on the `$increase_count` flag set here. */ $content_media_count = wp_increase_content_media_count( 0 ); $increase_count = true; // If the count so far is below the threshold, `loading` attribute is omitted. if ( $content_media_count < wp_omit_loading_attr_threshold() ) { $maybe_in_viewport = true; } else { $maybe_in_viewport = false; } } elseif ( // Only apply for main query but before the loop. $wp_query->before_loop && $wp_query->is_main_query() /* * Any image before the loop, but after the header has started should not be lazy-loaded, * except when the footer has already started which can happen when the current template * does not include any loop. */ && did_action( 'get_header' ) && ! did_action( 'get_footer' ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } } /* * If the element is in the viewport (`true`), potentially add * `fetchpriority` with a value of "high". Otherwise, i.e. if the element * is not not in the viewport (`false`) or it is unknown (`null`), add * `loading` with a value of "lazy". */ if ( $maybe_in_viewport ) { $loading_attrs = wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ); } else { // Only add `loading="lazy"` if the feature is enabled. if ( wp_lazy_loading_enabled( $tag_name, $context ) ) { $loading_attrs['loading'] = 'lazy'; } } /* * If flag was set based on contextual logic above, increase the content * media count, either unconditionally, or based on whether the image size * is larger than the threshold. */ if ( $increase_count ) { wp_increase_content_media_count(); } elseif ( $maybe_increase_count ) { /** This filter is documented in wp-includes/media.php */ $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 ); if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) { wp_increase_content_media_count(); } } /** * Filters the loading optimization attributes. * * @since 6.4.0 * * @param array $loading_attrs The loading optimization attributes. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); } /** * Gets the threshold for how many of the first content media elements to not lazy-load. * * This function runs the {@see 'wp_omit_loading_attr_threshold'} filter, which uses a default threshold value of 3. * The filter is only run once per page load, unless the `$force` parameter is used. * * @since 5.9.0 * * @param bool $force Optional. If set to true, the filter will be (re-)applied even if it already has been before. * Default false. * @return int The number of content media elements to not lazy-load. */ function wp_omit_loading_attr_threshold( $force = false ) { static $omit_threshold; // This function may be called multiple times. Run the filter only once per page load. if ( ! isset( $omit_threshold ) || $force ) { /** * Filters the threshold for how many of the first content media elements to not lazy-load. * * For these first content media elements, the `loading` attribute will be omitted. By default, this is the case * for only the very first content media element. * * @since 5.9.0 * @since 6.3.0 The default threshold was changed from 1 to 3. * * @param int $omit_threshold The number of media elements where the `loading` attribute will not be added. Default 3. */ $omit_threshold = apply_filters( 'wp_omit_loading_attr_threshold', 3 ); } return $omit_threshold; } /** * Increases an internal content media count variable. * * @since 5.9.0 * @access private * * @param int $amount Optional. Amount to increase by. Default 1. * @return int The latest content media count, after the increase. */ function wp_increase_content_media_count( $amount = 1 ) { static $content_media_count = 0; $content_media_count += $amount; return $content_media_count; } /** * Determines whether to add `fetchpriority='high'` to loading attributes. * * @since 6.3.0 * @access private * * @param array $loading_attrs Array of the loading optimization attributes for the element. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the element. * @return array Updated loading optimization attributes for the element. */ function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ) { // For now, adding `fetchpriority="high"` is only supported for images. if ( 'img' !== $tag_name ) { return $loading_attrs; } if ( isset( $attr['fetchpriority'] ) ) { /* * While any `fetchpriority` value could be set in `$loading_attrs`, * for consistency we only do it for `fetchpriority="high"` since that * is the only possible value that WordPress core would apply on its * own. */ if ( 'high' === $attr['fetchpriority'] ) { $loading_attrs['fetchpriority'] = 'high'; wp_high_priority_element_flag( false ); } return $loading_attrs; } // Lazy-loading and `fetchpriority="high"` are mutually exclusive. if ( isset( $loading_attrs['loading'] ) && 'lazy' === $loading_attrs['loading'] ) { return $loading_attrs; } if ( ! wp_high_priority_element_flag() ) { return $loading_attrs; } /** * Filters the minimum square-pixels threshold for an image to be eligible as the high-priority image. * * @since 6.3.0 * * @param int $threshold Minimum square-pixels threshold. Default 50000. */ $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 ); if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) { $loading_attrs['fetchpriority'] = 'high'; wp_high_priority_element_flag( false ); } return $loading_attrs; } /** * Accesses a flag that indicates if an element is a possible candidate for `fetchpriority='high'`. * * @since 6.3.0 * @access private * * @param bool $value Optional. Used to change the static variable. Default null. * @return bool Returns true if high-priority element was marked already, otherwise false. */ function wp_high_priority_element_flag( $value = null ) { static $high_priority_element = true; if ( is_bool( $value ) ) { $high_priority_element = $value; } return $high_priority_element; } /** * Determines the output format for the image editor. * * @since 6.7.0 * @access private * * @param string $filename Path to the image. * @param string $mime_type The source image mime type. * @return string[] An array of mime type mappings. */ function wp_get_image_editor_output_format( $filename, $mime_type ) { $output_format = array( 'image/heic' => 'image/jpeg', 'image/heif' => 'image/jpeg', 'image/heic-sequence' => 'image/jpeg', 'image/heif-sequence' => 'image/jpeg', ); /** * Filters the image editor output format mapping. * * Enables filtering the mime type used to save images. By default HEIC/HEIF images * are converted to JPEGs. * * @see WP_Image_Editor::get_output_format() * * @since 5.8.0 * @since 6.7.0 The default was changed from an empty array to an array * containing the HEIC/HEIF images mime types. * * @param string[] $output_format { * An array of mime type mappings. Maps a source mime type to a new * destination mime type. By default maps HEIC/HEIF input to JPEG output. * * @type string ...$0 The new mime type. * } * @param string $filename Path to the image. * @param string $mime_type The source image mime type. */ return apply_filters( 'image_editor_output_format', $output_format, $filename, $mime_type ); } <?php const SODIUM_LIBRARY_MAJOR_VERSION = 9; const SODIUM_LIBRARY_MINOR_VERSION = 1; const SODIUM_LIBRARY_VERSION = '1.0.8'; const SODIUM_BASE64_VARIANT_ORIGINAL = 1; const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3; const SODIUM_BASE64_VARIANT_URLSAFE = 5; const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7; const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32; const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12; const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12; const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16; const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32; const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24; const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16; const SODIUM_CRYPTO_AUTH_BYTES = 32; const SODIUM_CRYPTO_AUTH_KEYBYTES = 32; const SODIUM_CRYPTO_BOX_SEALBYTES = 16; const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32; const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32; const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64; const SODIUM_CRYPTO_BOX_MACBYTES = 16; const SODIUM_CRYPTO_BOX_NONCEBYTES = 24; const SODIUM_CRYPTO_BOX_SEEDBYTES = 32; const SODIUM_CRYPTO_KDF_BYTES_MIN = 16; const SODIUM_CRYPTO_KDF_BYTES_MAX = 64; const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8; const SODIUM_CRYPTO_KDF_KEYBYTES = 32; const SODIUM_CRYPTO_KX_BYTES = 32; const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b'; const SODIUM_CRYPTO_KX_SEEDBYTES = 32; const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64; const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32; const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32; const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32; const SODIUM_CRYPTO_GENERICHASH_BYTES = 32; const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16; const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64; const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32; const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16; const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64; const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16; const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$'; const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1; const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2; const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432; const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4; const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728; const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6; const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912; const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$'; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432; const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824; const SODIUM_CRYPTO_SCALARMULT_BYTES = 32; const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32; const SODIUM_CRYPTO_SHORTHASH_BYTES = 8; const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16; const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32; const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16; const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3; const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80; const SODIUM_CRYPTO_SIGN_BYTES = 64; const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32; const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32; const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64; const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96; const SODIUM_CRYPTO_STREAM_KEYBYTES = 32; const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24; const SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32; const SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24; <?php require_once dirname(dirname(__FILE__)) . '/autoload.php'; if (PHP_VERSION_ID < 50300) { return; } /* * This file is just for convenience, to allow developers to reduce verbosity when * they add this project to their libraries. * * Replace this: * * $x = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_encrypt(...$args); * * with this: * * use ParagonIE\Sodium\Compat; * * $x = Compat::crypto_aead_xchacha20poly1305_encrypt(...$args); */ spl_autoload_register(function ($class) { if ($class[0] === '\\') { $class = substr($class, 1); } $namespace = 'ParagonIE\\Sodium'; // Does the class use the namespace prefix? $len = strlen($namespace); if (strncmp($namespace, $class, $len) !== 0) { // no, move to the next registered autoloader return false; } // Get the relative class name $relative_class = substr($class, $len); // Replace the namespace prefix with the base directory, replace namespace // separators with directory separators in the relative class name, append // with .php $file = dirname(dirname(__FILE__)) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php'; // if the file exists, require it if (file_exists($file)) { require_once $file; return true; } return false; }); <?php const SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES = 16; const SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES = 32; const SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES = 32; const SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES = 32; const SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES = 0; const SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES = 32; const SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES = 32; <?php if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES')) { define( 'SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES', ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_BYTES ); define('SODIUM_COMPAT_POLYFILLED_RISTRETTO255', true); } if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES')) { define( 'SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES', ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_HASHBYTES ); } if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES')) { define( 'SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES', ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_SCALARBYTES ); } if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES')) { define( 'SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES', ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES ); } if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES')) { define( 'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES', ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES ); } if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES')) { define( 'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES', ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_BYTES ); } if (!is_callable('sodium_crypto_core_ristretto255_add')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_add() * * @param string $p * @param string $q * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_add( #[\SensitiveParameter] $p, #[\SensitiveParameter] $q ) { return ParagonIE_Sodium_Compat::ristretto255_add($p, $q, true); } } if (!is_callable('sodium_crypto_core_ristretto255_from_hash')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_from_hash() * * @param string $s * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_from_hash( #[\SensitiveParameter] $s ) { return ParagonIE_Sodium_Compat::ristretto255_from_hash($s, true); } } if (!is_callable('sodium_crypto_core_ristretto255_is_valid_point')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_is_valid_point() * * @param string $s * @return bool * @throws SodiumException */ function sodium_crypto_core_ristretto255_is_valid_point( #[\SensitiveParameter] $s ) { return ParagonIE_Sodium_Compat::ristretto255_is_valid_point($s, true); } } if (!is_callable('sodium_crypto_core_ristretto255_random')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_random() * * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_random() { return ParagonIE_Sodium_Compat::ristretto255_random(true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_add')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_add() * * @param string $x * @param string $y * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_add( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_add($x, $y, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_complement')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_complement() * * @param string $s * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_complement( #[\SensitiveParameter] $s ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_complement($s, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_invert')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_invert() * * @param string $p * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_invert( #[\SensitiveParameter] $p ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_mul')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_mul() * * @param string $x * @param string $y * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_mul( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_mul($x, $y, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_negate')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_negate() * * @param string $s * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_negate( #[\SensitiveParameter] $s ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_negate($s, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_random')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_random() * * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_random() { return ParagonIE_Sodium_Compat::ristretto255_scalar_random(true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_reduce() * * @param string $s * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_reduce( #[\SensitiveParameter] $s ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($s, true); } } if (!is_callable('sodium_crypto_core_ristretto255_scalar_sub')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_scalar_sub() * * @param string $x * @param string $y * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_scalar_sub( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y ) { return ParagonIE_Sodium_Compat::ristretto255_scalar_sub($x, $y, true); } } if (!is_callable('sodium_crypto_core_ristretto255_sub')) { /** * @see ParagonIE_Sodium_Compat::ristretto255_sub() * * @param string $p * @param string $q * @return string * @throws SodiumException */ function sodium_crypto_core_ristretto255_sub( #[\SensitiveParameter] $p, #[\SensitiveParameter] $q ) { return ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, true); } } if (!is_callable('sodium_crypto_scalarmult_ristretto255')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255() * @param string $n * @param string $p * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_scalarmult_ristretto255( #[\SensitiveParameter] $n, #[\SensitiveParameter] $p ) { return ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, true); } } if (!is_callable('sodium_crypto_scalarmult_ristretto255_base')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255_base() * @param string $n * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_scalarmult_ristretto255_base( #[\SensitiveParameter] $n ) { return ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, true); } }<?php require_once dirname(dirname(__FILE__)) . '/autoload.php'; /** * This file will monkey patch the pure-PHP implementation in place of the * PECL functions and constants, but only if they do not already exist. * * Thus, the functions or constants just proxy to the appropriate * ParagonIE_Sodium_Compat method or class constant, respectively. */ foreach (array( 'BASE64_VARIANT_ORIGINAL', 'BASE64_VARIANT_ORIGINAL_NO_PADDING', 'BASE64_VARIANT_URLSAFE', 'BASE64_VARIANT_URLSAFE_NO_PADDING', 'CRYPTO_AEAD_AES256GCM_KEYBYTES', 'CRYPTO_AEAD_AES256GCM_NSECBYTES', 'CRYPTO_AEAD_AES256GCM_NPUBBYTES', 'CRYPTO_AEAD_AES256GCM_ABYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_ABYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES', 'CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES', 'CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES', 'CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES', 'CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES', 'CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES', 'CRYPTO_AUTH_BYTES', 'CRYPTO_AUTH_KEYBYTES', 'CRYPTO_BOX_SEALBYTES', 'CRYPTO_BOX_SECRETKEYBYTES', 'CRYPTO_BOX_PUBLICKEYBYTES', 'CRYPTO_BOX_KEYPAIRBYTES', 'CRYPTO_BOX_MACBYTES', 'CRYPTO_BOX_NONCEBYTES', 'CRYPTO_BOX_SEEDBYTES', 'CRYPTO_KDF_BYTES_MIN', 'CRYPTO_KDF_BYTES_MAX', 'CRYPTO_KDF_CONTEXTBYTES', 'CRYPTO_KDF_KEYBYTES', 'CRYPTO_KX_BYTES', 'CRYPTO_KX_KEYPAIRBYTES', 'CRYPTO_KX_PRIMITIVE', 'CRYPTO_KX_SEEDBYTES', 'CRYPTO_KX_PUBLICKEYBYTES', 'CRYPTO_KX_SECRETKEYBYTES', 'CRYPTO_KX_SESSIONKEYBYTES', 'CRYPTO_GENERICHASH_BYTES', 'CRYPTO_GENERICHASH_BYTES_MIN', 'CRYPTO_GENERICHASH_BYTES_MAX', 'CRYPTO_GENERICHASH_KEYBYTES', 'CRYPTO_GENERICHASH_KEYBYTES_MIN', 'CRYPTO_GENERICHASH_KEYBYTES_MAX', 'CRYPTO_PWHASH_SALTBYTES', 'CRYPTO_PWHASH_STRPREFIX', 'CRYPTO_PWHASH_ALG_ARGON2I13', 'CRYPTO_PWHASH_ALG_ARGON2ID13', 'CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE', 'CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE', 'CRYPTO_PWHASH_MEMLIMIT_MODERATE', 'CRYPTO_PWHASH_OPSLIMIT_MODERATE', 'CRYPTO_PWHASH_MEMLIMIT_SENSITIVE', 'CRYPTO_PWHASH_OPSLIMIT_SENSITIVE', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE', 'CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE', 'CRYPTO_SCALARMULT_BYTES', 'CRYPTO_SCALARMULT_SCALARBYTES', 'CRYPTO_SHORTHASH_BYTES', 'CRYPTO_SHORTHASH_KEYBYTES', 'CRYPTO_SECRETBOX_KEYBYTES', 'CRYPTO_SECRETBOX_MACBYTES', 'CRYPTO_SECRETBOX_NONCEBYTES', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL', 'CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX', 'CRYPTO_SIGN_BYTES', 'CRYPTO_SIGN_SEEDBYTES', 'CRYPTO_SIGN_PUBLICKEYBYTES', 'CRYPTO_SIGN_SECRETKEYBYTES', 'CRYPTO_SIGN_KEYPAIRBYTES', 'CRYPTO_STREAM_KEYBYTES', 'CRYPTO_STREAM_NONCEBYTES', 'CRYPTO_STREAM_XCHACHA20_KEYBYTES', 'CRYPTO_STREAM_XCHACHA20_NONCEBYTES', 'LIBRARY_MAJOR_VERSION', 'LIBRARY_MINOR_VERSION', 'LIBRARY_VERSION_MAJOR', 'LIBRARY_VERSION_MINOR', 'VERSION_STRING' ) as $constant ) { if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) { define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant")); } } if (!is_callable('sodium_add')) { /** * @see ParagonIE_Sodium_Compat::add() * @param string $string1 * @param string $string2 * @return void * @throws SodiumException */ function sodium_add( #[\SensitiveParameter] &$string1, #[\SensitiveParameter] $string2 ) { ParagonIE_Sodium_Compat::add($string1, $string2); } } if (!is_callable('sodium_base642bin')) { /** * @see ParagonIE_Sodium_Compat::bin2base64() * @param string $string * @param int $variant * @param string $ignore * @return string * @throws SodiumException * @throws TypeError */ function sodium_base642bin( #[\SensitiveParameter] $string, $variant, $ignore ='' ) { return ParagonIE_Sodium_Compat::base642bin($string, $variant, $ignore); } } if (!is_callable('sodium_bin2base64')) { /** * @see ParagonIE_Sodium_Compat::bin2base64() * @param string $string * @param int $variant * @return string * @throws SodiumException * @throws TypeError */ function sodium_bin2base64( #[\SensitiveParameter] $string, $variant ) { return ParagonIE_Sodium_Compat::bin2base64($string, $variant); } } if (!is_callable('sodium_bin2hex')) { /** * @see ParagonIE_Sodium_Compat::hex2bin() * @param string $string * @return string * @throws SodiumException * @throws TypeError */ function sodium_bin2hex( #[\SensitiveParameter] $string ) { return ParagonIE_Sodium_Compat::bin2hex($string); } } if (!is_callable('sodium_compare')) { /** * @see ParagonIE_Sodium_Compat::compare() * @param string $string1 * @param string $string2 * @return int * @throws SodiumException * @throws TypeError */ function sodium_compare( #[\SensitiveParameter] $string1, #[\SensitiveParameter] $string2 ) { return ParagonIE_Sodium_Compat::compare($string1, $string2); } } if (!is_callable('sodium_crypto_aead_aes256gcm_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt() * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string|bool */ function sodium_crypto_aead_aes256gcm_decrypt( $ciphertext, $additional_data, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt( $ciphertext, $additional_data, $nonce, $key ); } catch (Error $ex) { return false; } catch (Exception $ex) { if (($ex instanceof SodiumException) && ($ex->getMessage() === 'AES-256-GCM is not available')) { throw $ex; } return false; } } } if (!is_callable('sodium_crypto_aead_aes256gcm_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_aes256gcm_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $additional_data, $nonce, $key); } } if (!is_callable('sodium_crypto_aead_aes256gcm_is_available')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available() * @return bool */ function sodium_crypto_aead_aes256gcm_is_available() { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available(); } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt() * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string|bool */ function sodium_crypto_aead_chacha20poly1305_decrypt( $ciphertext, $additional_data, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt( $ciphertext, $additional_data, $nonce, $key ); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_chacha20poly1305_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt( $message, $additional_data, $nonce, $key ); } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_keygen() * @return string * @throws Exception */ function sodium_crypto_aead_chacha20poly1305_keygen() { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_keygen(); } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string|bool */ function sodium_crypto_aead_chacha20poly1305_ietf_decrypt( $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt( $message, $additional_data, $nonce, $key ); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_chacha20poly1305_ietf_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt( $message, $additional_data, $nonce, $key ); } } if (!is_callable('sodium_crypto_aead_chacha20poly1305_ietf_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_keygen() * @return string * @throws Exception */ function sodium_crypto_aead_chacha20poly1305_ietf_keygen() { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_keygen(); } } if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt() * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string|bool */ function sodium_crypto_aead_xchacha20poly1305_ietf_decrypt( $ciphertext, $additional_data, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_decrypt( $ciphertext, $additional_data, $nonce, $key, true ); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_xchacha20poly1305_ietf_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt( $message, $additional_data, $nonce, $key, true ); } } if (!is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_keygen() * @return string * @throws Exception */ function sodium_crypto_aead_xchacha20poly1305_ietf_keygen() { return ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_keygen(); } } if (!is_callable('sodium_crypto_auth')) { /** * @see ParagonIE_Sodium_Compat::crypto_auth() * @param string $message * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_auth( $message, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_auth($message, $key); } } if (!is_callable('sodium_crypto_auth_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_auth_keygen() * @return string * @throws Exception */ function sodium_crypto_auth_keygen() { return ParagonIE_Sodium_Compat::crypto_auth_keygen(); } } if (!is_callable('sodium_crypto_auth_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_auth_verify() * @param string $mac * @param string $message * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ function sodium_crypto_auth_verify( $mac, $message, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key); } } if (!is_callable('sodium_crypto_box')) { /** * @see ParagonIE_Sodium_Compat::crypto_box() * @param string $message * @param string $nonce * @param string $key_pair * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $key_pair); } } if (!is_callable('sodium_crypto_box_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_keypair() * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_keypair() { return ParagonIE_Sodium_Compat::crypto_box_keypair(); } } if (!is_callable('sodium_crypto_box_keypair_from_secretkey_and_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey() * @param string $secret_key * @param string $public_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_keypair_from_secretkey_and_publickey( #[\SensitiveParameter] $secret_key, $public_key ) { return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($secret_key, $public_key); } } if (!is_callable('sodium_crypto_box_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_open() * @param string $ciphertext * @param string $nonce * @param string $key_pair * @return string|bool */ function sodium_crypto_box_open( $ciphertext, $nonce, #[\SensitiveParameter] $key_pair ) { try { return ParagonIE_Sodium_Compat::crypto_box_open($ciphertext, $nonce, $key_pair); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_box_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_publickey() * @param string $key_pair * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_publickey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_box_publickey($key_pair); } } if (!is_callable('sodium_crypto_box_publickey_from_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey() * @param string $secret_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_publickey_from_secretkey( #[\SensitiveParameter] $secret_key ) { return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($secret_key); } } if (!is_callable('sodium_crypto_box_seal')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_seal() * @param string $message * @param string $public_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_seal( #[\SensitiveParameter] $message, $public_key ) { return ParagonIE_Sodium_Compat::crypto_box_seal($message, $public_key); } } if (!is_callable('sodium_crypto_box_seal_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_seal_open() * @param string $message * @param string $key_pair * @return string|bool * @throws SodiumException */ function sodium_crypto_box_seal_open( $message, #[\SensitiveParameter] $key_pair ) { try { return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $key_pair); } catch (SodiumException $ex) { if ($ex->getMessage() === 'Argument 2 must be CRYPTO_BOX_KEYPAIRBYTES long.') { throw $ex; } return false; } } } if (!is_callable('sodium_crypto_box_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_secretkey() * @param string $key_pair * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_secretkey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_box_secretkey($key_pair); } } if (!is_callable('sodium_crypto_box_seed_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_seed_keypair() * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_box_seed_keypair( #[\SensitiveParameter] $seed ) { return ParagonIE_Sodium_Compat::crypto_box_seed_keypair($seed); } } if (!is_callable('sodium_crypto_generichash')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash() * @param string $message * @param string|null $key * @param int $length * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_generichash( $message, #[\SensitiveParameter] $key = null, $length = 32 ) { return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $length); } } if (!is_callable('sodium_crypto_generichash_final')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_final() * @param string|null $state * @param int $outputLength * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_generichash_final(&$state, $outputLength = 32) { return ParagonIE_Sodium_Compat::crypto_generichash_final($state, $outputLength); } } if (!is_callable('sodium_crypto_generichash_init')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_init() * @param string|null $key * @param int $length * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_generichash_init( #[\SensitiveParameter] $key = null, $length = 32 ) { return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $length); } } if (!is_callable('sodium_crypto_generichash_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_keygen() * @return string * @throws Exception */ function sodium_crypto_generichash_keygen() { return ParagonIE_Sodium_Compat::crypto_generichash_keygen(); } } if (!is_callable('sodium_crypto_generichash_update')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_update() * @param string|null $state * @param string $message * @return void * @throws SodiumException * @throws TypeError */ function sodium_crypto_generichash_update( #[\SensitiveParameter] &$state, $message = '' ) { ParagonIE_Sodium_Compat::crypto_generichash_update($state, $message); } } if (!is_callable('sodium_crypto_kdf_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_kdf_keygen() * @return string * @throws Exception */ function sodium_crypto_kdf_keygen() { return ParagonIE_Sodium_Compat::crypto_kdf_keygen(); } } if (!is_callable('sodium_crypto_kdf_derive_from_key')) { /** * @see ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key() * @param int $subkey_length * @param int $subkey_id * @param string $context * @param string $key * @return string * @throws Exception */ function sodium_crypto_kdf_derive_from_key( $subkey_length, $subkey_id, $context, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_kdf_derive_from_key( $subkey_length, $subkey_id, $context, $key ); } } if (!is_callable('sodium_crypto_kx')) { /** * @see ParagonIE_Sodium_Compat::crypto_kx() * @param string $my_secret * @param string $their_public * @param string $client_public * @param string $server_public * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_kx( #[\SensitiveParameter] $my_secret, $their_public, $client_public, $server_public ) { return ParagonIE_Sodium_Compat::crypto_kx( $my_secret, $their_public, $client_public, $server_public ); } } if (!is_callable('sodium_crypto_kx_seed_keypair')) { /** * @param string $seed * @return string * @throws Exception */ function sodium_crypto_kx_seed_keypair( #[\SensitiveParameter] $seed ) { return ParagonIE_Sodium_Compat::crypto_kx_seed_keypair($seed); } } if (!is_callable('sodium_crypto_kx_keypair')) { /** * @return string * @throws Exception */ function sodium_crypto_kx_keypair() { return ParagonIE_Sodium_Compat::crypto_kx_keypair(); } } if (!is_callable('sodium_crypto_kx_client_session_keys')) { /** * @param string $client_key_pair * @param string $server_key * @return array{0: string, 1: string} * @throws SodiumException */ function sodium_crypto_kx_client_session_keys( #[\SensitiveParameter] $client_key_pair, $server_key ) { return ParagonIE_Sodium_Compat::crypto_kx_client_session_keys($client_key_pair, $server_key); } } if (!is_callable('sodium_crypto_kx_server_session_keys')) { /** * @param string $server_key_pair * @param string $client_key * @return array{0: string, 1: string} * @throws SodiumException */ function sodium_crypto_kx_server_session_keys( #[\SensitiveParameter] $server_key_pair, $client_key ) { return ParagonIE_Sodium_Compat::crypto_kx_server_session_keys($server_key_pair, $client_key); } } if (!is_callable('sodium_crypto_kx_secretkey')) { /** * @param string $key_pair * @return string * @throws Exception */ function sodium_crypto_kx_secretkey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_kx_secretkey($key_pair); } } if (!is_callable('sodium_crypto_kx_publickey')) { /** * @param string $key_pair * @return string * @throws Exception */ function sodium_crypto_kx_publickey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_kx_publickey($key_pair); } } if (!is_callable('sodium_crypto_pwhash')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash() * @param int $length * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @param int|null $algo * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash( $length, #[\SensitiveParameter] $passwd, $salt, $opslimit, $memlimit, $algo = null ) { return ParagonIE_Sodium_Compat::crypto_pwhash($length, $passwd, $salt, $opslimit, $memlimit, $algo); } } if (!is_callable('sodium_crypto_pwhash_str')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_str() * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit); } } if (!is_callable('sodium_crypto_pwhash_str_needs_rehash')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash() * @param string $hash * @param int $opslimit * @param int $memlimit * @return bool * * @throws SodiumException */ function sodium_crypto_pwhash_str_needs_rehash( #[\SensitiveParameter] $hash, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_str_needs_rehash($hash, $opslimit, $memlimit); } } if (!is_callable('sodium_crypto_pwhash_str_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_verify() * @param string $passwd * @param string $hash * @return bool * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash); } } if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256() * @param int $length * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash_scryptsalsa208sha256( $length, #[\SensitiveParameter] $passwd, $salt, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256( $length, $passwd, $salt, $opslimit, $memlimit ); } } if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256_str')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str() * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash_scryptsalsa208sha256_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit); } } if (!is_callable('sodium_crypto_pwhash_scryptsalsa208sha256_str_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify() * @param string $passwd * @param string $hash * @return bool * @throws SodiumException * @throws TypeError */ function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash); } } if (!is_callable('sodium_crypto_scalarmult')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult() * @param string $n * @param string $p * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_scalarmult( #[\SensitiveParameter] $n, $p ) { return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p); } } if (!is_callable('sodium_crypto_scalarmult_base')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult_base() * @param string $n * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_scalarmult_base( #[\SensitiveParameter] $n ) { return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n); } } if (!is_callable('sodium_crypto_secretbox')) { /** * @see ParagonIE_Sodium_Compat::crypto_secretbox() * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_secretbox( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key); } } if (!is_callable('sodium_crypto_secretbox_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_secretbox_keygen() * @return string * @throws Exception */ function sodium_crypto_secretbox_keygen() { return ParagonIE_Sodium_Compat::crypto_secretbox_keygen(); } } if (!is_callable('sodium_crypto_secretbox_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_secretbox_open() * @param string $ciphertext * @param string $nonce * @param string $key * @return string|bool */ function sodium_crypto_secretbox_open( $ciphertext, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_secretbox_open($ciphertext, $nonce, $key); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_push')) { /** * @param string $key * @return array<int, string> * @throws SodiumException */ function sodium_crypto_secretstream_xchacha20poly1305_init_push( #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_push($key); } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_push')) { /** * @param string $state * @param string $message * @param string $additional_data * @param int $tag * @return string * @throws SodiumException */ function sodium_crypto_secretstream_xchacha20poly1305_push( #[\SensitiveParameter] &$state, #[\SensitiveParameter] $message, $additional_data = '', $tag = 0 ) { return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_push( $state, $message, $additional_data, $tag ); } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_init_pull')) { /** * @param string $header * @param string $key * @return string * @throws Exception */ function sodium_crypto_secretstream_xchacha20poly1305_init_pull( $header, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_init_pull($header, $key); } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_pull')) { /** * @param string $state * @param string $ciphertext * @param string $additional_data * @return bool|array{0: string, 1: int} * @throws SodiumException */ function sodium_crypto_secretstream_xchacha20poly1305_pull( #[\SensitiveParameter] &$state, $ciphertext, $additional_data = '' ) { return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_pull( $state, $ciphertext, $additional_data ); } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_rekey')) { /** * @param string $state * @return void * @throws SodiumException */ function sodium_crypto_secretstream_xchacha20poly1305_rekey( #[\SensitiveParameter] &$state ) { ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_rekey($state); } } if (!is_callable('sodium_crypto_secretstream_xchacha20poly1305_keygen')) { /** * @return string * @throws Exception */ function sodium_crypto_secretstream_xchacha20poly1305_keygen() { return ParagonIE_Sodium_Compat::crypto_secretstream_xchacha20poly1305_keygen(); } } if (!is_callable('sodium_crypto_shorthash')) { /** * @see ParagonIE_Sodium_Compat::crypto_shorthash() * @param string $message * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_shorthash( $message, #[\SensitiveParameter] $key = '' ) { return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key); } } if (!is_callable('sodium_crypto_shorthash_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_shorthash_keygen() * @return string * @throws Exception */ function sodium_crypto_shorthash_keygen() { return ParagonIE_Sodium_Compat::crypto_shorthash_keygen(); } } if (!is_callable('sodium_crypto_sign')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign() * @param string $message * @param string $secret_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign( $message, #[\SensitiveParameter] $secret_key ) { return ParagonIE_Sodium_Compat::crypto_sign($message, $secret_key); } } if (!is_callable('sodium_crypto_sign_detached')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_detached() * @param string $message * @param string $secret_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_detached( $message, #[\SensitiveParameter] $secret_key ) { return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $secret_key); } } if (!is_callable('sodium_crypto_sign_keypair_from_secretkey_and_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey() * @param string $secret_key * @param string $public_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_keypair_from_secretkey_and_publickey( #[\SensitiveParameter] $secret_key, $public_key ) { return ParagonIE_Sodium_Compat::crypto_sign_keypair_from_secretkey_and_publickey($secret_key, $public_key); } } if (!is_callable('sodium_crypto_sign_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_keypair() * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_keypair() { return ParagonIE_Sodium_Compat::crypto_sign_keypair(); } } if (!is_callable('sodium_crypto_sign_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_open() * @param string $signedMessage * @param string $public_key * @return string|bool */ function sodium_crypto_sign_open($signedMessage, $public_key) { try { return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $public_key); } catch (Error $ex) { return false; } catch (Exception $ex) { return false; } } } if (!is_callable('sodium_crypto_sign_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_publickey() * @param string $key_pair * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_publickey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_sign_publickey($key_pair); } } if (!is_callable('sodium_crypto_sign_publickey_from_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey() * @param string $secret_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_publickey_from_secretkey( #[\SensitiveParameter] $secret_key ) { return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($secret_key); } } if (!is_callable('sodium_crypto_sign_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_secretkey() * @param string $key_pair * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_secretkey( #[\SensitiveParameter] $key_pair ) { return ParagonIE_Sodium_Compat::crypto_sign_secretkey($key_pair); } } if (!is_callable('sodium_crypto_sign_seed_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_seed_keypair() * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_seed_keypair( #[\SensitiveParameter] $seed ) { return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed); } } if (!is_callable('sodium_crypto_sign_verify_detached')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_verify_detached() * @param string $signature * @param string $message * @param string $public_key * @return bool * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_verify_detached($signature, $message, $public_key) { return ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $public_key); } } if (!is_callable('sodium_crypto_sign_ed25519_pk_to_curve25519')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519() * @param string $public_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_ed25519_pk_to_curve25519($public_key) { return ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519($public_key); } } if (!is_callable('sodium_crypto_sign_ed25519_sk_to_curve25519')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519() * @param string $secret_key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_sign_ed25519_sk_to_curve25519( #[\SensitiveParameter] $secret_key ) { return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($secret_key); } } if (!is_callable('sodium_crypto_stream')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream() * @param int $length * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_stream( $length, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream($length, $nonce, $key); } } if (!is_callable('sodium_crypto_stream_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_keygen() * @return string * @throws Exception */ function sodium_crypto_stream_keygen() { return ParagonIE_Sodium_Compat::crypto_stream_keygen(); } } if (!is_callable('sodium_crypto_stream_xor')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xor() * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_stream_xor( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key); } } require_once dirname(__FILE__) . '/stream-xchacha20.php'; if (!is_callable('sodium_hex2bin')) { /** * @see ParagonIE_Sodium_Compat::hex2bin() * @param string $string * @param string $ignore * @return string * @throws SodiumException * @throws TypeError */ function sodium_hex2bin( #[\SensitiveParameter] $string, $ignore = '' ) { return ParagonIE_Sodium_Compat::hex2bin($string, $ignore); } } if (!is_callable('sodium_increment')) { /** * @see ParagonIE_Sodium_Compat::increment() * @param string $string * @return void * @throws SodiumException * @throws TypeError */ function sodium_increment( #[\SensitiveParameter] &$string ) { ParagonIE_Sodium_Compat::increment($string); } } if (!is_callable('sodium_library_version_major')) { /** * @see ParagonIE_Sodium_Compat::library_version_major() * @return int */ function sodium_library_version_major() { return ParagonIE_Sodium_Compat::library_version_major(); } } if (!is_callable('sodium_library_version_minor')) { /** * @see ParagonIE_Sodium_Compat::library_version_minor() * @return int */ function sodium_library_version_minor() { return ParagonIE_Sodium_Compat::library_version_minor(); } } if (!is_callable('sodium_version_string')) { /** * @see ParagonIE_Sodium_Compat::version_string() * @return string */ function sodium_version_string() { return ParagonIE_Sodium_Compat::version_string(); } } if (!is_callable('sodium_memcmp')) { /** * @see ParagonIE_Sodium_Compat::memcmp() * @param string $string1 * @param string $string2 * @return int * @throws SodiumException * @throws TypeError */ function sodium_memcmp( #[\SensitiveParameter] $string1, #[\SensitiveParameter] $string2 ) { return ParagonIE_Sodium_Compat::memcmp($string1, $string2); } } if (!is_callable('sodium_memzero')) { /** * @see ParagonIE_Sodium_Compat::memzero() * @param string $string * @return void * @throws SodiumException * @throws TypeError * * @psalm-suppress ReferenceConstraintViolation */ function sodium_memzero( #[\SensitiveParameter] &$string ) { ParagonIE_Sodium_Compat::memzero($string); } } if (!is_callable('sodium_pad')) { /** * @see ParagonIE_Sodium_Compat::pad() * @param string $unpadded * @param int $block_size * @return string * @throws SodiumException * @throws TypeError */ function sodium_pad( #[\SensitiveParameter] $unpadded, $block_size ) { return ParagonIE_Sodium_Compat::pad($unpadded, $block_size, true); } } if (!is_callable('sodium_unpad')) { /** * @see ParagonIE_Sodium_Compat::pad() * @param string $padded * @param int $block_size * @return string * @throws SodiumException * @throws TypeError */ function sodium_unpad( #[\SensitiveParameter] $padded, $block_size ) { return ParagonIE_Sodium_Compat::unpad($padded, $block_size, true); } } if (!is_callable('sodium_randombytes_buf')) { /** * @see ParagonIE_Sodium_Compat::randombytes_buf() * @param int $amount * @return string * @throws Exception */ function sodium_randombytes_buf($amount) { return ParagonIE_Sodium_Compat::randombytes_buf($amount); } } if (!is_callable('sodium_randombytes_uniform')) { /** * @see ParagonIE_Sodium_Compat::randombytes_uniform() * @param int $upperLimit * @return int * @throws Exception */ function sodium_randombytes_uniform($upperLimit) { return ParagonIE_Sodium_Compat::randombytes_uniform($upperLimit); } } if (!is_callable('sodium_randombytes_random16')) { /** * @see ParagonIE_Sodium_Compat::randombytes_random16() * @return int * @throws Exception */ function sodium_randombytes_random16() { return ParagonIE_Sodium_Compat::randombytes_random16(); } } <?php require_once dirname(dirname(__FILE__)) . '/autoload.php'; /** * This file will monkey patch the pure-PHP implementation in place of the * PECL functions and constants, but only if they do not already exist. * * Thus, the functions or constants just proxy to the appropriate * ParagonIE_Sodium_Compat method or class constant, respectively. */ foreach (array( 'CRYPTO_AEAD_AESGIS128L_KEYBYTES', 'CRYPTO_AEAD_AESGIS128L_NSECBYTES', 'CRYPTO_AEAD_AESGIS128L_NPUBBYTES', 'CRYPTO_AEAD_AESGIS128L_ABYTES', 'CRYPTO_AEAD_AESGIS256_KEYBYTES', 'CRYPTO_AEAD_AESGIS256_NSECBYTES', 'CRYPTO_AEAD_AESGIS256_NPUBBYTES', 'CRYPTO_AEAD_AESGIS256_ABYTES', ) as $constant ) { if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) { define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant")); } } if (!is_callable('sodium_crypto_aead_aegis128l_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt() * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException */ function sodium_crypto_aead_aegis128l_decrypt( $ciphertext, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt( $ciphertext, $additional_data, $nonce, $key ); } } if (!is_callable('sodium_crypto_aead_aegis128l_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_aegis128l_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt( $message, $additional_data, $nonce, $key ); } } if (!is_callable('sodium_crypto_aead_aegis256_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt() * @param string $ciphertext * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException */ function sodium_crypto_aead_aegis256_decrypt( $ciphertext, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aegis256_decrypt( $ciphertext, $additional_data, $nonce, $key ); } } if (!is_callable('sodium_crypto_aead_aegis256_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt() * @param string $message * @param string $additional_data * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_aead_aegis256_encrypt( #[\SensitiveParameter] $message, $additional_data, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt( $message, $additional_data, $nonce, $key ); } } <?php if (!is_callable('sodium_crypto_stream_xchacha20')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20() * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_stream_xchacha20( $len, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, true); } } if (!is_callable('sodium_crypto_stream_xchacha20_keygen')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen() * @return string * @throws Exception */ function sodium_crypto_stream_xchacha20_keygen() { return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen(); } } if (!is_callable('sodium_crypto_stream_xchacha20_xor')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor() * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_stream_xchacha20_xor( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, true); } } if (!is_callable('sodium_crypto_stream_xchacha20_xor_ic')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic() * @param string $message * @param string $nonce * @param int $counter * @param string $key * @return string * @throws SodiumException * @throws TypeError */ function sodium_crypto_stream_xchacha20_xor_ic( #[\SensitiveParameter] $message, $nonce, $counter, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic($message, $nonce, $counter, $key, true); } } <?php namespace Sodium; require_once dirname(dirname(__FILE__)) . '/autoload.php'; use ParagonIE_Sodium_Compat; /** * This file will monkey patch the pure-PHP implementation in place of the * PECL functions, but only if they do not already exist. * * Thus, the functions just proxy to the appropriate ParagonIE_Sodium_Compat * method. */ if (!is_callable('\\Sodium\\bin2hex')) { /** * @see ParagonIE_Sodium_Compat::bin2hex() * @param string $string * @return string * @throws \SodiumException * @throws \TypeError */ function bin2hex( #[\SensitiveParameter] $string ) { return ParagonIE_Sodium_Compat::bin2hex($string); } } if (!is_callable('\\Sodium\\compare')) { /** * @see ParagonIE_Sodium_Compat::compare() * @param string $a * @param string $b * @return int * @throws \SodiumException * @throws \TypeError */ function compare( #[\SensitiveParameter] $a, #[\SensitiveParameter] $b ) { return ParagonIE_Sodium_Compat::compare($a, $b); } } if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string|bool */ function crypto_aead_aes256gcm_decrypt( $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_aead_aes256gcm_encrypt( #[\SensitiveParameter] $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $assocData, $nonce, $key); } } if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_is_available')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available() * @return bool */ function crypto_aead_aes256gcm_is_available() { return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available(); } } if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string|bool */ function crypto_aead_chacha20poly1305_decrypt( $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_aead_chacha20poly1305_encrypt( #[\SensitiveParameter] $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key); } } if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string|bool */ function crypto_aead_chacha20poly1305_ietf_decrypt( $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_encrypt')) { /** * @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt() * @param string $message * @param string $assocData * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_aead_chacha20poly1305_ietf_encrypt( #[\SensitiveParameter] $message, $assocData, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key); } } if (!is_callable('\\Sodium\\crypto_auth')) { /** * @see ParagonIE_Sodium_Compat::crypto_auth() * @param string $message * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_auth( $message, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_auth($message, $key); } } if (!is_callable('\\Sodium\\crypto_auth_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_auth_verify() * @param string $mac * @param string $message * @param string $key * @return bool * @throws \SodiumException * @throws \TypeError */ function crypto_auth_verify( $mac, $message, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key); } } if (!is_callable('\\Sodium\\crypto_box')) { /** * @see ParagonIE_Sodium_Compat::crypto_box() * @param string $message * @param string $nonce * @param string $kp * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $kp ) { return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $kp); } } if (!is_callable('\\Sodium\\crypto_box_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_keypair() * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_keypair() { return ParagonIE_Sodium_Compat::crypto_box_keypair(); } } if (!is_callable('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey() * @param string $sk * @param string $pk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_keypair_from_secretkey_and_publickey( #[\SensitiveParameter] $sk, $pk ) { return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($sk, $pk); } } if (!is_callable('\\Sodium\\crypto_box_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_open() * @param string $message * @param string $nonce * @param string $kp * @return string|bool */ function crypto_box_open( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $kp ) { try { return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_box_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_publickey() * @param string $keypair * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_publickey( #[\SensitiveParameter] $keypair ) { return ParagonIE_Sodium_Compat::crypto_box_publickey($keypair); } } if (!is_callable('\\Sodium\\crypto_box_publickey_from_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey() * @param string $sk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_publickey_from_secretkey( #[\SensitiveParameter] $sk ) { return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($sk); } } if (!is_callable('\\Sodium\\crypto_box_seal')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_seal_open() * @param string $message * @param string $publicKey * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_seal( #[\SensitiveParameter] $message, $publicKey ) { return ParagonIE_Sodium_Compat::crypto_box_seal($message, $publicKey); } } if (!is_callable('\\Sodium\\crypto_box_seal_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_seal_open() * @param string $message * @param string $kp * @return string|bool */ function crypto_box_seal_open( $message, #[\SensitiveParameter] $kp ) { try { return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_box_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_box_secretkey() * @param string $keypair * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_box_secretkey( #[\SensitiveParameter] $keypair ) { return ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair); } } if (!is_callable('\\Sodium\\crypto_generichash')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash() * @param string $message * @param string|null $key * @param int $outLen * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_generichash( $message, #[\SensitiveParameter] $key = null, $outLen = 32 ) { return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $outLen); } } if (!is_callable('\\Sodium\\crypto_generichash_final')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_final() * @param string|null $ctx * @param int $outputLength * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_generichash_final( #[\SensitiveParameter] &$ctx, $outputLength = 32 ) { return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength); } } if (!is_callable('\\Sodium\\crypto_generichash_init')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_init() * @param string|null $key * @param int $outLen * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_generichash_init( #[\SensitiveParameter] $key = null, $outLen = 32 ) { return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outLen); } } if (!is_callable('\\Sodium\\crypto_generichash_update')) { /** * @see ParagonIE_Sodium_Compat::crypto_generichash_update() * @param string|null $ctx * @param string $message * @return void * @throws \SodiumException * @throws \TypeError */ function crypto_generichash_update( #[\SensitiveParameter] &$ctx, $message = '' ) { ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message); } } if (!is_callable('\\Sodium\\crypto_kx')) { /** * @see ParagonIE_Sodium_Compat::crypto_kx() * @param string $my_secret * @param string $their_public * @param string $client_public * @param string $server_public * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_kx( #[\SensitiveParameter] $my_secret, $their_public, $client_public, $server_public ) { return ParagonIE_Sodium_Compat::crypto_kx( $my_secret, $their_public, $client_public, $server_public, true ); } } if (!is_callable('\\Sodium\\crypto_pwhash')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash() * @param int $outlen * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash( $outlen, #[\SensitiveParameter] $passwd, $salt, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit); } } if (!is_callable('\\Sodium\\crypto_pwhash_str')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_str() * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit); } } if (!is_callable('\\Sodium\\crypto_pwhash_str_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_str_verify() * @param string $passwd * @param string $hash * @return bool * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash); } } if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256() * @param int $outlen * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash_scryptsalsa208sha256( $outlen, #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $salt, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256($outlen, $passwd, $salt, $opslimit, $memlimit); } } if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str() * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash_scryptsalsa208sha256_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit); } } if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify')) { /** * @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify() * @param string $passwd * @param string $hash * @return bool * @throws \SodiumException * @throws \TypeError */ function crypto_pwhash_scryptsalsa208sha256_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash); } } if (!is_callable('\\Sodium\\crypto_scalarmult')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult() * @param string $n * @param string $p * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_scalarmult( #[\SensitiveParameter] $n, $p ) { return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p); } } if (!is_callable('\\Sodium\\crypto_scalarmult_base')) { /** * @see ParagonIE_Sodium_Compat::crypto_scalarmult_base() * @param string $n * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_scalarmult_base( #[\SensitiveParameter] $n ) { return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n); } } if (!is_callable('\\Sodium\\crypto_secretbox')) { /** * @see ParagonIE_Sodium_Compat::crypto_secretbox() * @param string $message * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_secretbox( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key); } } if (!is_callable('\\Sodium\\crypto_secretbox_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_secretbox_open() * @param string $message * @param string $nonce * @param string $key * @return string|bool */ function crypto_secretbox_open( $message, $nonce, #[\SensitiveParameter] $key ) { try { return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_shorthash')) { /** * @see ParagonIE_Sodium_Compat::crypto_shorthash() * @param string $message * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_shorthash( $message, #[\SensitiveParameter] $key = '' ) { return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key); } } if (!is_callable('\\Sodium\\crypto_sign')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign() * @param string $message * @param string $sk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign( $message, #[\SensitiveParameter] $sk ) { return ParagonIE_Sodium_Compat::crypto_sign($message, $sk); } } if (!is_callable('\\Sodium\\crypto_sign_detached')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_detached() * @param string $message * @param string $sk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_detached( $message, #[\SensitiveParameter] $sk ) { return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk); } } if (!is_callable('\\Sodium\\crypto_sign_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_keypair() * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_keypair() { return ParagonIE_Sodium_Compat::crypto_sign_keypair(); } } if (!is_callable('\\Sodium\\crypto_sign_open')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_open() * @param string $signedMessage * @param string $pk * @return string|bool */ function crypto_sign_open($signedMessage, $pk) { try { return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk); } catch (\TypeError $ex) { return false; } catch (\SodiumException $ex) { return false; } } } if (!is_callable('\\Sodium\\crypto_sign_publickey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_publickey() * @param string $keypair * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_publickey( #[\SensitiveParameter] $keypair ) { return ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair); } } if (!is_callable('\\Sodium\\crypto_sign_publickey_from_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey() * @param string $sk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_publickey_from_secretkey( #[\SensitiveParameter] $sk ) { return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($sk); } } if (!is_callable('\\Sodium\\crypto_sign_secretkey')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_secretkey() * @param string $keypair * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_secretkey( #[\SensitiveParameter] $keypair ) { return ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair); } } if (!is_callable('\\Sodium\\crypto_sign_seed_keypair')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_seed_keypair() * @param string $seed * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_seed_keypair( #[\SensitiveParameter] $seed ) { return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed); } } if (!is_callable('\\Sodium\\crypto_sign_verify_detached')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_verify_detached() * @param string $signature * @param string $message * @param string $pk * @return bool * @throws \SodiumException * @throws \TypeError */ function crypto_sign_verify_detached($signature, $message, $pk) { return ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $pk); } } if (!is_callable('\\Sodium\\crypto_sign_ed25519_pk_to_curve25519')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519() * @param string $pk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_ed25519_pk_to_curve25519($pk) { return ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519($pk); } } if (!is_callable('\\Sodium\\crypto_sign_ed25519_sk_to_curve25519')) { /** * @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519() * @param string $sk * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_sign_ed25519_sk_to_curve25519( #[\SensitiveParameter] $sk ) { return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($sk); } } if (!is_callable('\\Sodium\\crypto_stream')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream() * @param int $len * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_stream( $len, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream($len, $nonce, $key); } } if (!is_callable('\\Sodium\\crypto_stream_xor')) { /** * @see ParagonIE_Sodium_Compat::crypto_stream_xor() * @param string $message * @param string $nonce * @param string $key * @return string * @throws \SodiumException * @throws \TypeError */ function crypto_stream_xor( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key); } } if (!is_callable('\\Sodium\\hex2bin')) { /** * @see ParagonIE_Sodium_Compat::hex2bin() * @param string $string * @return string * @throws \SodiumException * @throws \TypeError */ function hex2bin( #[\SensitiveParameter] $string ) { return ParagonIE_Sodium_Compat::hex2bin($string); } } if (!is_callable('\\Sodium\\memcmp')) { /** * @see ParagonIE_Sodium_Compat::memcmp() * @param string $a * @param string $b * @return int * @throws \SodiumException * @throws \TypeError */ function memcmp( #[\SensitiveParameter] $a, #[\SensitiveParameter] $b ) { return ParagonIE_Sodium_Compat::memcmp($a, $b); } } if (!is_callable('\\Sodium\\memzero')) { /** * @see ParagonIE_Sodium_Compat::memzero() * @param string $str * @return void * @throws \SodiumException * @throws \TypeError * * @psalm-suppress MissingParamType * @psalm-suppress MissingReturnType * @psalm-suppress ReferenceConstraintViolation */ function memzero( #[\SensitiveParameter] &$str ) { ParagonIE_Sodium_Compat::memzero($str); } } if (!is_callable('\\Sodium\\randombytes_buf')) { /** * @see ParagonIE_Sodium_Compat::randombytes_buf() * @param int $amount * @return string * @throws \TypeError */ function randombytes_buf($amount) { return ParagonIE_Sodium_Compat::randombytes_buf($amount); } } if (!is_callable('\\Sodium\\randombytes_uniform')) { /** * @see ParagonIE_Sodium_Compat::randombytes_uniform() * @param int $upperLimit * @return int * @throws \SodiumException * @throws \Error */ function randombytes_uniform($upperLimit) { return ParagonIE_Sodium_Compat::randombytes_uniform($upperLimit); } } if (!is_callable('\\Sodium\\randombytes_random16')) { /** * @see ParagonIE_Sodium_Compat::randombytes_random16() * @return int */ function randombytes_random16() { return ParagonIE_Sodium_Compat::randombytes_random16(); } } if (!defined('\\Sodium\\CRYPTO_AUTH_BYTES')) { require_once dirname(__FILE__) . '/constants.php'; } <?php namespace Sodium; require_once dirname(dirname(__FILE__)) . '/autoload.php'; use ParagonIE_Sodium_Compat; const CRYPTO_AEAD_AES256GCM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_KEYBYTES; const CRYPTO_AEAD_AES256GCM_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NSECBYTES; const CRYPTO_AEAD_AES256GCM_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NPUBBYTES; const CRYPTO_AEAD_AES256GCM_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_ABYTES; const CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES; const CRYPTO_AUTH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_AUTH_BYTES; const CRYPTO_AUTH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AUTH_KEYBYTES; const CRYPTO_BOX_SEALBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SEALBYTES; const CRYPTO_BOX_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES; const CRYPTO_BOX_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES; const CRYPTO_BOX_KEYPAIRBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES; const CRYPTO_BOX_MACBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_MACBYTES; const CRYPTO_BOX_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES; const CRYPTO_BOX_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SEEDBYTES; const CRYPTO_KX_BYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_BYTES; const CRYPTO_KX_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_SEEDBYTES; const CRYPTO_KX_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_PUBLICKEYBYTES; const CRYPTO_KX_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_SECRETKEYBYTES; const CRYPTO_GENERICHASH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES; const CRYPTO_GENERICHASH_BYTES_MIN = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MIN; const CRYPTO_GENERICHASH_BYTES_MAX = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MAX; const CRYPTO_GENERICHASH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES; const CRYPTO_GENERICHASH_KEYBYTES_MIN = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MIN; const CRYPTO_GENERICHASH_KEYBYTES_MAX = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MAX; const CRYPTO_SCALARMULT_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_BYTES; const CRYPTO_SCALARMULT_SCALARBYTES = ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_SCALARBYTES; const CRYPTO_SHORTHASH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_BYTES; const CRYPTO_SHORTHASH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_KEYBYTES; const CRYPTO_SECRETBOX_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES; const CRYPTO_SECRETBOX_MACBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES; const CRYPTO_SECRETBOX_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES; const CRYPTO_SIGN_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_BYTES; const CRYPTO_SIGN_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_SEEDBYTES; const CRYPTO_SIGN_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_PUBLICKEYBYTES; const CRYPTO_SIGN_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_SECRETKEYBYTES; const CRYPTO_SIGN_KEYPAIRBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_KEYPAIRBYTES; const CRYPTO_STREAM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_STREAM_KEYBYTES; const CRYPTO_STREAM_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_STREAM_NONCEBYTES; ISC License Copyright (c) 2016-2023, Paragon Initiative Enterprises <security at paragonie dot com> Copyright (c) 2013-2019, Frank Denis <j at pureftpd dot org> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. <?php /** * Class ParagonIE_Sodium_Core_SecretStream_State */ class ParagonIE_Sodium_Core_SecretStream_State { /** @var string $key */ protected $key; /** @var int $counter */ protected $counter; /** @var string $nonce */ protected $nonce; /** @var string $_pad */ protected $_pad; /** * ParagonIE_Sodium_Core_SecretStream_State constructor. * @param string $key * @param string|null $nonce */ public function __construct($key, $nonce = null) { $this->key = $key; $this->counter = 1; if (is_null($nonce)) { $nonce = str_repeat("\0", 12); } $this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);; $this->_pad = str_repeat("\0", 4); } /** * @return self */ public function counterReset() { $this->counter = 1; $this->_pad = str_repeat("\0", 4); return $this; } /** * @return string */ public function getKey() { return $this->key; } /** * @return string */ public function getCounter() { return ParagonIE_Sodium_Core_Util::store32_le($this->counter); } /** * @return string */ public function getNonce() { if (!is_string($this->nonce)) { $this->nonce = str_repeat("\0", 12); } if (ParagonIE_Sodium_Core_Util::strlen($this->nonce) !== 12) { $this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT); } return $this->nonce; } /** * @return string */ public function getCombinedNonce() { return $this->getCounter() . ParagonIE_Sodium_Core_Util::substr($this->getNonce(), 0, 8); } /** * @return self */ public function incrementCounter() { ++$this->counter; return $this; } /** * @return bool */ public function needsRekey() { return ($this->counter & 0xffff) === 0; } /** * @param string $newKeyAndNonce * @return self */ public function rekey($newKeyAndNonce) { $this->key = ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 0, 32); $this->nonce = str_pad( ParagonIE_Sodium_Core_Util::substr($newKeyAndNonce, 32), 12, "\0", STR_PAD_RIGHT ); return $this; } /** * @param string $str * @return self */ public function xorNonce($str) { $this->nonce = ParagonIE_Sodium_Core_Util::xorStrings( $this->getNonce(), str_pad( ParagonIE_Sodium_Core_Util::substr($str, 0, 8), 12, "\0", STR_PAD_RIGHT ) ); return $this; } /** * @param string $string * @return self */ public static function fromString($string) { $state = new ParagonIE_Sodium_Core_SecretStream_State( ParagonIE_Sodium_Core_Util::substr($string, 0, 32) ); $state->counter = ParagonIE_Sodium_Core_Util::load_4( ParagonIE_Sodium_Core_Util::substr($string, 32, 4) ); $state->nonce = ParagonIE_Sodium_Core_Util::substr($string, 36, 12); $state->_pad = ParagonIE_Sodium_Core_Util::substr($string, 48, 8); return $state; } /** * @return string */ public function toString() { return $this->key . $this->getCounter() . $this->nonce . $this->_pad; } } <?php if (class_exists('ParagonIE_Sodium_Core_Ed25519', false)) { return; } if (!class_exists('ParagonIE_Sodium_Core_Curve25519', false)) { require_once dirname(__FILE__) . '/Curve25519.php'; } /** * Class ParagonIE_Sodium_Core_Ed25519 */ abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve25519 { const KEYPAIR_BYTES = 96; const SEED_BYTES = 32; const SCALAR_BYTES = 32; /** * @internal You should not use this directly from another application * * @return string (96 bytes) * @throws Exception * @throws SodiumException * @throws TypeError */ public static function keypair() { $seed = random_bytes(self::SEED_BYTES); $pk = ''; $sk = ''; self::seed_keypair($pk, $sk, $seed); return $sk . $pk; } /** * @internal You should not use this directly from another application * * @param string $pk * @param string $sk * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function seed_keypair(&$pk, &$sk, $seed) { if (self::strlen($seed) !== self::SEED_BYTES) { throw new RangeException('crypto_sign keypair seed must be 32 bytes long'); } /** @var string $pk */ $pk = self::publickey_from_secretkey($seed); $sk = $seed . $pk; return $sk; } /** * @internal You should not use this directly from another application * * @param string $keypair * @return string * @throws TypeError */ public static function secretkey($keypair) { if (self::strlen($keypair) !== self::KEYPAIR_BYTES) { throw new RangeException('crypto_sign keypair must be 96 bytes long'); } return self::substr($keypair, 0, 64); } /** * @internal You should not use this directly from another application * * @param string $keypair * @return string * @throws TypeError */ public static function publickey($keypair) { if (self::strlen($keypair) !== self::KEYPAIR_BYTES) { throw new RangeException('crypto_sign keypair must be 96 bytes long'); } return self::substr($keypair, 64, 32); } /** * @internal You should not use this directly from another application * * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function publickey_from_secretkey($sk) { /** @var string $sk */ $sk = hash('sha512', self::substr($sk, 0, 32), true); $sk[0] = self::intToChr( self::chrToInt($sk[0]) & 248 ); $sk[31] = self::intToChr( (self::chrToInt($sk[31]) & 63) | 64 ); return self::sk_to_pk($sk); } /** * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function pk_to_curve25519($pk) { if (self::small_order($pk)) { throw new SodiumException('Public key is on a small order'); } $A = self::ge_frombytes_negate_vartime(self::substr($pk, 0, 32)); $p1 = self::ge_mul_l($A); if (!self::fe_isnonzero($p1->X)) { throw new SodiumException('Unexpected zero result'); } # fe_1(one_minus_y); # fe_sub(one_minus_y, one_minus_y, A.Y); # fe_invert(one_minus_y, one_minus_y); $one_minux_y = self::fe_invert( self::fe_sub( self::fe_1(), $A->Y ) ); # fe_1(x); # fe_add(x, x, A.Y); # fe_mul(x, x, one_minus_y); $x = self::fe_mul( self::fe_add(self::fe_1(), $A->Y), $one_minux_y ); # fe_tobytes(curve25519_pk, x); return self::fe_tobytes($x); } /** * @internal You should not use this directly from another application * * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sk_to_pk($sk) { return self::ge_p3_tobytes( self::ge_scalarmult_base( self::substr($sk, 0, 32) ) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { /** @var string $signature */ $signature = self::sign_detached($message, $sk); return $signature . $message; } /** * @internal You should not use this directly from another application * * @param string $message A signed message * @param string $pk Public key * @return string Message (without signature) * @throws SodiumException * @throws TypeError */ public static function sign_open($message, $pk) { /** @var string $signature */ $signature = self::substr($message, 0, 64); /** @var string $message */ $message = self::substr($message, 64); if (self::verify_detached($signature, $message, $pk)) { return $message; } throw new SodiumException('Invalid signature'); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_detached($message, $sk) { # crypto_hash_sha512(az, sk, 32); $az = hash('sha512', self::substr($sk, 0, 32), true); # az[0] &= 248; # az[31] &= 63; # az[31] |= 64; $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); # crypto_hash_sha512_init(&hs); # crypto_hash_sha512_update(&hs, az + 32, 32); # crypto_hash_sha512_update(&hs, m, mlen); # crypto_hash_sha512_final(&hs, nonce); $hs = hash_init('sha512'); hash_update($hs, self::substr($az, 32, 32)); hash_update($hs, $message); $nonceHash = hash_final($hs, true); # memmove(sig + 32, sk + 32, 32); $pk = self::substr($sk, 32, 32); # sc_reduce(nonce); # ge_scalarmult_base(&R, nonce); # ge_p3_tobytes(sig, &R); $nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32); $sig = self::ge_p3_tobytes( self::ge_scalarmult_base($nonce) ); # crypto_hash_sha512_init(&hs); # crypto_hash_sha512_update(&hs, sig, 64); # crypto_hash_sha512_update(&hs, m, mlen); # crypto_hash_sha512_final(&hs, hram); $hs = hash_init('sha512'); hash_update($hs, self::substr($sig, 0, 32)); hash_update($hs, self::substr($pk, 0, 32)); hash_update($hs, $message); $hramHash = hash_final($hs, true); # sc_reduce(hram); # sc_muladd(sig + 32, hram, az, nonce); $hram = self::sc_reduce($hramHash); $sigAfter = self::sc_muladd($hram, $az, $nonce); $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32); try { ParagonIE_Sodium_Compat::memzero($az); } catch (SodiumException $ex) { $az = null; } return $sig; } /** * @internal You should not use this directly from another application * * @param string $sig * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function verify_detached($sig, $message, $pk) { if (self::strlen($sig) < 64) { throw new SodiumException('Signature is too short'); } if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) { throw new SodiumException('S < L - Invalid signature'); } if (self::small_order($sig)) { throw new SodiumException('Signature is on too small of an order'); } if ((self::chrToInt($sig[63]) & 224) !== 0) { throw new SodiumException('Invalid signature'); } $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= self::chrToInt($pk[$i]); } if ($d === 0) { throw new SodiumException('All zero public key'); } /** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */ $orig = ParagonIE_Sodium_Compat::$fastMult; // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification. ParagonIE_Sodium_Compat::$fastMult = true; /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */ $A = self::ge_frombytes_negate_vartime($pk); /** @var string $hDigest */ $hDigest = hash( 'sha512', self::substr($sig, 0, 32) . self::substr($pk, 0, 32) . $message, true ); /** @var string $h */ $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32); /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */ $R = self::ge_double_scalarmult_vartime( $h, $A, self::substr($sig, 32) ); /** @var string $rcheck */ $rcheck = self::ge_tobytes($R); // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before. ParagonIE_Sodium_Compat::$fastMult = $orig; return self::verify_32($rcheck, self::substr($sig, 0, 32)); } /** * @internal You should not use this directly from another application * * @param string $S * @return bool * @throws SodiumException * @throws TypeError */ public static function check_S_lt_L($S) { if (self::strlen($S) < 32) { throw new SodiumException('Signature must be 32 bytes'); } $L = array( 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ); $c = 0; $n = 1; $i = 32; /** @var array<int, int> $L */ do { --$i; $x = self::chrToInt($S[$i]); $c |= ( (($x - $L[$i]) >> 8) & $n ); $n &= ( (($x ^ $L[$i]) - 1) >> 8 ); } while ($i !== 0); return $c === 0; } /** * @param string $R * @return bool * @throws SodiumException * @throws TypeError */ public static function small_order($R) { /** @var array<int, array<int, int>> $blocklist */ $blocklist = array( /* 0 (order 4) */ array( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), /* 1 (order 1) */ array( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */ array( 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 ), /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */ array( 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a ), /* p-1 (order 2) */ array( 0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85 ), /* p (order 4) */ array( 0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa ), /* p+1 (order 1) */ array( 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */ array( 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */ array( 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* 2p-1 (order 2) */ array( 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), /* 2p (order 4) */ array( 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), /* 2p+1 (order 1) */ array( 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ) ); /** @var int $countBlocklist */ $countBlocklist = count($blocklist); for ($i = 0; $i < $countBlocklist; ++$i) { $c = 0; for ($j = 0; $j < 32; ++$j) { $c |= self::chrToInt($R[$j]) ^ (int) $blocklist[$i][$j]; } if ($c === 0) { return true; } } return false; } /** * @param string $s * @return string * @throws SodiumException */ public static function scalar_complement($s) { $t_ = self::L . str_repeat("\x00", 32); sodium_increment($t_); $s_ = $s . str_repeat("\x00", 32); ParagonIE_Sodium_Compat::sub($t_, $s_); return self::sc_reduce($t_); } /** * @return string * @throws SodiumException */ public static function scalar_random() { do { $r = ParagonIE_Sodium_Compat::randombytes_buf(self::SCALAR_BYTES); $r[self::SCALAR_BYTES - 1] = self::intToChr( self::chrToInt($r[self::SCALAR_BYTES - 1]) & 0x1f ); } while ( !self::check_S_lt_L($r) || ParagonIE_Sodium_Compat::is_zero($r) ); return $r; } /** * @param string $s * @return string * @throws SodiumException */ public static function scalar_negate($s) { $t_ = self::L . str_repeat("\x00", 32) ; $s_ = $s . str_repeat("\x00", 32) ; ParagonIE_Sodium_Compat::sub($t_, $s_); return self::sc_reduce($t_); } /** * @param string $a * @param string $b * @return string * @throws SodiumException */ public static function scalar_add($a, $b) { $a_ = $a . str_repeat("\x00", 32); $b_ = $b . str_repeat("\x00", 32); ParagonIE_Sodium_Compat::add($a_, $b_); return self::sc_reduce($a_); } /** * @param string $x * @param string $y * @return string * @throws SodiumException */ public static function scalar_sub($x, $y) { $yn = self::scalar_negate($y); return self::scalar_add($x, $yn); } } <?php if (class_exists('ParagonIE_Sodium_Core_XSalsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core_XSalsa20 */ abstract class ParagonIE_Sodium_Core_XSalsa20 extends ParagonIE_Sodium_Core_HSalsa20 { /** * Expand a key and nonce into an xsalsa20 keystream. * * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function xsalsa20($len, $nonce, $key) { $ret = self::salsa20( $len, self::substr($nonce, 16, 8), self::hsalsa20($nonce, $key) ); return $ret; } /** * Encrypt a string with XSalsa20. Doesn't provide integrity. * * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function xsalsa20_xor($message, $nonce, $key) { return self::xorStrings( $message, self::xsalsa20( self::strlen($message), $nonce, $key ) ); } } <?php if (class_exists('ParagonIE_Sodium_Core_XChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core_XChaCha20 */ class ParagonIE_Sodium_Core_XChaCha20 extends ParagonIE_Sodium_Core_HChaCha20 { /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function stream($len = 64, $nonce = '', $key = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_Ctx( self::hChaCha20( self::substr($nonce, 0, 16), $key ), self::substr($nonce, 16, 8) ), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStream($len = 64, $nonce = '', $key = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_IetfCtx( self::hChaCha20( self::substr($nonce, 0, 16), $key ), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8) ), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function streamXorIc($message, $nonce = '', $key = '', $ic = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_Ctx( self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8), $ic ), $message ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_IetfCtx( self::hChaCha20(self::substr($nonce, 0, 16), $key), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8), $ic ), $message ); } } <?php if (class_exists('ParagonIE_Sodium_Core_HChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core_HChaCha20 */ class ParagonIE_Sodium_Core_HChaCha20 extends ParagonIE_Sodium_Core_ChaCha20 { /** * @param string $in * @param string $key * @param string|null $c * @return string * @throws TypeError */ public static function hChaCha20($in = '', $key = '', $c = null) { $ctx = array(); if ($c === null) { $ctx[0] = 0x61707865; $ctx[1] = 0x3320646e; $ctx[2] = 0x79622d32; $ctx[3] = 0x6b206574; } else { $ctx[0] = self::load_4(self::substr($c, 0, 4)); $ctx[1] = self::load_4(self::substr($c, 4, 4)); $ctx[2] = self::load_4(self::substr($c, 8, 4)); $ctx[3] = self::load_4(self::substr($c, 12, 4)); } $ctx[4] = self::load_4(self::substr($key, 0, 4)); $ctx[5] = self::load_4(self::substr($key, 4, 4)); $ctx[6] = self::load_4(self::substr($key, 8, 4)); $ctx[7] = self::load_4(self::substr($key, 12, 4)); $ctx[8] = self::load_4(self::substr($key, 16, 4)); $ctx[9] = self::load_4(self::substr($key, 20, 4)); $ctx[10] = self::load_4(self::substr($key, 24, 4)); $ctx[11] = self::load_4(self::substr($key, 28, 4)); $ctx[12] = self::load_4(self::substr($in, 0, 4)); $ctx[13] = self::load_4(self::substr($in, 4, 4)); $ctx[14] = self::load_4(self::substr($in, 8, 4)); $ctx[15] = self::load_4(self::substr($in, 12, 4)); return self::hChaCha20Bytes($ctx); } /** * @param array $ctx * @return string * @throws TypeError */ protected static function hChaCha20Bytes(array $ctx) { $x0 = (int) $ctx[0]; $x1 = (int) $ctx[1]; $x2 = (int) $ctx[2]; $x3 = (int) $ctx[3]; $x4 = (int) $ctx[4]; $x5 = (int) $ctx[5]; $x6 = (int) $ctx[6]; $x7 = (int) $ctx[7]; $x8 = (int) $ctx[8]; $x9 = (int) $ctx[9]; $x10 = (int) $ctx[10]; $x11 = (int) $ctx[11]; $x12 = (int) $ctx[12]; $x13 = (int) $ctx[13]; $x14 = (int) $ctx[14]; $x15 = (int) $ctx[15]; for ($i = 0; $i < 10; ++$i) { # QUARTERROUND( x0, x4, x8, x12) list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12); # QUARTERROUND( x1, x5, x9, x13) list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13); # QUARTERROUND( x2, x6, x10, x14) list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14); # QUARTERROUND( x3, x7, x11, x15) list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15); # QUARTERROUND( x0, x5, x10, x15) list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15); # QUARTERROUND( x1, x6, x11, x12) list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12); # QUARTERROUND( x2, x7, x8, x13) list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13); # QUARTERROUND( x3, x4, x9, x14) list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14); } return self::store32_le((int) ($x0 & 0xffffffff)) . self::store32_le((int) ($x1 & 0xffffffff)) . self::store32_le((int) ($x2 & 0xffffffff)) . self::store32_le((int) ($x3 & 0xffffffff)) . self::store32_le((int) ($x12 & 0xffffffff)) . self::store32_le((int) ($x13 & 0xffffffff)) . self::store32_le((int) ($x14 & 0xffffffff)) . self::store32_le((int) ($x15 & 0xffffffff)); } } <?php /** * Class ParagonIE_Sodium_Core_Ristretto255 */ class ParagonIE_Sodium_Core_Ristretto255 extends ParagonIE_Sodium_Core_Ed25519 { const crypto_core_ristretto255_HASHBYTES = 64; const HASH_SC_L = 48; const CORE_H2C_SHA256 = 1; const CORE_H2C_SHA512 = 2; /** * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_cneg(ParagonIE_Sodium_Core_Curve25519_Fe $f, $b) { $negf = self::fe_neg($f); return self::fe_cmov($f, $negf, $b); } /** * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe * @throws SodiumException */ public static function fe_abs(ParagonIE_Sodium_Core_Curve25519_Fe $f) { return self::fe_cneg($f, self::fe_isnegative($f)); } /** * Returns 0 if this field element results in all NUL bytes. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return int * @throws SodiumException */ public static function fe_iszero(ParagonIE_Sodium_Core_Curve25519_Fe $f) { static $zero; if ($zero === null) { $zero = str_repeat("\x00", 32); } /** @var string $zero */ $str = self::fe_tobytes($f); $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= self::chrToInt($str[$i]); } return (($d - 1) >> 31) & 1; } /** * @param ParagonIE_Sodium_Core_Curve25519_Fe $u * @param ParagonIE_Sodium_Core_Curve25519_Fe $v * @return array{x: ParagonIE_Sodium_Core_Curve25519_Fe, nonsquare: int} * * @throws SodiumException */ public static function ristretto255_sqrt_ratio_m1( ParagonIE_Sodium_Core_Curve25519_Fe $u, ParagonIE_Sodium_Core_Curve25519_Fe $v ) { $sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1); $v3 = self::fe_mul( self::fe_sq($v), $v ); /* v3 = v^3 */ $x = self::fe_mul( self::fe_mul( self::fe_sq($v3), $u ), $v ); /* x = uv^7 */ $x = self::fe_mul( self::fe_mul( self::fe_pow22523($x), /* x = (uv^7)^((q-5)/8) */ $v3 ), $u ); /* x = uv^3(uv^7)^((q-5)/8) */ $vxx = self::fe_mul( self::fe_sq($x), $v ); /* vx^2 */ $m_root_check = self::fe_sub($vxx, $u); /* vx^2-u */ $p_root_check = self::fe_add($vxx, $u); /* vx^2+u */ $f_root_check = self::fe_mul($u, $sqrtm1); /* u*sqrt(-1) */ $f_root_check = self::fe_add($vxx, $f_root_check); /* vx^2+u*sqrt(-1) */ $has_m_root = self::fe_iszero($m_root_check); $has_p_root = self::fe_iszero($p_root_check); $has_f_root = self::fe_iszero($f_root_check); $x_sqrtm1 = self::fe_mul($x, $sqrtm1); /* x*sqrt(-1) */ $x = self::fe_abs( self::fe_cmov($x, $x_sqrtm1, $has_p_root | $has_f_root) ); return array( 'x' => $x, 'nonsquare' => $has_m_root | $has_p_root ); } /** * @param string $s * @return int * @throws SodiumException */ public static function ristretto255_point_is_canonical($s) { $c = (self::chrToInt($s[31]) & 0x7f) ^ 0x7f; for ($i = 30; $i > 0; --$i) { $c |= self::chrToInt($s[$i]) ^ 0xff; } $c = ($c - 1) >> 8; $d = (0xed - 1 - self::chrToInt($s[0])) >> 8; $e = self::chrToInt($s[31]) >> 7; return 1 - ((($c & $d) | $e | self::chrToInt($s[0])) & 1); } /** * @param string $s * @param bool $skipCanonicalCheck * @return array{h: ParagonIE_Sodium_Core_Curve25519_Ge_P3, res: int} * @throws SodiumException */ public static function ristretto255_frombytes($s, $skipCanonicalCheck = false) { if (!$skipCanonicalCheck) { if (!self::ristretto255_point_is_canonical($s)) { throw new SodiumException('S is not canonical'); } } $s_ = self::fe_frombytes($s); $ss = self::fe_sq($s_); /* ss = s^2 */ $u1 = self::fe_sub(self::fe_1(), $ss); /* u1 = 1-ss */ $u1u1 = self::fe_sq($u1); /* u1u1 = u1^2 */ $u2 = self::fe_add(self::fe_1(), $ss); /* u2 = 1+ss */ $u2u2 = self::fe_sq($u2); /* u2u2 = u2^2 */ $v = self::fe_mul( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d), $u1u1 ); /* v = d*u1^2 */ $v = self::fe_neg($v); /* v = -d*u1^2 */ $v = self::fe_sub($v, $u2u2); /* v = -(d*u1^2)-u2^2 */ $v_u2u2 = self::fe_mul($v, $u2u2); /* v_u2u2 = v*u2^2 */ // fe25519_1(one); // notsquare = ristretto255_sqrt_ratio_m1(inv_sqrt, one, v_u2u2); $one = self::fe_1(); $result = self::ristretto255_sqrt_ratio_m1($one, $v_u2u2); $inv_sqrt = $result['x']; $notsquare = $result['nonsquare']; $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(); $h->X = self::fe_mul($inv_sqrt, $u2); $h->Y = self::fe_mul(self::fe_mul($inv_sqrt, $h->X), $v); $h->X = self::fe_mul($h->X, $s_); $h->X = self::fe_abs( self::fe_add($h->X, $h->X) ); $h->Y = self::fe_mul($u1, $h->Y); $h->Z = self::fe_1(); $h->T = self::fe_mul($h->X, $h->Y); $res = - ((1 - $notsquare) | self::fe_isnegative($h->T) | self::fe_iszero($h->Y)); return array('h' => $h, 'res' => $res); } /** * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h * @return string * @throws SodiumException */ public static function ristretto255_p3_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h) { $sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1); $invsqrtamd = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$invsqrtamd); $u1 = self::fe_add($h->Z, $h->Y); /* u1 = Z+Y */ $zmy = self::fe_sub($h->Z, $h->Y); /* zmy = Z-Y */ $u1 = self::fe_mul($u1, $zmy); /* u1 = (Z+Y)*(Z-Y) */ $u2 = self::fe_mul($h->X, $h->Y); /* u2 = X*Y */ $u1_u2u2 = self::fe_mul(self::fe_sq($u2), $u1); /* u1_u2u2 = u1*u2^2 */ $one = self::fe_1(); // fe25519_1(one); // (void) ristretto255_sqrt_ratio_m1(inv_sqrt, one, u1_u2u2); $result = self::ristretto255_sqrt_ratio_m1($one, $u1_u2u2); $inv_sqrt = $result['x']; $den1 = self::fe_mul($inv_sqrt, $u1); /* den1 = inv_sqrt*u1 */ $den2 = self::fe_mul($inv_sqrt, $u2); /* den2 = inv_sqrt*u2 */ $z_inv = self::fe_mul($h->T, self::fe_mul($den1, $den2)); /* z_inv = den1*den2*T */ $ix = self::fe_mul($h->X, $sqrtm1); /* ix = X*sqrt(-1) */ $iy = self::fe_mul($h->Y, $sqrtm1); /* iy = Y*sqrt(-1) */ $eden = self::fe_mul($den1, $invsqrtamd); $t_z_inv = self::fe_mul($h->T, $z_inv); /* t_z_inv = T*z_inv */ $rotate = self::fe_isnegative($t_z_inv); $x_ = self::fe_copy($h->X); $y_ = self::fe_copy($h->Y); $den_inv = self::fe_copy($den2); $x_ = self::fe_cmov($x_, $iy, $rotate); $y_ = self::fe_cmov($y_, $ix, $rotate); $den_inv = self::fe_cmov($den_inv, $eden, $rotate); $x_z_inv = self::fe_mul($x_, $z_inv); $y_ = self::fe_cneg($y_, self::fe_isnegative($x_z_inv)); // fe25519_sub(s_, h->Z, y_); // fe25519_mul(s_, den_inv, s_); // fe25519_abs(s_, s_); // fe25519_tobytes(s, s_); return self::fe_tobytes( self::fe_abs( self::fe_mul( $den_inv, self::fe_sub($h->Z, $y_) ) ) ); } /** * @param ParagonIE_Sodium_Core_Curve25519_Fe $t * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * * @throws SodiumException */ public static function ristretto255_elligator(ParagonIE_Sodium_Core_Curve25519_Fe $t) { $sqrtm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1); $onemsqd = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$onemsqd); $d = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d); $sqdmone = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqdmone); $sqrtadm1 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtadm1); $one = self::fe_1(); $r = self::fe_mul($sqrtm1, self::fe_sq($t)); /* r = sqrt(-1)*t^2 */ $u = self::fe_mul(self::fe_add($r, $one), $onemsqd); /* u = (r+1)*(1-d^2) */ $c = self::fe_neg(self::fe_1()); /* c = -1 */ $rpd = self::fe_add($r, $d); /* rpd = r+d */ $v = self::fe_mul( self::fe_sub( $c, self::fe_mul($r, $d) ), $rpd ); /* v = (c-r*d)*(r+d) */ $result = self::ristretto255_sqrt_ratio_m1($u, $v); $s = $result['x']; $wasnt_square = 1 - $result['nonsquare']; $s_prime = self::fe_neg( self::fe_abs( self::fe_mul($s, $t) ) ); /* s_prime = -|s*t| */ $s = self::fe_cmov($s, $s_prime, $wasnt_square); $c = self::fe_cmov($c, $r, $wasnt_square); // fe25519_sub(n, r, one); /* n = r-1 */ // fe25519_mul(n, n, c); /* n = c*(r-1) */ // fe25519_mul(n, n, ed25519_sqdmone); /* n = c*(r-1)*(d-1)^2 */ // fe25519_sub(n, n, v); /* n = c*(r-1)*(d-1)^2-v */ $n = self::fe_sub( self::fe_mul( self::fe_mul( self::fe_sub($r, $one), $c ), $sqdmone ), $v ); /* n = c*(r-1)*(d-1)^2-v */ $w0 = self::fe_mul( self::fe_add($s, $s), $v ); /* w0 = 2s*v */ $w1 = self::fe_mul($n, $sqrtadm1); /* w1 = n*sqrt(ad-1) */ $ss = self::fe_sq($s); /* ss = s^2 */ $w2 = self::fe_sub($one, $ss); /* w2 = 1-s^2 */ $w3 = self::fe_add($one, $ss); /* w3 = 1+s^2 */ return new ParagonIE_Sodium_Core_Curve25519_Ge_P3( self::fe_mul($w0, $w3), self::fe_mul($w2, $w1), self::fe_mul($w1, $w3), self::fe_mul($w0, $w2) ); } /** * @param string $h * @return string * @throws SodiumException */ public static function ristretto255_from_hash($h) { if (self::strlen($h) !== 64) { throw new SodiumException('Hash must be 64 bytes'); } //fe25519_frombytes(r0, h); //fe25519_frombytes(r1, h + 32); $r0 = self::fe_frombytes(self::substr($h, 0, 32)); $r1 = self::fe_frombytes(self::substr($h, 32, 32)); //ristretto255_elligator(&p0, r0); //ristretto255_elligator(&p1, r1); $p0 = self::ristretto255_elligator($r0); $p1 = self::ristretto255_elligator($r1); //ge25519_p3_to_cached(&p1_cached, &p1); //ge25519_add_cached(&p_p1p1, &p0, &p1_cached); $p_p1p1 = self::ge_add( $p0, self::ge_p3_to_cached($p1) ); //ge25519_p1p1_to_p3(&p, &p_p1p1); //ristretto255_p3_tobytes(s, &p); return self::ristretto255_p3_tobytes( self::ge_p1p1_to_p3($p_p1p1) ); } /** * @param string $p * @return int * @throws SodiumException */ public static function is_valid_point($p) { $result = self::ristretto255_frombytes($p); if ($result['res'] !== 0) { return 0; } return 1; } /** * @param string $p * @param string $q * @return string * @throws SodiumException */ public static function ristretto255_add($p, $q) { $p_res = self::ristretto255_frombytes($p); $q_res = self::ristretto255_frombytes($q); if ($p_res['res'] !== 0 || $q_res['res'] !== 0) { throw new SodiumException('Could not add points'); } $p_p3 = $p_res['h']; $q_p3 = $q_res['h']; $q_cached = self::ge_p3_to_cached($q_p3); $r_p1p1 = self::ge_add($p_p3, $q_cached); $r_p3 = self::ge_p1p1_to_p3($r_p1p1); return self::ristretto255_p3_tobytes($r_p3); } /** * @param string $p * @param string $q * @return string * @throws SodiumException */ public static function ristretto255_sub($p, $q) { $p_res = self::ristretto255_frombytes($p); $q_res = self::ristretto255_frombytes($q); if ($p_res['res'] !== 0 || $q_res['res'] !== 0) { throw new SodiumException('Could not add points'); } $p_p3 = $p_res['h']; $q_p3 = $q_res['h']; $q_cached = self::ge_p3_to_cached($q_p3); $r_p1p1 = self::ge_sub($p_p3, $q_cached); $r_p3 = self::ge_p1p1_to_p3($r_p1p1); return self::ristretto255_p3_tobytes($r_p3); } /** * @param int $hLen * @param ?string $ctx * @param string $msg * @return string * @throws SodiumException * @psalm-suppress PossiblyInvalidArgument hash API */ protected static function h2c_string_to_hash_sha256($hLen, $ctx, $msg) { $h = array_fill(0, $hLen, 0); $ctx_len = !is_null($ctx) ? self::strlen($ctx) : 0; if ($hLen > 0xff) { throw new SodiumException('Hash must be less than 256 bytes'); } if ($ctx_len > 0xff) { $st = hash_init('sha256'); self::hash_update($st, "H2C-OVERSIZE-DST-"); self::hash_update($st, $ctx); $ctx = hash_final($st, true); $ctx_len = 32; } $t = array(0, $hLen, 0); $ux = str_repeat("\0", 64); $st = hash_init('sha256'); self::hash_update($st, $ux); self::hash_update($st, $msg); self::hash_update($st, self::intArrayToString($t)); self::hash_update($st, $ctx); self::hash_update($st, self::intToChr($ctx_len)); $u0 = hash_final($st, true); for ($i = 0; $i < $hLen; $i += 64) { $ux = self::xorStrings($ux, $u0); ++$t[2]; $st = hash_init('sha256'); self::hash_update($st, $ux); self::hash_update($st, self::intToChr($t[2])); self::hash_update($st, $ctx); self::hash_update($st, self::intToChr($ctx_len)); $ux = hash_final($st, true); $amount = min($hLen - $i, 64); for ($j = 0; $j < $amount; ++$j) { $h[$i + $j] = self::chrToInt($ux[$i]); } } return self::intArrayToString(array_slice($h, 0, $hLen)); } /** * @param int $hLen * @param ?string $ctx * @param string $msg * @return string * @throws SodiumException * @psalm-suppress PossiblyInvalidArgument hash API */ protected static function h2c_string_to_hash_sha512($hLen, $ctx, $msg) { $h = array_fill(0, $hLen, 0); $ctx_len = !is_null($ctx) ? self::strlen($ctx) : 0; if ($hLen > 0xff) { throw new SodiumException('Hash must be less than 256 bytes'); } if ($ctx_len > 0xff) { $st = hash_init('sha256'); self::hash_update($st, "H2C-OVERSIZE-DST-"); self::hash_update($st, $ctx); $ctx = hash_final($st, true); $ctx_len = 32; } $t = array(0, $hLen, 0); $ux = str_repeat("\0", 128); $st = hash_init('sha512'); self::hash_update($st, $ux); self::hash_update($st, $msg); self::hash_update($st, self::intArrayToString($t)); self::hash_update($st, $ctx); self::hash_update($st, self::intToChr($ctx_len)); $u0 = hash_final($st, true); for ($i = 0; $i < $hLen; $i += 128) { $ux = self::xorStrings($ux, $u0); ++$t[2]; $st = hash_init('sha512'); self::hash_update($st, $ux); self::hash_update($st, self::intToChr($t[2])); self::hash_update($st, $ctx); self::hash_update($st, self::intToChr($ctx_len)); $ux = hash_final($st, true); $amount = min($hLen - $i, 128); for ($j = 0; $j < $amount; ++$j) { $h[$i + $j] = self::chrToInt($ux[$i]); } } return self::intArrayToString(array_slice($h, 0, $hLen)); } /** * @param int $hLen * @param ?string $ctx * @param string $msg * @param int $hash_alg * @return string * @throws SodiumException */ public static function h2c_string_to_hash($hLen, $ctx, $msg, $hash_alg) { switch ($hash_alg) { case self::CORE_H2C_SHA256: return self::h2c_string_to_hash_sha256($hLen, $ctx, $msg); case self::CORE_H2C_SHA512: return self::h2c_string_to_hash_sha512($hLen, $ctx, $msg); default: throw new SodiumException('Invalid H2C hash algorithm'); } } /** * @param ?string $ctx * @param string $msg * @param int $hash_alg * @return string * @throws SodiumException */ protected static function _string_to_element($ctx, $msg, $hash_alg) { return self::ristretto255_from_hash( self::h2c_string_to_hash(self::crypto_core_ristretto255_HASHBYTES, $ctx, $msg, $hash_alg) ); } /** * @return string * @throws SodiumException * @throws Exception */ public static function ristretto255_random() { return self::ristretto255_from_hash( ParagonIE_Sodium_Compat::randombytes_buf(self::crypto_core_ristretto255_HASHBYTES) ); } /** * @return string * @throws SodiumException */ public static function ristretto255_scalar_random() { return self::scalar_random(); } /** * @param string $s * @return string * @throws SodiumException */ public static function ristretto255_scalar_complement($s) { return self::scalar_complement($s); } /** * @param string $s * @return string */ public static function ristretto255_scalar_invert($s) { return self::sc25519_invert($s); } /** * @param string $s * @return string * @throws SodiumException */ public static function ristretto255_scalar_negate($s) { return self::scalar_negate($s); } /** * @param string $x * @param string $y * @return string */ public static function ristretto255_scalar_add($x, $y) { return self::scalar_add($x, $y); } /** * @param string $x * @param string $y * @return string */ public static function ristretto255_scalar_sub($x, $y) { return self::scalar_sub($x, $y); } /** * @param string $x * @param string $y * @return string */ public static function ristretto255_scalar_mul($x, $y) { return self::sc25519_mul($x, $y); } /** * @param string $ctx * @param string $msg * @param int $hash_alg * @return string * @throws SodiumException */ public static function ristretto255_scalar_from_string($ctx, $msg, $hash_alg) { $h = array_fill(0, 64, 0); $h_be = self::stringToIntArray( self::h2c_string_to_hash( self::HASH_SC_L, $ctx, $msg, $hash_alg ) ); for ($i = 0; $i < self::HASH_SC_L; ++$i) { $h[$i] = $h_be[self::HASH_SC_L - 1 - $i]; } return self::ristretto255_scalar_reduce(self::intArrayToString($h)); } /** * @param string $s * @return string */ public static function ristretto255_scalar_reduce($s) { return self::sc_reduce($s); } /** * @param string $n * @param string $p * @return string * @throws SodiumException */ public static function scalarmult_ristretto255($n, $p) { if (self::strlen($n) !== 32) { throw new SodiumException('Scalar must be 32 bytes, ' . self::strlen($p) . ' given.'); } if (self::strlen($p) !== 32) { throw new SodiumException('Point must be 32 bytes, ' . self::strlen($p) . ' given.'); } $result = self::ristretto255_frombytes($p); if ($result['res'] !== 0) { throw new SodiumException('Could not multiply points'); } $P = $result['h']; $t = self::stringToIntArray($n); $t[31] &= 0x7f; $Q = self::ge_scalarmult(self::intArrayToString($t), $P); $q = self::ristretto255_p3_tobytes($Q); if (ParagonIE_Sodium_Compat::is_zero($q)) { throw new SodiumException('An unknown error has occurred'); } return $q; } /** * @param string $n * @return string * @throws SodiumException */ public static function scalarmult_ristretto255_base($n) { $t = self::stringToIntArray($n); $t[31] &= 0x7f; $Q = self::ge_scalarmult_base(self::intArrayToString($t)); $q = self::ristretto255_p3_tobytes($Q); if (ParagonIE_Sodium_Compat::is_zero($q)) { throw new SodiumException('An unknown error has occurred'); } return $q; } } <?php if (!defined('SODIUM_COMPAT_AEGIS_C0')) { define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62"); } if (!defined('SODIUM_COMPAT_AEGIS_C1')) { define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd"); } class ParagonIE_Sodium_Core_AEGIS256 extends ParagonIE_Sodium_Core_AES { /** * @param string $ct * @param string $tag * @param string $ad * @param string $key * @param string $nonce * @return string * @throws SodiumException */ public static function decrypt($ct, $tag, $ad, $key, $nonce) { $state = self::init($key, $nonce); // ad_blocks = Split(ZeroPad(ad, 128), 128) $ad_blocks = (self::strlen($ad) + 15) >> 4; // for ai in ad_blocks: // Absorb(ai) for ($i = 0; $i < $ad_blocks; ++$i) { $ai = self::substr($ad, $i << 4, 16); if (self::strlen($ai) < 16) { $ai = str_pad($ai, 16, "\0", STR_PAD_RIGHT); } $state->absorb($ai); } $msg = ''; $cn = self::strlen($ct) & 15; $ct_blocks = self::strlen($ct) >> 4; // ct_blocks = Split(ZeroPad(ct, 128), 128) // cn = Tail(ct, |ct| mod 128) for ($i = 0; $i < $ct_blocks; ++$i) { $msg .= $state->dec(self::substr($ct, $i << 4, 16)); } // if cn is not empty: // msg = msg || DecPartial(cn) if ($cn) { $start = $ct_blocks << 4; $msg .= $state->decPartial(self::substr($ct, $start, $cn)); } $expected_tag = $state->finalize( self::strlen($ad) << 3, self::strlen($msg) << 3 ); if (!self::hashEquals($expected_tag, $tag)) { try { // The RFC says to erase msg, so we shall try: ParagonIE_Sodium_Compat::memzero($msg); } catch (SodiumException $ex) { // Do nothing if we cannot memzero } throw new SodiumException('verification failed'); } return $msg; } /** * @param string $msg * @param string $ad * @param string $key * @param string $nonce * @return array * @throws SodiumException */ public static function encrypt($msg, $ad, $key, $nonce) { $state = self::init($key, $nonce); $ad_len = self::strlen($ad); $msg_len = self::strlen($msg); $ad_blocks = ($ad_len + 15) >> 4; for ($i = 0; $i < $ad_blocks; ++$i) { $ai = self::substr($ad, $i << 4, 16); if (self::strlen($ai) < 16) { $ai = str_pad($ai, 16, "\0", STR_PAD_RIGHT); } $state->absorb($ai); } $ct = ''; $msg_blocks = ($msg_len + 15) >> 4; for ($i = 0; $i < $msg_blocks; ++$i) { $xi = self::substr($msg, $i << 4, 16); if (self::strlen($xi) < 16) { $xi = str_pad($xi, 16, "\0", STR_PAD_RIGHT); } $ct .= $state->enc($xi); } $tag = $state->finalize( $ad_len << 3, $msg_len << 3 ); return array( self::substr($ct, 0, $msg_len), $tag ); } /** * @param string $key * @param string $nonce * @return ParagonIE_Sodium_Core_AEGIS_State256 */ public static function init($key, $nonce) { return ParagonIE_Sodium_Core_AEGIS_State256::init($key, $nonce); } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519 * * Implements Curve25519 core functions * * Based on the ref10 curve25519 code provided by libsodium * * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c */ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Curve25519_H { /** * Get a field element of size 10 with a value of 0 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_0() { return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); } /** * Get a field element of size 10 with a value of 1 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_1() { return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); } /** * Add two field elements. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function fe_add( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g ) { /** @var array<int, int> $arr */ $arr = array(); for ($i = 0; $i < 10; ++$i) { $arr[$i] = (int) ($f[$i] + $g[$i]); } return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($arr); } /** * Constant-time conditional move. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment */ public static function fe_cmov( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g, $b = 0 ) { /** @var array<int, int> $h */ $h = array(); $b *= -1; for ($i = 0; $i < 10; ++$i) { $x = (($f[$i] ^ $g[$i]) & $b); $h[$i] = ($f[$i]) ^ $x; } return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h); } /** * Create a copy of a field element. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_copy(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $h = clone $f; return $h; } /** * Give: 32-byte string. * Receive: A field element object to use for internal calculations. * * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core_Curve25519_Fe * @throws RangeException * @throws TypeError */ public static function fe_frombytes($s) { if (self::strlen($s) !== 32) { throw new RangeException('Expected a 32-byte string.'); } $h0 = self::load_4($s); $h1 = self::load_3(self::substr($s, 4, 3)) << 6; $h2 = self::load_3(self::substr($s, 7, 3)) << 5; $h3 = self::load_3(self::substr($s, 10, 3)) << 3; $h4 = self::load_3(self::substr($s, 13, 3)) << 2; $h5 = self::load_4(self::substr($s, 16, 4)); $h6 = self::load_3(self::substr($s, 20, 3)) << 7; $h7 = self::load_3(self::substr($s, 23, 3)) << 5; $h8 = self::load_3(self::substr($s, 26, 3)) << 4; $h9 = (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ); } /** * Convert a field element to a byte string. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $h * @return string */ public static function fe_tobytes(ParagonIE_Sodium_Core_Curve25519_Fe $h) { $h0 = (int) $h[0]; $h1 = (int) $h[1]; $h2 = (int) $h[2]; $h3 = (int) $h[3]; $h4 = (int) $h[4]; $h5 = (int) $h[5]; $h6 = (int) $h[6]; $h7 = (int) $h[7]; $h8 = (int) $h[8]; $h9 = (int) $h[9]; $q = (self::mul($h9, 19, 5) + (1 << 24)) >> 25; $q = ($h0 + $q) >> 26; $q = ($h1 + $q) >> 25; $q = ($h2 + $q) >> 26; $q = ($h3 + $q) >> 25; $q = ($h4 + $q) >> 26; $q = ($h5 + $q) >> 25; $q = ($h6 + $q) >> 26; $q = ($h7 + $q) >> 25; $q = ($h8 + $q) >> 26; $q = ($h9 + $q) >> 25; $h0 += self::mul($q, 19, 5); $carry0 = $h0 >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry1 = $h1 >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry2 = $h2 >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry3 = $h3 >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry4 = $h4 >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry5 = $h5 >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry6 = $h6 >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry7 = $h7 >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry8 = $h8 >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = $h9 >> 25; $h9 -= $carry9 << 25; /** * @var array<int, int> */ $s = array( (int) (($h0 >> 0) & 0xff), (int) (($h0 >> 8) & 0xff), (int) (($h0 >> 16) & 0xff), (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff), (int) (($h1 >> 6) & 0xff), (int) (($h1 >> 14) & 0xff), (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff), (int) (($h2 >> 5) & 0xff), (int) (($h2 >> 13) & 0xff), (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff), (int) (($h3 >> 3) & 0xff), (int) (($h3 >> 11) & 0xff), (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff), (int) (($h4 >> 2) & 0xff), (int) (($h4 >> 10) & 0xff), (int) (($h4 >> 18) & 0xff), (int) (($h5 >> 0) & 0xff), (int) (($h5 >> 8) & 0xff), (int) (($h5 >> 16) & 0xff), (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff), (int) (($h6 >> 7) & 0xff), (int) (($h6 >> 15) & 0xff), (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff), (int) (($h7 >> 5) & 0xff), (int) (($h7 >> 13) & 0xff), (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff), (int) (($h8 >> 4) & 0xff), (int) (($h8 >> 12) & 0xff), (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff), (int) (($h9 >> 2) & 0xff), (int) (($h9 >> 10) & 0xff), (int) (($h9 >> 18) & 0xff) ); return self::intArrayToString($s); } /** * Is a field element negative? (1 = yes, 0 = no. Used in calculations.) * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return int * @throws SodiumException * @throws TypeError */ public static function fe_isnegative(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $str = self::fe_tobytes($f); return (int) (self::chrToInt($str[0]) & 1); } /** * Returns 0 if this field element results in all NUL bytes. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return bool * @throws SodiumException * @throws TypeError */ public static function fe_isnonzero(ParagonIE_Sodium_Core_Curve25519_Fe $f) { static $zero; if ($zero === null) { $zero = str_repeat("\x00", 32); } /** @var string $zero */ /** @var string $str */ $str = self::fe_tobytes($f); return !self::verify_32($str, (string) $zero); } /** * Multiply two field elements * * h = f * g * * @internal You should not use this directly from another application * * @security Is multiplication a source of timing leaks? If so, can we do * anything to prevent that from happening? * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_mul( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g ) { // Ensure limbs aren't oversized. $f = self::fe_normalize($f); $g = self::fe_normalize($g); $f0 = $f[0]; $f1 = $f[1]; $f2 = $f[2]; $f3 = $f[3]; $f4 = $f[4]; $f5 = $f[5]; $f6 = $f[6]; $f7 = $f[7]; $f8 = $f[8]; $f9 = $f[9]; $g0 = $g[0]; $g1 = $g[1]; $g2 = $g[2]; $g3 = $g[3]; $g4 = $g[4]; $g5 = $g[5]; $g6 = $g[6]; $g7 = $g[7]; $g8 = $g[8]; $g9 = $g[9]; $g1_19 = self::mul($g1, 19, 5); $g2_19 = self::mul($g2, 19, 5); $g3_19 = self::mul($g3, 19, 5); $g4_19 = self::mul($g4, 19, 5); $g5_19 = self::mul($g5, 19, 5); $g6_19 = self::mul($g6, 19, 5); $g7_19 = self::mul($g7, 19, 5); $g8_19 = self::mul($g8, 19, 5); $g9_19 = self::mul($g9, 19, 5); $f1_2 = $f1 << 1; $f3_2 = $f3 << 1; $f5_2 = $f5 << 1; $f7_2 = $f7 << 1; $f9_2 = $f9 << 1; $f0g0 = self::mul($f0, $g0, 26); $f0g1 = self::mul($f0, $g1, 25); $f0g2 = self::mul($f0, $g2, 26); $f0g3 = self::mul($f0, $g3, 25); $f0g4 = self::mul($f0, $g4, 26); $f0g5 = self::mul($f0, $g5, 25); $f0g6 = self::mul($f0, $g6, 26); $f0g7 = self::mul($f0, $g7, 25); $f0g8 = self::mul($f0, $g8, 26); $f0g9 = self::mul($f0, $g9, 26); $f1g0 = self::mul($f1, $g0, 26); $f1g1_2 = self::mul($f1_2, $g1, 25); $f1g2 = self::mul($f1, $g2, 26); $f1g3_2 = self::mul($f1_2, $g3, 25); $f1g4 = self::mul($f1, $g4, 26); $f1g5_2 = self::mul($f1_2, $g5, 25); $f1g6 = self::mul($f1, $g6, 26); $f1g7_2 = self::mul($f1_2, $g7, 25); $f1g8 = self::mul($f1, $g8, 26); $f1g9_38 = self::mul($g9_19, $f1_2, 26); $f2g0 = self::mul($f2, $g0, 26); $f2g1 = self::mul($f2, $g1, 25); $f2g2 = self::mul($f2, $g2, 26); $f2g3 = self::mul($f2, $g3, 25); $f2g4 = self::mul($f2, $g4, 26); $f2g5 = self::mul($f2, $g5, 25); $f2g6 = self::mul($f2, $g6, 26); $f2g7 = self::mul($f2, $g7, 25); $f2g8_19 = self::mul($g8_19, $f2, 26); $f2g9_19 = self::mul($g9_19, $f2, 26); $f3g0 = self::mul($f3, $g0, 26); $f3g1_2 = self::mul($f3_2, $g1, 25); $f3g2 = self::mul($f3, $g2, 26); $f3g3_2 = self::mul($f3_2, $g3, 25); $f3g4 = self::mul($f3, $g4, 26); $f3g5_2 = self::mul($f3_2, $g5, 25); $f3g6 = self::mul($f3, $g6, 26); $f3g7_38 = self::mul($g7_19, $f3_2, 26); $f3g8_19 = self::mul($g8_19, $f3, 25); $f3g9_38 = self::mul($g9_19, $f3_2, 26); $f4g0 = self::mul($f4, $g0, 26); $f4g1 = self::mul($f4, $g1, 25); $f4g2 = self::mul($f4, $g2, 26); $f4g3 = self::mul($f4, $g3, 25); $f4g4 = self::mul($f4, $g4, 26); $f4g5 = self::mul($f4, $g5, 25); $f4g6_19 = self::mul($g6_19, $f4, 26); $f4g7_19 = self::mul($g7_19, $f4, 26); $f4g8_19 = self::mul($g8_19, $f4, 26); $f4g9_19 = self::mul($g9_19, $f4, 26); $f5g0 = self::mul($f5, $g0, 26); $f5g1_2 = self::mul($f5_2, $g1, 25); $f5g2 = self::mul($f5, $g2, 26); $f5g3_2 = self::mul($f5_2, $g3, 25); $f5g4 = self::mul($f5, $g4, 26); $f5g5_38 = self::mul($g5_19, $f5_2, 26); $f5g6_19 = self::mul($g6_19, $f5, 25); $f5g7_38 = self::mul($g7_19, $f5_2, 26); $f5g8_19 = self::mul($g8_19, $f5, 25); $f5g9_38 = self::mul($g9_19, $f5_2, 26); $f6g0 = self::mul($f6, $g0, 26); $f6g1 = self::mul($f6, $g1, 25); $f6g2 = self::mul($f6, $g2, 26); $f6g3 = self::mul($f6, $g3, 25); $f6g4_19 = self::mul($g4_19, $f6, 26); $f6g5_19 = self::mul($g5_19, $f6, 26); $f6g6_19 = self::mul($g6_19, $f6, 26); $f6g7_19 = self::mul($g7_19, $f6, 26); $f6g8_19 = self::mul($g8_19, $f6, 26); $f6g9_19 = self::mul($g9_19, $f6, 26); $f7g0 = self::mul($f7, $g0, 26); $f7g1_2 = self::mul($f7_2, $g1, 25); $f7g2 = self::mul($f7, $g2, 26); $f7g3_38 = self::mul($g3_19, $f7_2, 26); $f7g4_19 = self::mul($g4_19, $f7, 26); $f7g5_38 = self::mul($g5_19, $f7_2, 26); $f7g6_19 = self::mul($g6_19, $f7, 25); $f7g7_38 = self::mul($g7_19, $f7_2, 26); $f7g8_19 = self::mul($g8_19, $f7, 25); $f7g9_38 = self::mul($g9_19,$f7_2, 26); $f8g0 = self::mul($f8, $g0, 26); $f8g1 = self::mul($f8, $g1, 25); $f8g2_19 = self::mul($g2_19, $f8, 26); $f8g3_19 = self::mul($g3_19, $f8, 26); $f8g4_19 = self::mul($g4_19, $f8, 26); $f8g5_19 = self::mul($g5_19, $f8, 26); $f8g6_19 = self::mul($g6_19, $f8, 26); $f8g7_19 = self::mul($g7_19, $f8, 26); $f8g8_19 = self::mul($g8_19, $f8, 26); $f8g9_19 = self::mul($g9_19, $f8, 26); $f9g0 = self::mul($f9, $g0, 26); $f9g1_38 = self::mul($g1_19, $f9_2, 26); $f9g2_19 = self::mul($g2_19, $f9, 25); $f9g3_38 = self::mul($g3_19, $f9_2, 26); $f9g4_19 = self::mul($g4_19, $f9, 25); $f9g5_38 = self::mul($g5_19, $f9_2, 26); $f9g6_19 = self::mul($g6_19, $f9, 25); $f9g7_38 = self::mul($g7_19, $f9_2, 26); $f9g8_19 = self::mul($g8_19, $f9, 25); $f9g9_38 = self::mul($g9_19, $f9_2, 26); $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38; $h1 = $f0g1 + $f1g0 + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19; $h2 = $f0g2 + $f1g1_2 + $f2g0 + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38; $h3 = $f0g3 + $f1g2 + $f2g1 + $f3g0 + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19; $h4 = $f0g4 + $f1g3_2 + $f2g2 + $f3g1_2 + $f4g0 + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38; $h5 = $f0g5 + $f1g4 + $f2g3 + $f3g2 + $f4g1 + $f5g0 + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19; $h6 = $f0g6 + $f1g5_2 + $f2g4 + $f3g3_2 + $f4g2 + $f5g1_2 + $f6g0 + $f7g9_38 + $f8g8_19 + $f9g7_38; $h7 = $f0g7 + $f1g6 + $f2g5 + $f3g4 + $f4g3 + $f5g2 + $f6g1 + $f7g0 + $f8g9_19 + $f9g8_19; $h8 = $f0g8 + $f1g7_2 + $f2g6 + $f3g5_2 + $f4g4 + $f5g3_2 + $f6g2 + $f7g1_2 + $f8g0 + $f9g9_38; $h9 = $f0g9 + $f1g8 + $f2g7 + $f3g6 + $f4g5 + $f5g4 + $f6g3 + $f7g2 + $f8g1 + $f9g0 ; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * Get the negative values for each piece of the field element. * * h = -f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment */ public static function fe_neg(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $h = new ParagonIE_Sodium_Core_Curve25519_Fe(); for ($i = 0; $i < 10; ++$i) { $h[$i] = -$f[$i]; } return self::fe_normalize($h); } /** * Square a field element * * h = f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_sq(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $f = self::fe_normalize($f); $f0 = (int) $f[0]; $f1 = (int) $f[1]; $f2 = (int) $f[2]; $f3 = (int) $f[3]; $f4 = (int) $f[4]; $f5 = (int) $f[5]; $f6 = (int) $f[6]; $f7 = (int) $f[7]; $f8 = (int) $f[8]; $f9 = (int) $f[9]; $f0_2 = $f0 << 1; $f1_2 = $f1 << 1; $f2_2 = $f2 << 1; $f3_2 = $f3 << 1; $f4_2 = $f4 << 1; $f5_2 = $f5 << 1; $f6_2 = $f6 << 1; $f7_2 = $f7 << 1; $f5_38 = self::mul($f5, 38, 6); $f6_19 = self::mul($f6, 19, 5); $f7_38 = self::mul($f7, 38, 6); $f8_19 = self::mul($f8, 19, 5); $f9_38 = self::mul($f9, 38, 6); $f0f0 = self::mul($f0, $f0, 26); $f0f1_2 = self::mul($f0_2, $f1, 26); $f0f2_2 = self::mul($f0_2, $f2, 26); $f0f3_2 = self::mul($f0_2, $f3, 26); $f0f4_2 = self::mul($f0_2, $f4, 26); $f0f5_2 = self::mul($f0_2, $f5, 26); $f0f6_2 = self::mul($f0_2, $f6, 26); $f0f7_2 = self::mul($f0_2, $f7, 26); $f0f8_2 = self::mul($f0_2, $f8, 26); $f0f9_2 = self::mul($f0_2, $f9, 26); $f1f1_2 = self::mul($f1_2, $f1, 26); $f1f2_2 = self::mul($f1_2, $f2, 26); $f1f3_4 = self::mul($f1_2, $f3_2, 26); $f1f4_2 = self::mul($f1_2, $f4, 26); $f1f5_4 = self::mul($f1_2, $f5_2, 26); $f1f6_2 = self::mul($f1_2, $f6, 26); $f1f7_4 = self::mul($f1_2, $f7_2, 26); $f1f8_2 = self::mul($f1_2, $f8, 26); $f1f9_76 = self::mul($f9_38, $f1_2, 27); $f2f2 = self::mul($f2, $f2, 27); $f2f3_2 = self::mul($f2_2, $f3, 27); $f2f4_2 = self::mul($f2_2, $f4, 27); $f2f5_2 = self::mul($f2_2, $f5, 27); $f2f6_2 = self::mul($f2_2, $f6, 27); $f2f7_2 = self::mul($f2_2, $f7, 27); $f2f8_38 = self::mul($f8_19, $f2_2, 27); $f2f9_38 = self::mul($f9_38, $f2, 26); $f3f3_2 = self::mul($f3_2, $f3, 26); $f3f4_2 = self::mul($f3_2, $f4, 26); $f3f5_4 = self::mul($f3_2, $f5_2, 26); $f3f6_2 = self::mul($f3_2, $f6, 26); $f3f7_76 = self::mul($f7_38, $f3_2, 26); $f3f8_38 = self::mul($f8_19, $f3_2, 26); $f3f9_76 = self::mul($f9_38, $f3_2, 26); $f4f4 = self::mul($f4, $f4, 26); $f4f5_2 = self::mul($f4_2, $f5, 26); $f4f6_38 = self::mul($f6_19, $f4_2, 27); $f4f7_38 = self::mul($f7_38, $f4, 26); $f4f8_38 = self::mul($f8_19, $f4_2, 27); $f4f9_38 = self::mul($f9_38, $f4, 26); $f5f5_38 = self::mul($f5_38, $f5, 26); $f5f6_38 = self::mul($f6_19, $f5_2, 26); $f5f7_76 = self::mul($f7_38, $f5_2, 26); $f5f8_38 = self::mul($f8_19, $f5_2, 26); $f5f9_76 = self::mul($f9_38, $f5_2, 26); $f6f6_19 = self::mul($f6_19, $f6, 26); $f6f7_38 = self::mul($f7_38, $f6, 26); $f6f8_38 = self::mul($f8_19, $f6_2, 27); $f6f9_38 = self::mul($f9_38, $f6, 26); $f7f7_38 = self::mul($f7_38, $f7, 26); $f7f8_38 = self::mul($f8_19, $f7_2, 26); $f7f9_76 = self::mul($f9_38, $f7_2, 26); $f8f8_19 = self::mul($f8_19, $f8, 26); $f8f9_38 = self::mul($f9_38, $f8, 26); $f9f9_38 = self::mul($f9_38, $f9, 26); $h0 = $f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38; $h1 = $f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38; $h2 = $f0f2_2 + $f1f1_2 + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19; $h3 = $f0f3_2 + $f1f2_2 + $f4f9_38 + $f5f8_38 + $f6f7_38; $h4 = $f0f4_2 + $f1f3_4 + $f2f2 + $f5f9_76 + $f6f8_38 + $f7f7_38; $h5 = $f0f5_2 + $f1f4_2 + $f2f3_2 + $f6f9_38 + $f7f8_38; $h6 = $f0f6_2 + $f1f5_4 + $f2f4_2 + $f3f3_2 + $f7f9_76 + $f8f8_19; $h7 = $f0f7_2 + $f1f6_2 + $f2f5_2 + $f3f4_2 + $f8f9_38; $h8 = $f0f8_2 + $f1f7_4 + $f2f6_2 + $f3f5_4 + $f4f4 + $f9f9_38; $h9 = $f0f9_2 + $f1f8_2 + $f2f7_2 + $f3f6_2 + $f4f5_2; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * Square and double a field element * * h = 2 * f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $f = self::fe_normalize($f); $f0 = (int) $f[0]; $f1 = (int) $f[1]; $f2 = (int) $f[2]; $f3 = (int) $f[3]; $f4 = (int) $f[4]; $f5 = (int) $f[5]; $f6 = (int) $f[6]; $f7 = (int) $f[7]; $f8 = (int) $f[8]; $f9 = (int) $f[9]; $f0_2 = $f0 << 1; $f1_2 = $f1 << 1; $f2_2 = $f2 << 1; $f3_2 = $f3 << 1; $f4_2 = $f4 << 1; $f5_2 = $f5 << 1; $f6_2 = $f6 << 1; $f7_2 = $f7 << 1; $f5_38 = self::mul($f5, 38, 6); /* 1.959375*2^30 */ $f6_19 = self::mul($f6, 19, 5); /* 1.959375*2^30 */ $f7_38 = self::mul($f7, 38, 6); /* 1.959375*2^30 */ $f8_19 = self::mul($f8, 19, 5); /* 1.959375*2^30 */ $f9_38 = self::mul($f9, 38, 6); /* 1.959375*2^30 */ $f0f0 = self::mul($f0, $f0, 24); $f0f1_2 = self::mul($f0_2, $f1, 24); $f0f2_2 = self::mul($f0_2, $f2, 24); $f0f3_2 = self::mul($f0_2, $f3, 24); $f0f4_2 = self::mul($f0_2, $f4, 24); $f0f5_2 = self::mul($f0_2, $f5, 24); $f0f6_2 = self::mul($f0_2, $f6, 24); $f0f7_2 = self::mul($f0_2, $f7, 24); $f0f8_2 = self::mul($f0_2, $f8, 24); $f0f9_2 = self::mul($f0_2, $f9, 24); $f1f1_2 = self::mul($f1_2, $f1, 24); $f1f2_2 = self::mul($f1_2, $f2, 24); $f1f3_4 = self::mul($f1_2, $f3_2, 24); $f1f4_2 = self::mul($f1_2, $f4, 24); $f1f5_4 = self::mul($f1_2, $f5_2, 24); $f1f6_2 = self::mul($f1_2, $f6, 24); $f1f7_4 = self::mul($f1_2, $f7_2, 24); $f1f8_2 = self::mul($f1_2, $f8, 24); $f1f9_76 = self::mul($f9_38, $f1_2, 24); $f2f2 = self::mul($f2, $f2, 24); $f2f3_2 = self::mul($f2_2, $f3, 24); $f2f4_2 = self::mul($f2_2, $f4, 24); $f2f5_2 = self::mul($f2_2, $f5, 24); $f2f6_2 = self::mul($f2_2, $f6, 24); $f2f7_2 = self::mul($f2_2, $f7, 24); $f2f8_38 = self::mul($f8_19, $f2_2, 25); $f2f9_38 = self::mul($f9_38, $f2, 24); $f3f3_2 = self::mul($f3_2, $f3, 24); $f3f4_2 = self::mul($f3_2, $f4, 24); $f3f5_4 = self::mul($f3_2, $f5_2, 24); $f3f6_2 = self::mul($f3_2, $f6, 24); $f3f7_76 = self::mul($f7_38, $f3_2, 24); $f3f8_38 = self::mul($f8_19, $f3_2, 24); $f3f9_76 = self::mul($f9_38, $f3_2, 24); $f4f4 = self::mul($f4, $f4, 24); $f4f5_2 = self::mul($f4_2, $f5, 24); $f4f6_38 = self::mul($f6_19, $f4_2, 25); $f4f7_38 = self::mul($f7_38, $f4, 24); $f4f8_38 = self::mul($f8_19, $f4_2, 25); $f4f9_38 = self::mul($f9_38, $f4, 24); $f5f5_38 = self::mul($f5_38, $f5, 24); $f5f6_38 = self::mul($f6_19, $f5_2, 24); $f5f7_76 = self::mul($f7_38, $f5_2, 24); $f5f8_38 = self::mul($f8_19, $f5_2, 24); $f5f9_76 = self::mul($f9_38, $f5_2, 24); $f6f6_19 = self::mul($f6_19, $f6, 24); $f6f7_38 = self::mul($f7_38, $f6, 24); $f6f8_38 = self::mul($f8_19, $f6_2, 25); $f6f9_38 = self::mul($f9_38, $f6, 24); $f7f7_38 = self::mul($f7_38, $f7, 24); $f7f8_38 = self::mul($f8_19, $f7_2, 24); $f7f9_76 = self::mul($f9_38, $f7_2, 24); $f8f8_19 = self::mul($f8_19, $f8, 24); $f8f9_38 = self::mul($f9_38, $f8, 24); $f9f9_38 = self::mul($f9_38, $f9, 24); $h0 = (int) ($f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38) << 1; $h1 = (int) ($f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38) << 1; $h2 = (int) ($f0f2_2 + $f1f1_2 + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19) << 1; $h3 = (int) ($f0f3_2 + $f1f2_2 + $f4f9_38 + $f5f8_38 + $f6f7_38) << 1; $h4 = (int) ($f0f4_2 + $f1f3_4 + $f2f2 + $f5f9_76 + $f6f8_38 + $f7f7_38) << 1; $h5 = (int) ($f0f5_2 + $f1f4_2 + $f2f3_2 + $f6f9_38 + $f7f8_38) << 1; $h6 = (int) ($f0f6_2 + $f1f5_4 + $f2f4_2 + $f3f3_2 + $f7f9_76 + $f8f8_19) << 1; $h7 = (int) ($f0f7_2 + $f1f6_2 + $f2f5_2 + $f3f4_2 + $f8f9_38) << 1; $h8 = (int) ($f0f8_2 + $f1f7_4 + $f2f6_2 + $f3f5_4 + $f4f4 + $f9f9_38) << 1; $h9 = (int) ($f0f9_2 + $f1f8_2 + $f2f7_2 + $f3f6_2 + $f4f5_2) << 1; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $Z * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_invert(ParagonIE_Sodium_Core_Curve25519_Fe $Z) { $z = clone $Z; $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t2 = self::fe_sq($t0); $t1 = self::fe_mul($t1, $t2); $t2 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 20; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 100; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } return self::fe_mul($t1, $t0); } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106 * * @param ParagonIE_Sodium_Core_Curve25519_Fe $z * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_pow22523(ParagonIE_Sodium_Core_Curve25519_Fe $z) { $z = self::fe_normalize($z); # fe_sq(t0, z); # fe_sq(t1, t0); # fe_sq(t1, t1); # fe_mul(t1, z, t1); # fe_mul(t0, t0, t1); # fe_sq(t0, t0); # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t0 = self::fe_sq($t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 5; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 20; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 20; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 100; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 100; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t0, t0); # fe_sq(t0, t0); # fe_mul(out, t0, z); $t0 = self::fe_mul($t1, $t0); $t0 = self::fe_sq($t0); $t0 = self::fe_sq($t0); return self::fe_mul($t0, $z); } /** * Subtract two field elements. * * h = f - g * * Preconditions: * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * * Postconditions: * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedOperand */ public static function fe_sub(ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g) { return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) ($f[0] - $g[0]), (int) ($f[1] - $g[1]), (int) ($f[2] - $g[2]), (int) ($f[3] - $g[3]), (int) ($f[4] - $g[4]), (int) ($f[5] - $g[5]), (int) ($f[6] - $g[6]), (int) ($f[7] - $g[7]), (int) ($f[8] - $g[8]), (int) ($f[9] - $g[9]) ) ) ); } /** * Add two group elements. * * r = p + q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_add( ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YplusX); $r->Y = self::fe_mul($r->Y, $q->YminusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215 * @param string $a * @return array<int, mixed> * @throws SodiumException * @throws TypeError */ public static function slide($a) { if (self::strlen($a) < 256) { if (self::strlen($a) < 16) { $a = str_pad($a, 256, '0', STR_PAD_RIGHT); } } /** @var array<int, int> $r */ $r = array(); /** @var int $i */ for ($i = 0; $i < 256; ++$i) { $r[$i] = (int) ( 1 & ( self::chrToInt($a[(int) ($i >> 3)]) >> ($i & 7) ) ); } for ($i = 0;$i < 256;++$i) { if ($r[$i]) { for ($b = 1;$b <= 6 && $i + $b < 256;++$b) { if ($r[$i + $b]) { if ($r[$i] + ($r[$i + $b] << $b) <= 15) { $r[$i] += $r[$i + $b] << $b; $r[$i + $b] = 0; } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) { $r[$i] -= $r[$i + $b] << $b; for ($k = $i + $b; $k < 256; ++$k) { if (!$r[$k]) { $r[$k] = 1; break; } $r[$k] = 0; } } else { break; } } } } } return $r; } /** * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_frombytes_negate_vartime($s) { static $d = null; if (!$d) { $d = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d); } # fe_frombytes(h->Y,s); # fe_1(h->Z); $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3( self::fe_0(), self::fe_frombytes($s), self::fe_1() ); # fe_sq(u,h->Y); # fe_mul(v,u,d); # fe_sub(u,u,h->Z); /* u = y^2-1 */ # fe_add(v,v,h->Z); /* v = dy^2+1 */ $u = self::fe_sq($h->Y); /** @var ParagonIE_Sodium_Core_Curve25519_Fe $d */ $v = self::fe_mul($u, $d); $u = self::fe_sub($u, $h->Z); /* u = y^2 - 1 */ $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */ # fe_sq(v3,v); # fe_mul(v3,v3,v); /* v3 = v^3 */ # fe_sq(h->X,v3); # fe_mul(h->X,h->X,v); # fe_mul(h->X,h->X,u); /* x = uv^7 */ $v3 = self::fe_sq($v); $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */ $h->X = self::fe_sq($v3); $h->X = self::fe_mul($h->X, $v); $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */ # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ # fe_mul(h->X,h->X,v3); # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */ $h->X = self::fe_mul($h->X, $v3); $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */ # fe_sq(vxx,h->X); # fe_mul(vxx,vxx,v); # fe_sub(check,vxx,u); /* vx^2-u */ $vxx = self::fe_sq($h->X); $vxx = self::fe_mul($vxx, $v); $check = self::fe_sub($vxx, $u); /* vx^2 - u */ # if (fe_isnonzero(check)) { # fe_add(check,vxx,u); /* vx^2+u */ # if (fe_isnonzero(check)) { # return -1; # } # fe_mul(h->X,h->X,sqrtm1); # } if (self::fe_isnonzero($check)) { $check = self::fe_add($vxx, $u); /* vx^2 + u */ if (self::fe_isnonzero($check)) { throw new RangeException('Internal check failed.'); } $h->X = self::fe_mul( $h->X, ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1) ); } # if (fe_isnegative(h->X) == (s[31] >> 7)) { # fe_neg(h->X,h->X); # } $i = self::chrToInt($s[31]); if (self::fe_isnegative($h->X) === ($i >> 7)) { $h->X = self::fe_neg($h->X); } # fe_mul(h->T,h->X,h->Y); $h->T = self::fe_mul($h->X, $h->Y); return $h; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_madd( ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yplusx); $r->Y = self::fe_mul($r->Y, $q->yminusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add(clone $p->Z, clone $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_msub( ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yminusx); $r->Y = self::fe_mul($r->Y, $q->yplusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add($p->Z, $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P2(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); $r->T = self::fe_mul($p->X, $p->Y); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p2_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_P2( self::fe_0(), self::fe_1(), self::fe_1() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_p2_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_sq($p->X); $r->Z = self::fe_sq($p->Y); $r->T = self::fe_sq2($p->Z); $r->Y = self::fe_add($p->X, $p->Y); $t0 = self::fe_sq($r->Y); $r->Y = self::fe_add($r->Z, $r->X); $r->Z = self::fe_sub($r->Z, $r->X); $r->X = self::fe_sub($t0, $r->Y); $r->T = self::fe_sub($r->T, $r->Z); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_p3_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_P3( self::fe_0(), self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached */ public static function ge_p3_to_cached(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { static $d2 = null; if ($d2 === null) { $d2 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d2); } /** @var ParagonIE_Sodium_Core_Curve25519_Fe $d2 */ $r = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(); $r->YplusX = self::fe_add($p->Y, $p->X); $r->YminusX = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_copy($p->Z); $r->T2d = self::fe_mul($p->T, $d2); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p3_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { return new ParagonIE_Sodium_Core_Curve25519_Ge_P2( self::fe_copy($p->X), self::fe_copy($p->Y), self::fe_copy($p->Z) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_p3_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_p3_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { $q = self::ge_p3_to_p2($p); return self::ge_p2_dbl($q); } /** * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp */ public static function ge_precomp_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param int $b * @param int $c * @return int */ public static function equal($b, $c) { return (int) ((($b ^ $c) - 1) >> 31) & 1; } /** * @internal You should not use this directly from another application * * @param int|string $char * @return int (1 = yes, 0 = no) * @throws SodiumException * @throws TypeError */ public static function negative($char) { if (is_int($char)) { return ($char >> 63) & 1; } $x = self::chrToInt(self::substr($char, 0, 1)); return (int) ($x >> 63); } /** * Conditional move * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp */ public static function cmov( ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u, $b ) { if (!is_int($b)) { throw new InvalidArgumentException('Expected an integer.'); } return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_cmov($t->yplusx, $u->yplusx, $b), self::fe_cmov($t->yminusx, $u->yminusx, $b), self::fe_cmov($t->xy2d, $u->xy2d, $b) ); } /** * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached */ public static function ge_cmov_cached( ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u, $b ) { $b &= 1; $ret = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(); $ret->YplusX = self::fe_cmov($t->YplusX, $u->YplusX, $b); $ret->YminusX = self::fe_cmov($t->YminusX, $u->YminusX, $b); $ret->Z = self::fe_cmov($t->Z, $u->Z, $b); $ret->T2d = self::fe_cmov($t->T2d, $u->T2d, $b); return $ret; } /** * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $cached * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached * @throws SodiumException */ public static function ge_cmov8_cached(array $cached, $b) { // const unsigned char bnegative = negative(b); // const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); // ge25519_cached_0(t); $t = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_1(), self::fe_1(), self::fe_1(), self::fe_0() ); // ge25519_cmov_cached(t, &cached[0], equal(babs, 1)); // ge25519_cmov_cached(t, &cached[1], equal(babs, 2)); // ge25519_cmov_cached(t, &cached[2], equal(babs, 3)); // ge25519_cmov_cached(t, &cached[3], equal(babs, 4)); // ge25519_cmov_cached(t, &cached[4], equal(babs, 5)); // ge25519_cmov_cached(t, &cached[5], equal(babs, 6)); // ge25519_cmov_cached(t, &cached[6], equal(babs, 7)); // ge25519_cmov_cached(t, &cached[7], equal(babs, 8)); for ($x = 0; $x < 8; ++$x) { $t = self::ge_cmov_cached($t, $cached[$x], self::equal($babs, $x + 1)); } // fe25519_copy(minust.YplusX, t->YminusX); // fe25519_copy(minust.YminusX, t->YplusX); // fe25519_copy(minust.Z, t->Z); // fe25519_neg(minust.T2d, t->T2d); $minust = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_copy($t->YminusX), self::fe_copy($t->YplusX), self::fe_copy($t->Z), self::fe_neg($t->T2d) ); return self::ge_cmov_cached($t, $minust, $bnegative); } /** * @internal You should not use this directly from another application * * @param int $pos * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayOffset */ public static function ge_select($pos = 0, $b = 0) { static $base = null; if ($base === null) { $base = array(); /** @var int $i */ foreach (self::$base as $i => $bas) { for ($j = 0; $j < 8; ++$j) { $base[$i][$j] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][0]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][1]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][2]) ); } } } /** @var array<int, array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp>> $base */ if (!is_int($pos)) { throw new InvalidArgumentException('Position must be an integer'); } if ($pos < 0 || $pos > 31) { throw new RangeException('Position is out of range [0, 31]'); } $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); $t = self::ge_precomp_0(); for ($i = 0; $i < 8; ++$i) { $t = self::cmov( $t, $base[$pos][$i], self::equal($babs, $i + 1) ); } $minusT = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_copy($t->yminusx), self::fe_copy($t->yplusx), self::fe_neg($t->xy2d) ); return self::cmov($t, $minusT, $bnegative); } /** * Subtract two group elements. * * r = p - q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_sub( ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YminusX); $r->Y = self::fe_mul($r->Y, $q->YplusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * Convert a group element to a byte string. * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A * @param string $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess */ public static function ge_double_scalarmult_vartime( $a, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A, $b ) { /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Cached> $Ai */ $Ai = array(); /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp> $Bi */ static $Bi = array(); if (!$Bi) { for ($i = 0; $i < 8; ++$i) { $Bi[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][0]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][1]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][2]) ); } } for ($i = 0; $i < 8; ++$i) { $Ai[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_0(), self::fe_0(), self::fe_0(), self::fe_0() ); } # slide(aslide,a); # slide(bslide,b); /** @var array<int, int> $aslide */ $aslide = self::slide($a); /** @var array<int, int> $bslide */ $bslide = self::slide($b); # ge_p3_to_cached(&Ai[0],A); # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); $Ai[0] = self::ge_p3_to_cached($A); $t = self::ge_p3_dbl($A); $A2 = self::ge_p1p1_to_p3($t); # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); for ($i = 0; $i < 7; ++$i) { $t = self::ge_add($A2, $Ai[$i]); $u = self::ge_p1p1_to_p3($t); $Ai[$i + 1] = self::ge_p3_to_cached($u); } # ge_p2_0(r); $r = self::ge_p2_0(); # for (i = 255;i >= 0;--i) { # if (aslide[i] || bslide[i]) break; # } $i = 255; for (; $i >= 0; --$i) { if ($aslide[$i] || $bslide[$i]) { break; } } # for (;i >= 0;--i) { for (; $i >= 0; --$i) { # ge_p2_dbl(&t,r); $t = self::ge_p2_dbl($r); # if (aslide[i] > 0) { if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_add(&t,&u,&Ai[aslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_add( $u, $Ai[(int) floor($aslide[$i] / 2)] ); # } else if (aslide[i] < 0) { } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_sub(&t,&u,&Ai[(-aslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_sub( $u, $Ai[(int) floor(-$aslide[$i] / 2)] ); } # if (bslide[i] > 0) { if ($bslide[$i] > 0) { /** @var int $index */ $index = (int) floor($bslide[$i] / 2); # ge_p1p1_to_p3(&u,&t); # ge_madd(&t,&u,&Bi[bslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_madd($t, $u, $Bi[$index]); # } else if (bslide[i] < 0) { } elseif ($bslide[$i] < 0) { /** @var int $index */ $index = (int) floor(-$bslide[$i] / 2); # ge_p1p1_to_p3(&u,&t); # ge_msub(&t,&u,&Bi[(-bslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_msub($t, $u, $Bi[$index]); } # ge_p1p1_to_p2(r,&t); $r = self::ge_p1p1_to_p2($t); } return $r; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function ge_scalarmult($a, $p) { $e = array_fill(0, 64, 0); /** @var ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $pi */ $pi = array(); // ge25519_p3_to_cached(&pi[1 - 1], p); /* p */ $pi[0] = self::ge_p3_to_cached($p); // ge25519_p3_dbl(&t2, p); // ge25519_p1p1_to_p3(&p2, &t2); // ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */ $t2 = self::ge_p3_dbl($p); $p2 = self::ge_p1p1_to_p3($t2); $pi[1] = self::ge_p3_to_cached($p2); // ge25519_add_cached(&t3, p, &pi[2 - 1]); // ge25519_p1p1_to_p3(&p3, &t3); // ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */ $t3 = self::ge_add($p, $pi[1]); $p3 = self::ge_p1p1_to_p3($t3); $pi[2] = self::ge_p3_to_cached($p3); // ge25519_p3_dbl(&t4, &p2); // ge25519_p1p1_to_p3(&p4, &t4); // ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */ $t4 = self::ge_p3_dbl($p2); $p4 = self::ge_p1p1_to_p3($t4); $pi[3] = self::ge_p3_to_cached($p4); // ge25519_add_cached(&t5, p, &pi[4 - 1]); // ge25519_p1p1_to_p3(&p5, &t5); // ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */ $t5 = self::ge_add($p, $pi[3]); $p5 = self::ge_p1p1_to_p3($t5); $pi[4] = self::ge_p3_to_cached($p5); // ge25519_p3_dbl(&t6, &p3); // ge25519_p1p1_to_p3(&p6, &t6); // ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */ $t6 = self::ge_p3_dbl($p3); $p6 = self::ge_p1p1_to_p3($t6); $pi[5] = self::ge_p3_to_cached($p6); // ge25519_add_cached(&t7, p, &pi[6 - 1]); // ge25519_p1p1_to_p3(&p7, &t7); // ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */ $t7 = self::ge_add($p, $pi[5]); $p7 = self::ge_p1p1_to_p3($t7); $pi[6] = self::ge_p3_to_cached($p7); // ge25519_p3_dbl(&t8, &p4); // ge25519_p1p1_to_p3(&p8, &t8); // ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */ $t8 = self::ge_p3_dbl($p4); $p8 = self::ge_p1p1_to_p3($t8); $pi[7] = self::ge_p3_to_cached($p8); // for (i = 0; i < 32; ++i) { // e[2 * i + 0] = (a[i] >> 0) & 15; // e[2 * i + 1] = (a[i] >> 4) & 15; // } for ($i = 0; $i < 32; ++$i) { $e[($i << 1) ] = self::chrToInt($a[$i]) & 15; $e[($i << 1) + 1] = (self::chrToInt($a[$i]) >> 4) & 15; } // /* each e[i] is between 0 and 15 */ // /* e[63] is between 0 and 7 */ // carry = 0; // for (i = 0; i < 63; ++i) { // e[i] += carry; // carry = e[i] + 8; // carry >>= 4; // e[i] -= carry * ((signed char) 1 << 4); // } $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } // e[63] += carry; // /* each e[i] is between -8 and 8 */ $e[63] += $carry; // ge25519_p3_0(h); $h = self::ge_p3_0(); // for (i = 63; i != 0; i--) { for ($i = 63; $i != 0; --$i) { // ge25519_cmov8_cached(&t, pi, e[i]); $t = self::ge_cmov8_cached($pi, $e[$i]); // ge25519_add_cached(&r, h, &t); $r = self::ge_add($h, $t); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); // ge25519_p1p1_to_p3(h, &r); /* *16 */ $h = self::ge_p1p1_to_p3($r); /* *16 */ } // ge25519_cmov8_cached(&t, pi, e[i]); // ge25519_add_cached(&r, h, &t); // ge25519_p1p1_to_p3(h, &r); $t = self::ge_cmov8_cached($pi, $e[0]); $r = self::ge_add($h, $t); return self::ge_p1p1_to_p3($r); } /** * @internal You should not use this directly from another application * * @param string $a * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function ge_scalarmult_base($a) { /** @var array<int, int> $e */ $e = array(); $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); for ($i = 0; $i < 32; ++$i) { $dbl = (int) $i << 1; $e[$dbl] = (int) self::chrToInt($a[$i]) & 15; $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15; } $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } $e[63] += (int) $carry; $h = self::ge_p3_0(); for ($i = 1; $i < 64; $i += 2) { $t = self::ge_select((int) floor($i / 2), (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } $r = self::ge_p3_dbl($h); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $h = self::ge_p1p1_to_p3($r); for ($i = 0; $i < 64; $i += 2) { $t = self::ge_select($i >> 1, (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } return $h; } /** * Calculates (ab + c) mod l * where l = 2^252 + 27742317777372353535851937790883648493 * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @param string $c * @return string * @throws TypeError */ public static function sc_muladd($a, $b, $c) { $a0 = 2097151 & self::load_3(self::substr($a, 0, 3)); $a1 = 2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5); $a2 = 2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2); $a3 = 2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7); $a4 = 2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4); $a5 = 2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1); $a6 = 2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6); $a7 = 2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3); $a8 = 2097151 & self::load_3(self::substr($a, 21, 3)); $a9 = 2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5); $a10 = 2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2); $a11 = (self::load_4(self::substr($a, 28, 4)) >> 7); $b0 = 2097151 & self::load_3(self::substr($b, 0, 3)); $b1 = 2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5); $b2 = 2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2); $b3 = 2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7); $b4 = 2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4); $b5 = 2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1); $b6 = 2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6); $b7 = 2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3); $b8 = 2097151 & self::load_3(self::substr($b, 21, 3)); $b9 = 2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5); $b10 = 2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2); $b11 = (self::load_4(self::substr($b, 28, 4)) >> 7); $c0 = 2097151 & self::load_3(self::substr($c, 0, 3)); $c1 = 2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5); $c2 = 2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2); $c3 = 2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7); $c4 = 2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4); $c5 = 2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1); $c6 = 2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6); $c7 = 2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3); $c8 = 2097151 & self::load_3(self::substr($c, 21, 3)); $c9 = 2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5); $c10 = 2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2); $c11 = (self::load_4(self::substr($c, 28, 4)) >> 7); /* Can't really avoid the pyramid here: */ $s0 = $c0 + self::mul($a0, $b0, 24); $s1 = $c1 + self::mul($a0, $b1, 24) + self::mul($a1, $b0, 24); $s2 = $c2 + self::mul($a0, $b2, 24) + self::mul($a1, $b1, 24) + self::mul($a2, $b0, 24); $s3 = $c3 + self::mul($a0, $b3, 24) + self::mul($a1, $b2, 24) + self::mul($a2, $b1, 24) + self::mul($a3, $b0, 24); $s4 = $c4 + self::mul($a0, $b4, 24) + self::mul($a1, $b3, 24) + self::mul($a2, $b2, 24) + self::mul($a3, $b1, 24) + self::mul($a4, $b0, 24); $s5 = $c5 + self::mul($a0, $b5, 24) + self::mul($a1, $b4, 24) + self::mul($a2, $b3, 24) + self::mul($a3, $b2, 24) + self::mul($a4, $b1, 24) + self::mul($a5, $b0, 24); $s6 = $c6 + self::mul($a0, $b6, 24) + self::mul($a1, $b5, 24) + self::mul($a2, $b4, 24) + self::mul($a3, $b3, 24) + self::mul($a4, $b2, 24) + self::mul($a5, $b1, 24) + self::mul($a6, $b0, 24); $s7 = $c7 + self::mul($a0, $b7, 24) + self::mul($a1, $b6, 24) + self::mul($a2, $b5, 24) + self::mul($a3, $b4, 24) + self::mul($a4, $b3, 24) + self::mul($a5, $b2, 24) + self::mul($a6, $b1, 24) + self::mul($a7, $b0, 24); $s8 = $c8 + self::mul($a0, $b8, 24) + self::mul($a1, $b7, 24) + self::mul($a2, $b6, 24) + self::mul($a3, $b5, 24) + self::mul($a4, $b4, 24) + self::mul($a5, $b3, 24) + self::mul($a6, $b2, 24) + self::mul($a7, $b1, 24) + self::mul($a8, $b0, 24); $s9 = $c9 + self::mul($a0, $b9, 24) + self::mul($a1, $b8, 24) + self::mul($a2, $b7, 24) + self::mul($a3, $b6, 24) + self::mul($a4, $b5, 24) + self::mul($a5, $b4, 24) + self::mul($a6, $b3, 24) + self::mul($a7, $b2, 24) + self::mul($a8, $b1, 24) + self::mul($a9, $b0, 24); $s10 = $c10 + self::mul($a0, $b10, 24) + self::mul($a1, $b9, 24) + self::mul($a2, $b8, 24) + self::mul($a3, $b7, 24) + self::mul($a4, $b6, 24) + self::mul($a5, $b5, 24) + self::mul($a6, $b4, 24) + self::mul($a7, $b3, 24) + self::mul($a8, $b2, 24) + self::mul($a9, $b1, 24) + self::mul($a10, $b0, 24); $s11 = $c11 + self::mul($a0, $b11, 24) + self::mul($a1, $b10, 24) + self::mul($a2, $b9, 24) + self::mul($a3, $b8, 24) + self::mul($a4, $b7, 24) + self::mul($a5, $b6, 24) + self::mul($a6, $b5, 24) + self::mul($a7, $b4, 24) + self::mul($a8, $b3, 24) + self::mul($a9, $b2, 24) + self::mul($a10, $b1, 24) + self::mul($a11, $b0, 24); $s12 = self::mul($a1, $b11, 24) + self::mul($a2, $b10, 24) + self::mul($a3, $b9, 24) + self::mul($a4, $b8, 24) + self::mul($a5, $b7, 24) + self::mul($a6, $b6, 24) + self::mul($a7, $b5, 24) + self::mul($a8, $b4, 24) + self::mul($a9, $b3, 24) + self::mul($a10, $b2, 24) + self::mul($a11, $b1, 24); $s13 = self::mul($a2, $b11, 24) + self::mul($a3, $b10, 24) + self::mul($a4, $b9, 24) + self::mul($a5, $b8, 24) + self::mul($a6, $b7, 24) + self::mul($a7, $b6, 24) + self::mul($a8, $b5, 24) + self::mul($a9, $b4, 24) + self::mul($a10, $b3, 24) + self::mul($a11, $b2, 24); $s14 = self::mul($a3, $b11, 24) + self::mul($a4, $b10, 24) + self::mul($a5, $b9, 24) + self::mul($a6, $b8, 24) + self::mul($a7, $b7, 24) + self::mul($a8, $b6, 24) + self::mul($a9, $b5, 24) + self::mul($a10, $b4, 24) + self::mul($a11, $b3, 24); $s15 = self::mul($a4, $b11, 24) + self::mul($a5, $b10, 24) + self::mul($a6, $b9, 24) + self::mul($a7, $b8, 24) + self::mul($a8, $b7, 24) + self::mul($a9, $b6, 24) + self::mul($a10, $b5, 24) + self::mul($a11, $b4, 24); $s16 = self::mul($a5, $b11, 24) + self::mul($a6, $b10, 24) + self::mul($a7, $b9, 24) + self::mul($a8, $b8, 24) + self::mul($a9, $b7, 24) + self::mul($a10, $b6, 24) + self::mul($a11, $b5, 24); $s17 = self::mul($a6, $b11, 24) + self::mul($a7, $b10, 24) + self::mul($a8, $b9, 24) + self::mul($a9, $b8, 24) + self::mul($a10, $b7, 24) + self::mul($a11, $b6, 24); $s18 = self::mul($a7, $b11, 24) + self::mul($a8, $b10, 24) + self::mul($a9, $b9, 24) + self::mul($a10, $b8, 24) + self::mul($a11, $b7, 24); $s19 = self::mul($a8, $b11, 24) + self::mul($a9, $b10, 24) + self::mul($a10, $b9, 24) + self::mul($a11, $b8, 24); $s20 = self::mul($a9, $b11, 24) + self::mul($a10, $b10, 24) + self::mul($a11, $b9, 24); $s21 = self::mul($a10, $b11, 24) + self::mul($a11, $b10, 24); $s22 = self::mul($a11, $b11, 24); $s23 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry18 = ($s18 + (1 << 20)) >> 21; $s19 += $carry18; $s18 -= $carry18 << 21; $carry20 = ($s20 + (1 << 20)) >> 21; $s21 += $carry20; $s20 -= $carry20 << 21; $carry22 = ($s22 + (1 << 20)) >> 21; $s23 += $carry22; $s22 -= $carry22 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $carry17 = ($s17 + (1 << 20)) >> 21; $s18 += $carry17; $s17 -= $carry17 << 21; $carry19 = ($s19 + (1 << 20)) >> 21; $s20 += $carry19; $s19 -= $carry19 << 21; $carry21 = ($s21 + (1 << 20)) >> 21; $s22 += $carry21; $s21 -= $carry21 << 21; $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; /** * @var array<int, int> */ $arr = array( (int) (0xff & ($s0 >> 0)), (int) (0xff & ($s0 >> 8)), (int) (0xff & (($s0 >> 16) | $s1 << 5)), (int) (0xff & ($s1 >> 3)), (int) (0xff & ($s1 >> 11)), (int) (0xff & (($s1 >> 19) | $s2 << 2)), (int) (0xff & ($s2 >> 6)), (int) (0xff & (($s2 >> 14) | $s3 << 7)), (int) (0xff & ($s3 >> 1)), (int) (0xff & ($s3 >> 9)), (int) (0xff & (($s3 >> 17) | $s4 << 4)), (int) (0xff & ($s4 >> 4)), (int) (0xff & ($s4 >> 12)), (int) (0xff & (($s4 >> 20) | $s5 << 1)), (int) (0xff & ($s5 >> 7)), (int) (0xff & (($s5 >> 15) | $s6 << 6)), (int) (0xff & ($s6 >> 2)), (int) (0xff & ($s6 >> 10)), (int) (0xff & (($s6 >> 18) | $s7 << 3)), (int) (0xff & ($s7 >> 5)), (int) (0xff & ($s7 >> 13)), (int) (0xff & ($s8 >> 0)), (int) (0xff & ($s8 >> 8)), (int) (0xff & (($s8 >> 16) | $s9 << 5)), (int) (0xff & ($s9 >> 3)), (int) (0xff & ($s9 >> 11)), (int) (0xff & (($s9 >> 19) | $s10 << 2)), (int) (0xff & ($s10 >> 6)), (int) (0xff & (($s10 >> 14) | $s11 << 7)), (int) (0xff & ($s11 >> 1)), (int) (0xff & ($s11 >> 9)), 0xff & ($s11 >> 17) ); return self::intArrayToString($arr); } /** * @internal You should not use this directly from another application * * @param string $s * @return string * @throws TypeError */ public static function sc_reduce($s) { $s0 = 2097151 & self::load_3(self::substr($s, 0, 3)); $s1 = 2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5); $s2 = 2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2); $s3 = 2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7); $s4 = 2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4); $s5 = 2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1); $s6 = 2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6); $s7 = 2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3); $s8 = 2097151 & self::load_3(self::substr($s, 21, 3)); $s9 = 2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5); $s10 = 2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2); $s11 = 2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7); $s12 = 2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4); $s13 = 2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1); $s14 = 2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6); $s15 = 2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3); $s16 = 2097151 & self::load_3(self::substr($s, 42, 3)); $s17 = 2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5); $s18 = 2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2); $s19 = 2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7); $s20 = 2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4); $s21 = 2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1); $s22 = 2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6); $s23 = 0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3); $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; /** * @var array<int, int> */ $arr = array( (int) ($s0 >> 0), (int) ($s0 >> 8), (int) (($s0 >> 16) | $s1 << 5), (int) ($s1 >> 3), (int) ($s1 >> 11), (int) (($s1 >> 19) | $s2 << 2), (int) ($s2 >> 6), (int) (($s2 >> 14) | $s3 << 7), (int) ($s3 >> 1), (int) ($s3 >> 9), (int) (($s3 >> 17) | $s4 << 4), (int) ($s4 >> 4), (int) ($s4 >> 12), (int) (($s4 >> 20) | $s5 << 1), (int) ($s5 >> 7), (int) (($s5 >> 15) | $s6 << 6), (int) ($s6 >> 2), (int) ($s6 >> 10), (int) (($s6 >> 18) | $s7 << 3), (int) ($s7 >> 5), (int) ($s7 >> 13), (int) ($s8 >> 0), (int) ($s8 >> 8), (int) (($s8 >> 16) | $s9 << 5), (int) ($s9 >> 3), (int) ($s9 >> 11), (int) (($s9 >> 19) | $s10 << 2), (int) ($s10 >> 6), (int) (($s10 >> 14) | $s11 << 7), (int) ($s11 >> 1), (int) ($s11 >> 9), (int) $s11 >> 17 ); return self::intArrayToString($arr); } /** * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_mul_l(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A) { $aslide = array( 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 ); /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Cached> $Ai size 8 */ $Ai = array(); # ge_p3_to_cached(&Ai[0], A); $Ai[0] = self::ge_p3_to_cached($A); # ge_p3_dbl(&t, A); $t = self::ge_p3_dbl($A); # ge_p1p1_to_p3(&A2, &t); $A2 = self::ge_p1p1_to_p3($t); for ($i = 1; $i < 8; ++$i) { # ge_add(&t, &A2, &Ai[0]); $t = self::ge_add($A2, $Ai[$i - 1]); # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_p3_to_cached(&Ai[i], &u); $Ai[$i] = self::ge_p3_to_cached($u); } $r = self::ge_p3_0(); for ($i = 252; $i >= 0; --$i) { $t = self::ge_p3_dbl($r); if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_add(&t, &u, &Ai[aslide[i] / 2]); $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]); } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]); } } # ge_p1p1_to_p3(r, &t); return self::ge_p1p1_to_p3($t); } /** * @param string $a * @param string $b * @return string */ public static function sc25519_mul($a, $b) { // int64_t a0 = 2097151 & load_3(a); // int64_t a1 = 2097151 & (load_4(a + 2) >> 5); // int64_t a2 = 2097151 & (load_3(a + 5) >> 2); // int64_t a3 = 2097151 & (load_4(a + 7) >> 7); // int64_t a4 = 2097151 & (load_4(a + 10) >> 4); // int64_t a5 = 2097151 & (load_3(a + 13) >> 1); // int64_t a6 = 2097151 & (load_4(a + 15) >> 6); // int64_t a7 = 2097151 & (load_3(a + 18) >> 3); // int64_t a8 = 2097151 & load_3(a + 21); // int64_t a9 = 2097151 & (load_4(a + 23) >> 5); // int64_t a10 = 2097151 & (load_3(a + 26) >> 2); // int64_t a11 = (load_4(a + 28) >> 7); $a0 = 2097151 & self::load_3(self::substr($a, 0, 3)); $a1 = 2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5); $a2 = 2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2); $a3 = 2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7); $a4 = 2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4); $a5 = 2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1); $a6 = 2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6); $a7 = 2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3); $a8 = 2097151 & self::load_3(self::substr($a, 21, 3)); $a9 = 2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5); $a10 = 2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2); $a11 = (self::load_4(self::substr($a, 28, 4)) >> 7); // int64_t b0 = 2097151 & load_3(b); // int64_t b1 = 2097151 & (load_4(b + 2) >> 5); // int64_t b2 = 2097151 & (load_3(b + 5) >> 2); // int64_t b3 = 2097151 & (load_4(b + 7) >> 7); // int64_t b4 = 2097151 & (load_4(b + 10) >> 4); // int64_t b5 = 2097151 & (load_3(b + 13) >> 1); // int64_t b6 = 2097151 & (load_4(b + 15) >> 6); // int64_t b7 = 2097151 & (load_3(b + 18) >> 3); // int64_t b8 = 2097151 & load_3(b + 21); // int64_t b9 = 2097151 & (load_4(b + 23) >> 5); // int64_t b10 = 2097151 & (load_3(b + 26) >> 2); // int64_t b11 = (load_4(b + 28) >> 7); $b0 = 2097151 & self::load_3(self::substr($b, 0, 3)); $b1 = 2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5); $b2 = 2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2); $b3 = 2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7); $b4 = 2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4); $b5 = 2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1); $b6 = 2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6); $b7 = 2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3); $b8 = 2097151 & self::load_3(self::substr($b, 21, 3)); $b9 = 2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5); $b10 = 2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2); $b11 = (self::load_4(self::substr($b, 28, 4)) >> 7); // s0 = a0 * b0; // s1 = a0 * b1 + a1 * b0; // s2 = a0 * b2 + a1 * b1 + a2 * b0; // s3 = a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; // s4 = a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; // s5 = a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; // s6 = a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; // s7 = a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + // a6 * b1 + a7 * b0; // s8 = a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + // a6 * b2 + a7 * b1 + a8 * b0; // s9 = a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + // a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; // s10 = a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + // a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; // s11 = a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + // a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; // s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + // a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; // s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + // a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; // s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + // a9 * b5 + a10 * b4 + a11 * b3; // s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + // a10 * b5 + a11 * b4; // s16 = // a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; // s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; // s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; // s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; // s20 = a9 * b11 + a10 * b10 + a11 * b9; // s21 = a10 * b11 + a11 * b10; // s22 = a11 * b11; // s23 = 0; $s0 = self::mul($a0, $b0, 22); $s1 = self::mul($a0, $b1, 22) + self::mul($a1, $b0, 22); $s2 = self::mul($a0, $b2, 22) + self::mul($a1, $b1, 22) + self::mul($a2, $b0, 22); $s3 = self::mul($a0, $b3, 22) + self::mul($a1, $b2, 22) + self::mul($a2, $b1, 22) + self::mul($a3, $b0, 22); $s4 = self::mul($a0, $b4, 22) + self::mul($a1, $b3, 22) + self::mul($a2, $b2, 22) + self::mul($a3, $b1, 22) + self::mul($a4, $b0, 22); $s5 = self::mul($a0, $b5, 22) + self::mul($a1, $b4, 22) + self::mul($a2, $b3, 22) + self::mul($a3, $b2, 22) + self::mul($a4, $b1, 22) + self::mul($a5, $b0, 22); $s6 = self::mul($a0, $b6, 22) + self::mul($a1, $b5, 22) + self::mul($a2, $b4, 22) + self::mul($a3, $b3, 22) + self::mul($a4, $b2, 22) + self::mul($a5, $b1, 22) + self::mul($a6, $b0, 22); $s7 = self::mul($a0, $b7, 22) + self::mul($a1, $b6, 22) + self::mul($a2, $b5, 22) + self::mul($a3, $b4, 22) + self::mul($a4, $b3, 22) + self::mul($a5, $b2, 22) + self::mul($a6, $b1, 22) + self::mul($a7, $b0, 22); $s8 = self::mul($a0, $b8, 22) + self::mul($a1, $b7, 22) + self::mul($a2, $b6, 22) + self::mul($a3, $b5, 22) + self::mul($a4, $b4, 22) + self::mul($a5, $b3, 22) + self::mul($a6, $b2, 22) + self::mul($a7, $b1, 22) + self::mul($a8, $b0, 22); $s9 = self::mul($a0, $b9, 22) + self::mul($a1, $b8, 22) + self::mul($a2, $b7, 22) + self::mul($a3, $b6, 22) + self::mul($a4, $b5, 22) + self::mul($a5, $b4, 22) + self::mul($a6, $b3, 22) + self::mul($a7, $b2, 22) + self::mul($a8, $b1, 22) + self::mul($a9, $b0, 22); $s10 = self::mul($a0, $b10, 22) + self::mul($a1, $b9, 22) + self::mul($a2, $b8, 22) + self::mul($a3, $b7, 22) + self::mul($a4, $b6, 22) + self::mul($a5, $b5, 22) + self::mul($a6, $b4, 22) + self::mul($a7, $b3, 22) + self::mul($a8, $b2, 22) + self::mul($a9, $b1, 22) + self::mul($a10, $b0, 22); $s11 = self::mul($a0, $b11, 22) + self::mul($a1, $b10, 22) + self::mul($a2, $b9, 22) + self::mul($a3, $b8, 22) + self::mul($a4, $b7, 22) + self::mul($a5, $b6, 22) + self::mul($a6, $b5, 22) + self::mul($a7, $b4, 22) + self::mul($a8, $b3, 22) + self::mul($a9, $b2, 22) + self::mul($a10, $b1, 22) + self::mul($a11, $b0, 22); $s12 = self::mul($a1, $b11, 22) + self::mul($a2, $b10, 22) + self::mul($a3, $b9, 22) + self::mul($a4, $b8, 22) + self::mul($a5, $b7, 22) + self::mul($a6, $b6, 22) + self::mul($a7, $b5, 22) + self::mul($a8, $b4, 22) + self::mul($a9, $b3, 22) + self::mul($a10, $b2, 22) + self::mul($a11, $b1, 22); $s13 = self::mul($a2, $b11, 22) + self::mul($a3, $b10, 22) + self::mul($a4, $b9, 22) + self::mul($a5, $b8, 22) + self::mul($a6, $b7, 22) + self::mul($a7, $b6, 22) + self::mul($a8, $b5, 22) + self::mul($a9, $b4, 22) + self::mul($a10, $b3, 22) + self::mul($a11, $b2, 22); $s14 = self::mul($a3, $b11, 22) + self::mul($a4, $b10, 22) + self::mul($a5, $b9, 22) + self::mul($a6, $b8, 22) + self::mul($a7, $b7, 22) + self::mul($a8, $b6, 22) + self::mul($a9, $b5, 22) + self::mul($a10, $b4, 22) + self::mul($a11, $b3, 22); $s15 = self::mul($a4, $b11, 22) + self::mul($a5, $b10, 22) + self::mul($a6, $b9, 22) + self::mul($a7, $b8, 22) + self::mul($a8, $b7, 22) + self::mul($a9, $b6, 22) + self::mul($a10, $b5, 22) + self::mul($a11, $b4, 22); $s16 = self::mul($a5, $b11, 22) + self::mul($a6, $b10, 22) + self::mul($a7, $b9, 22) + self::mul($a8, $b8, 22) + self::mul($a9, $b7, 22) + self::mul($a10, $b6, 22) + self::mul($a11, $b5, 22); $s17 = self::mul($a6, $b11, 22) + self::mul($a7, $b10, 22) + self::mul($a8, $b9, 22) + self::mul($a9, $b8, 22) + self::mul($a10, $b7, 22) + self::mul($a11, $b6, 22); $s18 = self::mul($a7, $b11, 22) + self::mul($a8, $b10, 22) + self::mul($a9, $b9, 22) + self::mul($a10, $b8, 22) + self::mul($a11, $b7, 22); $s19 = self::mul($a8, $b11, 22) + self::mul($a9, $b10, 22) + self::mul($a10, $b9, 22) + self::mul($a11, $b8, 22); $s20 = self::mul($a9, $b11, 22) + self::mul($a10, $b10, 22) + self::mul($a11, $b9, 22); $s21 = self::mul($a10, $b11, 22) + self::mul($a11, $b10, 22); $s22 = self::mul($a11, $b11, 22); $s23 = 0; // carry0 = (s0 + (int64_t) (1L << 20)) >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry2 = (s2 + (int64_t) (1L << 20)) >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry4 = (s4 + (int64_t) (1L << 20)) >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry12 = (s12 + (int64_t) (1L << 20)) >> 21; // s13 += carry12; // s12 -= carry12 * ((uint64_t) 1L << 21); $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; // carry14 = (s14 + (int64_t) (1L << 20)) >> 21; // s15 += carry14; // s14 -= carry14 * ((uint64_t) 1L << 21); $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; // carry16 = (s16 + (int64_t) (1L << 20)) >> 21; // s17 += carry16; // s16 -= carry16 * ((uint64_t) 1L << 21); $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; // carry18 = (s18 + (int64_t) (1L << 20)) >> 21; // s19 += carry18; // s18 -= carry18 * ((uint64_t) 1L << 21); $carry18 = ($s18 + (1 << 20)) >> 21; $s19 += $carry18; $s18 -= $carry18 << 21; // carry20 = (s20 + (int64_t) (1L << 20)) >> 21; // s21 += carry20; // s20 -= carry20 * ((uint64_t) 1L << 21); $carry20 = ($s20 + (1 << 20)) >> 21; $s21 += $carry20; $s20 -= $carry20 << 21; // carry22 = (s22 + (int64_t) (1L << 20)) >> 21; // s23 += carry22; // s22 -= carry22 * ((uint64_t) 1L << 21); $carry22 = ($s22 + (1 << 20)) >> 21; $s23 += $carry22; $s22 -= $carry22 << 21; // carry1 = (s1 + (int64_t) (1L << 20)) >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry3 = (s3 + (int64_t) (1L << 20)) >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry5 = (s5 + (int64_t) (1L << 20)) >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // carry13 = (s13 + (int64_t) (1L << 20)) >> 21; // s14 += carry13; // s13 -= carry13 * ((uint64_t) 1L << 21); $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; // carry15 = (s15 + (int64_t) (1L << 20)) >> 21; // s16 += carry15; // s15 -= carry15 * ((uint64_t) 1L << 21); $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; // carry17 = (s17 + (int64_t) (1L << 20)) >> 21; // s18 += carry17; // s17 -= carry17 * ((uint64_t) 1L << 21); $carry17 = ($s17 + (1 << 20)) >> 21; $s18 += $carry17; $s17 -= $carry17 << 21; // carry19 = (s19 + (int64_t) (1L << 20)) >> 21; // s20 += carry19; // s19 -= carry19 * ((uint64_t) 1L << 21); $carry19 = ($s19 + (1 << 20)) >> 21; $s20 += $carry19; $s19 -= $carry19 << 21; // carry21 = (s21 + (int64_t) (1L << 20)) >> 21; // s22 += carry21; // s21 -= carry21 * ((uint64_t) 1L << 21); $carry21 = ($s21 + (1 << 20)) >> 21; $s22 += $carry21; $s21 -= $carry21 << 21; // s11 += s23 * 666643; // s12 += s23 * 470296; // s13 += s23 * 654183; // s14 -= s23 * 997805; // s15 += s23 * 136657; // s16 -= s23 * 683901; $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); // s10 += s22 * 666643; // s11 += s22 * 470296; // s12 += s22 * 654183; // s13 -= s22 * 997805; // s14 += s22 * 136657; // s15 -= s22 * 683901; $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); // s9 += s21 * 666643; // s10 += s21 * 470296; // s11 += s21 * 654183; // s12 -= s21 * 997805; // s13 += s21 * 136657; // s14 -= s21 * 683901; $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); // s8 += s20 * 666643; // s9 += s20 * 470296; // s10 += s20 * 654183; // s11 -= s20 * 997805; // s12 += s20 * 136657; // s13 -= s20 * 683901; $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); // s7 += s19 * 666643; // s8 += s19 * 470296; // s9 += s19 * 654183; // s10 -= s19 * 997805; // s11 += s19 * 136657; // s12 -= s19 * 683901; $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); // s6 += s18 * 666643; // s7 += s18 * 470296; // s8 += s18 * 654183; // s9 -= s18 * 997805; // s10 += s18 * 136657; // s11 -= s18 * 683901; $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry12 = (s12 + (int64_t) (1L << 20)) >> 21; // s13 += carry12; // s12 -= carry12 * ((uint64_t) 1L << 21); $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; // carry14 = (s14 + (int64_t) (1L << 20)) >> 21; // s15 += carry14; // s14 -= carry14 * ((uint64_t) 1L << 21); $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; // carry16 = (s16 + (int64_t) (1L << 20)) >> 21; // s17 += carry16; // s16 -= carry16 * ((uint64_t) 1L << 21); $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // carry13 = (s13 + (int64_t) (1L << 20)) >> 21; // s14 += carry13; // s13 -= carry13 * ((uint64_t) 1L << 21); $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; // carry15 = (s15 + (int64_t) (1L << 20)) >> 21; // s16 += carry15; // s15 -= carry15 * ((uint64_t) 1L << 21); $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; // s5 += s17 * 666643; // s6 += s17 * 470296; // s7 += s17 * 654183; // s8 -= s17 * 997805; // s9 += s17 * 136657; // s10 -= s17 * 683901; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); // s4 += s16 * 666643; // s5 += s16 * 470296; // s6 += s16 * 654183; // s7 -= s16 * 997805; // s8 += s16 * 136657; // s9 -= s16 * 683901; $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); // s3 += s15 * 666643; // s4 += s15 * 470296; // s5 += s15 * 654183; // s6 -= s15 * 997805; // s7 += s15 * 136657; // s8 -= s15 * 683901; $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); // s2 += s14 * 666643; // s3 += s14 * 470296; // s4 += s14 * 654183; // s5 -= s14 * 997805; // s6 += s14 * 136657; // s7 -= s14 * 683901; $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); // s1 += s13 * 666643; // s2 += s13 * 470296; // s3 += s13 * 654183; // s4 -= s13 * 997805; // s5 += s13 * 136657; // s6 -= s13 * 683901; $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; // s12 = 0; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; // carry0 = (s0 + (int64_t) (1L << 20)) >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry2 = (s2 + (int64_t) (1L << 20)) >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry4 = (s4 + (int64_t) (1L << 20)) >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry1 = (s1 + (int64_t) (1L << 20)) >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry3 = (s3 + (int64_t) (1L << 20)) >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry5 = (s5 + (int64_t) (1L << 20)) >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; // s12 = 0; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; // carry0 = s0 >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry1 = s1 >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry2 = s2 >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry3 = s3 >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry4 = s4 >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry5 = s5 >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry6 = s6 >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry7 = s7 >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry8 = s8 >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry9 = s9 >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry10 = s10 >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry11 = s11 >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); // carry0 = s0 >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry1 = s1 >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry2 = s2 >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry3 = s3 >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry4 = s4 >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry5 = s5 >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry6 = s6 >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry7 = s7 >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry8 = s8 >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry9 = s9 >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry10 = s10 >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $s = array_fill(0, 32, 0); // s[0] = s0 >> 0; $s[0] = $s0 >> 0; // s[1] = s0 >> 8; $s[1] = $s0 >> 8; // s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); $s[2] = ($s0 >> 16) | ($s1 << 5); // s[3] = s1 >> 3; $s[3] = $s1 >> 3; // s[4] = s1 >> 11; $s[4] = $s1 >> 11; // s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); $s[5] = ($s1 >> 19) | ($s2 << 2); // s[6] = s2 >> 6; $s[6] = $s2 >> 6; // s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); $s[7] = ($s2 >> 14) | ($s3 << 7); // s[8] = s3 >> 1; $s[8] = $s3 >> 1; // s[9] = s3 >> 9; $s[9] = $s3 >> 9; // s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); $s[10] = ($s3 >> 17) | ($s4 << 4); // s[11] = s4 >> 4; $s[11] = $s4 >> 4; // s[12] = s4 >> 12; $s[12] = $s4 >> 12; // s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); $s[13] = ($s4 >> 20) | ($s5 << 1); // s[14] = s5 >> 7; $s[14] = $s5 >> 7; // s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); $s[15] = ($s5 >> 15) | ($s6 << 6); // s[16] = s6 >> 2; $s[16] = $s6 >> 2; // s[17] = s6 >> 10; $s[17] = $s6 >> 10; // s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); $s[18] = ($s6 >> 18) | ($s7 << 3); // s[19] = s7 >> 5; $s[19] = $s7 >> 5; // s[20] = s7 >> 13; $s[20] = $s7 >> 13; // s[21] = s8 >> 0; $s[21] = $s8 >> 0; // s[22] = s8 >> 8; $s[22] = $s8 >> 8; // s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); $s[23] = ($s8 >> 16) | ($s9 << 5); // s[24] = s9 >> 3; $s[24] = $s9 >> 3; // s[25] = s9 >> 11; $s[25] = $s9 >> 11; // s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); $s[26] = ($s9 >> 19) | ($s10 << 2); // s[27] = s10 >> 6; $s[27] = $s10 >> 6; // s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); $s[28] = ($s10 >> 14) | ($s11 << 7); // s[29] = s11 >> 1; $s[29] = $s11 >> 1; // s[30] = s11 >> 9; $s[30] = $s11 >> 9; // s[31] = s11 >> 17; $s[31] = $s11 >> 17; return self::intArrayToString($s); } /** * @param string $s * @return string */ public static function sc25519_sq($s) { return self::sc25519_mul($s, $s); } /** * @param string $s * @param int $n * @param string $a * @return string */ public static function sc25519_sqmul($s, $n, $a) { for ($i = 0; $i < $n; ++$i) { $s = self::sc25519_sq($s); } return self::sc25519_mul($s, $a); } /** * @param string $s * @return string */ public static function sc25519_invert($s) { $_10 = self::sc25519_sq($s); $_11 = self::sc25519_mul($s, $_10); $_100 = self::sc25519_mul($s, $_11); $_1000 = self::sc25519_sq($_100); $_1010 = self::sc25519_mul($_10, $_1000); $_1011 = self::sc25519_mul($s, $_1010); $_10000 = self::sc25519_sq($_1000); $_10110 = self::sc25519_sq($_1011); $_100000 = self::sc25519_mul($_1010, $_10110); $_100110 = self::sc25519_mul($_10000, $_10110); $_1000000 = self::sc25519_sq($_100000); $_1010000 = self::sc25519_mul($_10000, $_1000000); $_1010011 = self::sc25519_mul($_11, $_1010000); $_1100011 = self::sc25519_mul($_10000, $_1010011); $_1100111 = self::sc25519_mul($_100, $_1100011); $_1101011 = self::sc25519_mul($_100, $_1100111); $_10010011 = self::sc25519_mul($_1000000, $_1010011); $_10010111 = self::sc25519_mul($_100, $_10010011); $_10111101 = self::sc25519_mul($_100110, $_10010111); $_11010011 = self::sc25519_mul($_10110, $_10111101); $_11100111 = self::sc25519_mul($_1010000, $_10010111); $_11101011 = self::sc25519_mul($_100, $_11100111); $_11110101 = self::sc25519_mul($_1010, $_11101011); $recip = self::sc25519_mul($_1011, $_11110101); $recip = self::sc25519_sqmul($recip, 126, $_1010011); $recip = self::sc25519_sqmul($recip, 9, $_10); $recip = self::sc25519_mul($recip, $_11110101); $recip = self::sc25519_sqmul($recip, 7, $_1100111); $recip = self::sc25519_sqmul($recip, 9, $_11110101); $recip = self::sc25519_sqmul($recip, 11, $_10111101); $recip = self::sc25519_sqmul($recip, 8, $_11100111); $recip = self::sc25519_sqmul($recip, 9, $_1101011); $recip = self::sc25519_sqmul($recip, 6, $_1011); $recip = self::sc25519_sqmul($recip, 14, $_10010011); $recip = self::sc25519_sqmul($recip, 10, $_1100011); $recip = self::sc25519_sqmul($recip, 9, $_10010111); $recip = self::sc25519_sqmul($recip, 10, $_11110101); $recip = self::sc25519_sqmul($recip, 8, $_11010011); return self::sc25519_sqmul($recip, 8, $_11101011); } /** * @param string $s * @return string */ public static function clamp($s) { $s_ = self::stringToIntArray($s); $s_[0] &= 248; $s_[31] |= 64; $s_[31] &= 128; return self::intArrayToString($s_); } /** * Ensure limbs are less than 28 bits long to prevent float promotion. * * This uses a constant-time conditional swap under the hood. * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_normalize(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $x = (PHP_INT_SIZE << 3) - 1; // 31 or 63 $g = self::fe_copy($f); for ($i = 0; $i < 10; ++$i) { $mask = -(($g[$i] >> $x) & 1); /* * Get two candidate normalized values for $g[$i], depending on the sign of $g[$i]: */ $a = $g[$i] & 0x7ffffff; $b = -((-$g[$i]) & 0x7ffffff); /* * Return the appropriate candidate value, based on the sign of the original input: * * The following is equivalent to this ternary: * * $g[$i] = (($g[$i] >> $x) & 1) ? $a : $b; * * Except what's written doesn't contain timing leaks. */ $g[$i] = ($a ^ (($a ^ $b) & $mask)); } return $g; } } <?php if (!defined('SODIUM_COMPAT_AEGIS_C0')) { define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62"); } if (!defined('SODIUM_COMPAT_AEGIS_C1')) { define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd"); } class ParagonIE_Sodium_Core_AEGIS128L extends ParagonIE_Sodium_Core_AES { /** * @param string $ct * @param string $tag * @param string $ad * @param string $key * @param string $nonce * @return string * @throws SodiumException */ public static function decrypt($ct, $tag, $ad, $key, $nonce) { $state = self::init($key, $nonce); $ad_blocks = (self::strlen($ad) + 31) >> 5; for ($i = 0; $i < $ad_blocks; ++$i) { $ai = self::substr($ad, $i << 5, 32); if (self::strlen($ai) < 32) { $ai = str_pad($ai, 32, "\0", STR_PAD_RIGHT); } $state->absorb($ai); } $msg = ''; $cn = self::strlen($ct) & 31; $ct_blocks = self::strlen($ct) >> 5; for ($i = 0; $i < $ct_blocks; ++$i) { $msg .= $state->dec(self::substr($ct, $i << 5, 32)); } if ($cn) { $start = $ct_blocks << 5; $msg .= $state->decPartial(self::substr($ct, $start, $cn)); } $expected_tag = $state->finalize( self::strlen($ad) << 3, self::strlen($msg) << 3 ); if (!self::hashEquals($expected_tag, $tag)) { try { // The RFC says to erase msg, so we shall try: ParagonIE_Sodium_Compat::memzero($msg); } catch (SodiumException $ex) { // Do nothing if we cannot memzero } throw new SodiumException('verification failed'); } return $msg; } /** * @param string $msg * @param string $ad * @param string $key * @param string $nonce * @return array * * @throws SodiumException */ public static function encrypt($msg, $ad, $key, $nonce) { $state = self::init($key, $nonce); // ad_blocks = Split(ZeroPad(ad, 256), 256) // for ai in ad_blocks: // Absorb(ai) $ad_len = self::strlen($ad); $msg_len = self::strlen($msg); $ad_blocks = ($ad_len + 31) >> 5; for ($i = 0; $i < $ad_blocks; ++$i) { $ai = self::substr($ad, $i << 5, 32); if (self::strlen($ai) < 32) { $ai = str_pad($ai, 32, "\0", STR_PAD_RIGHT); } $state->absorb($ai); } // msg_blocks = Split(ZeroPad(msg, 256), 256) // for xi in msg_blocks: // ct = ct || Enc(xi) $ct = ''; $msg_blocks = ($msg_len + 31) >> 5; for ($i = 0; $i < $msg_blocks; ++$i) { $xi = self::substr($msg, $i << 5, 32); if (self::strlen($xi) < 32) { $xi = str_pad($xi, 32, "\0", STR_PAD_RIGHT); } $ct .= $state->enc($xi); } // tag = Finalize(|ad|, |msg|) // ct = Truncate(ct, |msg|) $tag = $state->finalize( $ad_len << 3, $msg_len << 3 ); // return ct and tag return array( self::substr($ct, 0, $msg_len), $tag ); } /** * @param string $key * @param string $nonce * @return ParagonIE_Sodium_Core_AEGIS_State128L */ public static function init($key, $nonce) { return ParagonIE_Sodium_Core_AEGIS_State128L::init($key, $nonce); } } <?php if (class_exists('ParagonIE_Sodium_Core_SipHash', false)) { return; } /** * Class ParagonIE_SodiumCompat_Core_SipHash * * Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers */ class ParagonIE_Sodium_Core_SipHash extends ParagonIE_Sodium_Core_Util { /** * @internal You should not use this directly from another application * * @param int[] $v * @return int[] * */ public static function sipRound(array $v) { # v0 += v1; list($v[0], $v[1]) = self::add( array($v[0], $v[1]), array($v[2], $v[3]) ); # v1=ROTL(v1,13); list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 13); # v1 ^= v0; $v[2] = (int) $v[2] ^ (int) $v[0]; $v[3] = (int) $v[3] ^ (int) $v[1]; # v0=ROTL(v0,32); list($v[0], $v[1]) = self::rotl_64((int) $v[0], (int) $v[1], 32); # v2 += v3; list($v[4], $v[5]) = self::add( array((int) $v[4], (int) $v[5]), array((int) $v[6], (int) $v[7]) ); # v3=ROTL(v3,16); list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 16); # v3 ^= v2; $v[6] = (int) $v[6] ^ (int) $v[4]; $v[7] = (int) $v[7] ^ (int) $v[5]; # v0 += v3; list($v[0], $v[1]) = self::add( array((int) $v[0], (int) $v[1]), array((int) $v[6], (int) $v[7]) ); # v3=ROTL(v3,21); list($v[6], $v[7]) = self::rotl_64((int) $v[6], (int) $v[7], 21); # v3 ^= v0; $v[6] = (int) $v[6] ^ (int) $v[0]; $v[7] = (int) $v[7] ^ (int) $v[1]; # v2 += v1; list($v[4], $v[5]) = self::add( array((int) $v[4], (int) $v[5]), array((int) $v[2], (int) $v[3]) ); # v1=ROTL(v1,17); list($v[2], $v[3]) = self::rotl_64((int) $v[2], (int) $v[3], 17); # v1 ^= v2;; $v[2] = (int) $v[2] ^ (int) $v[4]; $v[3] = (int) $v[3] ^ (int) $v[5]; # v2=ROTL(v2,32) list($v[4], $v[5]) = self::rotl_64((int) $v[4], (int) $v[5], 32); return $v; } /** * Add two 32 bit integers representing a 64-bit integer. * * @internal You should not use this directly from another application * * @param int[] $a * @param int[] $b * @return array<int, mixed> */ public static function add(array $a, array $b) { /** @var int $x1 */ $x1 = $a[1] + $b[1]; /** @var int $c */ $c = $x1 >> 32; // Carry if ($a + $b) > 0xffffffff /** @var int $x0 */ $x0 = $a[0] + $b[0] + $c; return array( $x0 & 0xffffffff, $x1 & 0xffffffff ); } /** * @internal You should not use this directly from another application * * @param int $int0 * @param int $int1 * @param int $c * @return array<int, mixed> */ public static function rotl_64($int0, $int1, $c) { $int0 &= 0xffffffff; $int1 &= 0xffffffff; $c &= 63; if ($c === 32) { return array($int1, $int0); } if ($c > 31) { $tmp = $int1; $int1 = $int0; $int0 = $tmp; $c &= 31; } if ($c === 0) { return array($int0, $int1); } return array( 0xffffffff & ( ($int0 << $c) | ($int1 >> (32 - $c)) ), 0xffffffff & ( ($int1 << $c) | ($int0 >> (32 - $c)) ), ); } /** * Implements Siphash-2-4 using only 32-bit numbers. * * When we split an int into two, the higher bits go to the lower index. * e.g. 0xDEADBEEFAB10C92D becomes [ * 0 => 0xDEADBEEF, * 1 => 0xAB10C92D * ]. * * @internal You should not use this directly from another application * * @param string $in * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function sipHash24($in, $key) { $inlen = self::strlen($in); # /* "somepseudorandomlygeneratedbytes" */ # u64 v0 = 0x736f6d6570736575ULL; # u64 v1 = 0x646f72616e646f6dULL; # u64 v2 = 0x6c7967656e657261ULL; # u64 v3 = 0x7465646279746573ULL; $v = array( 0x736f6d65, // 0 0x70736575, // 1 0x646f7261, // 2 0x6e646f6d, // 3 0x6c796765, // 4 0x6e657261, // 5 0x74656462, // 6 0x79746573 // 7 ); // v0 => $v[0], $v[1] // v1 => $v[2], $v[3] // v2 => $v[4], $v[5] // v3 => $v[6], $v[7] # u64 k0 = LOAD64_LE( k ); # u64 k1 = LOAD64_LE( k + 8 ); $k = array( self::load_4(self::substr($key, 4, 4)), self::load_4(self::substr($key, 0, 4)), self::load_4(self::substr($key, 12, 4)), self::load_4(self::substr($key, 8, 4)) ); // k0 => $k[0], $k[1] // k1 => $k[2], $k[3] # b = ( ( u64 )inlen ) << 56; $b = array( $inlen << 24, 0 ); // See docblock for why the 0th index gets the higher bits. # v3 ^= k1; $v[6] ^= $k[2]; $v[7] ^= $k[3]; # v2 ^= k0; $v[4] ^= $k[0]; $v[5] ^= $k[1]; # v1 ^= k1; $v[2] ^= $k[2]; $v[3] ^= $k[3]; # v0 ^= k0; $v[0] ^= $k[0]; $v[1] ^= $k[1]; $left = $inlen; # for ( ; in != end; in += 8 ) while ($left >= 8) { # m = LOAD64_LE( in ); $m = array( self::load_4(self::substr($in, 4, 4)), self::load_4(self::substr($in, 0, 4)) ); # v3 ^= m; $v[6] ^= $m[0]; $v[7] ^= $m[1]; # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); # v0 ^= m; $v[0] ^= $m[0]; $v[1] ^= $m[1]; $in = self::substr($in, 8); $left -= 8; } # switch( left ) # { # case 7: b |= ( ( u64 )in[ 6] ) << 48; # case 6: b |= ( ( u64 )in[ 5] ) << 40; # case 5: b |= ( ( u64 )in[ 4] ) << 32; # case 4: b |= ( ( u64 )in[ 3] ) << 24; # case 3: b |= ( ( u64 )in[ 2] ) << 16; # case 2: b |= ( ( u64 )in[ 1] ) << 8; # case 1: b |= ( ( u64 )in[ 0] ); break; # case 0: break; # } switch ($left) { case 7: $b[0] |= self::chrToInt($in[6]) << 16; case 6: $b[0] |= self::chrToInt($in[5]) << 8; case 5: $b[0] |= self::chrToInt($in[4]); case 4: $b[1] |= self::chrToInt($in[3]) << 24; case 3: $b[1] |= self::chrToInt($in[2]) << 16; case 2: $b[1] |= self::chrToInt($in[1]) << 8; case 1: $b[1] |= self::chrToInt($in[0]); case 0: break; } // See docblock for why the 0th index gets the higher bits. # v3 ^= b; $v[6] ^= $b[0]; $v[7] ^= $b[1]; # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); # v0 ^= b; $v[0] ^= $b[0]; $v[1] ^= $b[1]; // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation # v2 ^= 0xff; $v[5] ^= 0xff; # SIPROUND; # SIPROUND; # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); $v = self::sipRound($v); $v = self::sipRound($v); # b = v0 ^ v1 ^ v2 ^ v3; # STORE64_LE( out, b ); return self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) . self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]); } } <?php if (class_exists('ParagonIE_Sodium_Core_HSalsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core_HSalsa20 */ abstract class ParagonIE_Sodium_Core_HSalsa20 extends ParagonIE_Sodium_Core_Salsa20 { /** * Calculate an hsalsa20 hash of a single block * * HSalsa20 doesn't have a counter and will never be used for more than * one block (used to derive a subkey for xsalsa20). * * @internal You should not use this directly from another application * * @param string $in * @param string $k * @param string|null $c * @return string * @throws TypeError */ public static function hsalsa20($in, $k, $c = null) { if ($c === null) { $x0 = 0x61707865; $x5 = 0x3320646e; $x10 = 0x79622d32; $x15 = 0x6b206574; } else { $x0 = self::load_4(self::substr($c, 0, 4)); $x5 = self::load_4(self::substr($c, 4, 4)); $x10 = self::load_4(self::substr($c, 8, 4)); $x15 = self::load_4(self::substr($c, 12, 4)); } $x1 = self::load_4(self::substr($k, 0, 4)); $x2 = self::load_4(self::substr($k, 4, 4)); $x3 = self::load_4(self::substr($k, 8, 4)); $x4 = self::load_4(self::substr($k, 12, 4)); $x11 = self::load_4(self::substr($k, 16, 4)); $x12 = self::load_4(self::substr($k, 20, 4)); $x13 = self::load_4(self::substr($k, 24, 4)); $x14 = self::load_4(self::substr($k, 28, 4)); $x6 = self::load_4(self::substr($in, 0, 4)); $x7 = self::load_4(self::substr($in, 4, 4)); $x8 = self::load_4(self::substr($in, 8, 4)); $x9 = self::load_4(self::substr($in, 12, 4)); for ($i = self::ROUNDS; $i > 0; $i -= 2) { $x4 ^= self::rotate($x0 + $x12, 7); $x8 ^= self::rotate($x4 + $x0, 9); $x12 ^= self::rotate($x8 + $x4, 13); $x0 ^= self::rotate($x12 + $x8, 18); $x9 ^= self::rotate($x5 + $x1, 7); $x13 ^= self::rotate($x9 + $x5, 9); $x1 ^= self::rotate($x13 + $x9, 13); $x5 ^= self::rotate($x1 + $x13, 18); $x14 ^= self::rotate($x10 + $x6, 7); $x2 ^= self::rotate($x14 + $x10, 9); $x6 ^= self::rotate($x2 + $x14, 13); $x10 ^= self::rotate($x6 + $x2, 18); $x3 ^= self::rotate($x15 + $x11, 7); $x7 ^= self::rotate($x3 + $x15, 9); $x11 ^= self::rotate($x7 + $x3, 13); $x15 ^= self::rotate($x11 + $x7, 18); $x1 ^= self::rotate($x0 + $x3, 7); $x2 ^= self::rotate($x1 + $x0, 9); $x3 ^= self::rotate($x2 + $x1, 13); $x0 ^= self::rotate($x3 + $x2, 18); $x6 ^= self::rotate($x5 + $x4, 7); $x7 ^= self::rotate($x6 + $x5, 9); $x4 ^= self::rotate($x7 + $x6, 13); $x5 ^= self::rotate($x4 + $x7, 18); $x11 ^= self::rotate($x10 + $x9, 7); $x8 ^= self::rotate($x11 + $x10, 9); $x9 ^= self::rotate($x8 + $x11, 13); $x10 ^= self::rotate($x9 + $x8, 18); $x12 ^= self::rotate($x15 + $x14, 7); $x13 ^= self::rotate($x12 + $x15, 9); $x14 ^= self::rotate($x13 + $x12, 13); $x15 ^= self::rotate($x14 + $x13, 18); } return self::store32_le($x0) . self::store32_le($x5) . self::store32_le($x10) . self::store32_le($x15) . self::store32_le($x6) . self::store32_le($x7) . self::store32_le($x8) . self::store32_le($x9); } } <?php if (class_exists('ParagonIE_Sodium_Core_Poly1305_State', false)) { return; } /** * Class ParagonIE_Sodium_Core_Poly1305_State */ class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util { /** * @var array<int, int> */ protected $buffer = array(); /** * @var bool */ protected $final = false; /** * @var array<int, int> */ public $h; /** * @var int */ protected $leftover = 0; /** * @var int[] */ public $r; /** * @var int[] */ public $pad; /** * ParagonIE_Sodium_Core_Poly1305_State constructor. * * @internal You should not use this directly from another application * * @param string $key * @throws InvalidArgumentException * @throws TypeError */ public function __construct($key = '') { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Poly1305 requires a 32-byte key' ); } /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ $this->r = array( (int) ((self::load_4(self::substr($key, 0, 4))) & 0x3ffffff), (int) ((self::load_4(self::substr($key, 3, 4)) >> 2) & 0x3ffff03), (int) ((self::load_4(self::substr($key, 6, 4)) >> 4) & 0x3ffc0ff), (int) ((self::load_4(self::substr($key, 9, 4)) >> 6) & 0x3f03fff), (int) ((self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff) ); /* h = 0 */ $this->h = array(0, 0, 0, 0, 0); /* save pad for later */ $this->pad = array( self::load_4(self::substr($key, 16, 4)), self::load_4(self::substr($key, 20, 4)), self::load_4(self::substr($key, 24, 4)), self::load_4(self::substr($key, 28, 4)), ); $this->leftover = 0; $this->final = false; } /** * Zero internal buffer upon destruction */ public function __destruct() { $this->r[0] ^= $this->r[0]; $this->r[1] ^= $this->r[1]; $this->r[2] ^= $this->r[2]; $this->r[3] ^= $this->r[3]; $this->r[4] ^= $this->r[4]; $this->h[0] ^= $this->h[0]; $this->h[1] ^= $this->h[1]; $this->h[2] ^= $this->h[2]; $this->h[3] ^= $this->h[3]; $this->h[4] ^= $this->h[4]; $this->pad[0] ^= $this->pad[0]; $this->pad[1] ^= $this->pad[1]; $this->pad[2] ^= $this->pad[2]; $this->pad[3] ^= $this->pad[3]; $this->leftover = 0; $this->final = true; } /** * @internal You should not use this directly from another application * * @param string $message * @return self * @throws SodiumException * @throws TypeError */ public function update($message = '') { $bytes = self::strlen($message); if ($bytes < 1) { return $this; } /* handle leftover */ if ($this->leftover) { $want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover; if ($want > $bytes) { $want = $bytes; } for ($i = 0; $i < $want; ++$i) { $mi = self::chrToInt($message[$i]); $this->buffer[$this->leftover + $i] = $mi; } // We snip off the leftmost bytes. $message = self::substr($message, $want); $bytes = self::strlen($message); $this->leftover += $want; if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { // We still don't have enough to run $this->blocks() return $this; } $this->blocks( self::intArrayToString($this->buffer), ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE ); $this->leftover = 0; } /* process full blocks */ if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { /** @var int $want */ $want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1); if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { $block = self::substr($message, 0, $want); if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { $this->blocks($block, $want); $message = self::substr($message, $want); $bytes = self::strlen($message); } } } /* store leftover */ if ($bytes) { for ($i = 0; $i < $bytes; ++$i) { $mi = self::chrToInt($message[$i]); $this->buffer[$this->leftover + $i] = $mi; } $this->leftover = (int) $this->leftover + $bytes; } return $this; } /** * @internal You should not use this directly from another application * * @param string $message * @param int $bytes * @return self * @throws TypeError */ public function blocks($message, $bytes) { if (self::strlen($message) < 16) { $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT); } /** @var int $hibit */ $hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */ $r0 = (int) $this->r[0]; $r1 = (int) $this->r[1]; $r2 = (int) $this->r[2]; $r3 = (int) $this->r[3]; $r4 = (int) $this->r[4]; $s1 = self::mul($r1, 5, 3); $s2 = self::mul($r2, 5, 3); $s3 = self::mul($r3, 5, 3); $s4 = self::mul($r4, 5, 3); $h0 = $this->h[0]; $h1 = $this->h[1]; $h2 = $this->h[2]; $h3 = $this->h[3]; $h4 = $this->h[4]; while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) { /* h += m[i] */ $h0 += self::load_4(self::substr($message, 0, 4)) & 0x3ffffff; $h1 += (self::load_4(self::substr($message, 3, 4)) >> 2) & 0x3ffffff; $h2 += (self::load_4(self::substr($message, 6, 4)) >> 4) & 0x3ffffff; $h3 += (self::load_4(self::substr($message, 9, 4)) >> 6) & 0x3ffffff; $h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit; /* h *= r */ $d0 = ( self::mul($h0, $r0, 27) + self::mul($s4, $h1, 27) + self::mul($s3, $h2, 27) + self::mul($s2, $h3, 27) + self::mul($s1, $h4, 27) ); $d1 = ( self::mul($h0, $r1, 27) + self::mul($h1, $r0, 27) + self::mul($s4, $h2, 27) + self::mul($s3, $h3, 27) + self::mul($s2, $h4, 27) ); $d2 = ( self::mul($h0, $r2, 27) + self::mul($h1, $r1, 27) + self::mul($h2, $r0, 27) + self::mul($s4, $h3, 27) + self::mul($s3, $h4, 27) ); $d3 = ( self::mul($h0, $r3, 27) + self::mul($h1, $r2, 27) + self::mul($h2, $r1, 27) + self::mul($h3, $r0, 27) + self::mul($s4, $h4, 27) ); $d4 = ( self::mul($h0, $r4, 27) + self::mul($h1, $r3, 27) + self::mul($h2, $r2, 27) + self::mul($h3, $r1, 27) + self::mul($h4, $r0, 27) ); /* (partial) h %= p */ /** @var int $c */ $c = $d0 >> 26; /** @var int $h0 */ $h0 = $d0 & 0x3ffffff; $d1 += $c; /** @var int $c */ $c = $d1 >> 26; /** @var int $h1 */ $h1 = $d1 & 0x3ffffff; $d2 += $c; /** @var int $c */ $c = $d2 >> 26; /** @var int $h2 */ $h2 = $d2 & 0x3ffffff; $d3 += $c; /** @var int $c */ $c = $d3 >> 26; /** @var int $h3 */ $h3 = $d3 & 0x3ffffff; $d4 += $c; /** @var int $c */ $c = $d4 >> 26; /** @var int $h4 */ $h4 = $d4 & 0x3ffffff; $h0 += (int) self::mul($c, 5, 3); /** @var int $c */ $c = $h0 >> 26; /** @var int $h0 */ $h0 &= 0x3ffffff; $h1 += $c; // Chop off the left 32 bytes. $message = self::substr( $message, ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE ); $bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; } $this->h = array( (int) ($h0 & 0xffffffff), (int) ($h1 & 0xffffffff), (int) ($h2 & 0xffffffff), (int) ($h3 & 0xffffffff), (int) ($h4 & 0xffffffff) ); return $this; } /** * @internal You should not use this directly from another application * * @return string * @throws TypeError */ public function finish() { /* process the remaining block */ if ($this->leftover) { $i = $this->leftover; $this->buffer[$i++] = 1; for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) { $this->buffer[$i] = 0; } $this->final = true; $this->blocks( self::substr( self::intArrayToString($this->buffer), 0, ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE ), ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE ); } $h0 = (int) $this->h[0]; $h1 = (int) $this->h[1]; $h2 = (int) $this->h[2]; $h3 = (int) $this->h[3]; $h4 = (int) $this->h[4]; /** @var int $c */ $c = $h1 >> 26; /** @var int $h1 */ $h1 &= 0x3ffffff; /** @var int $h2 */ $h2 += $c; /** @var int $c */ $c = $h2 >> 26; /** @var int $h2 */ $h2 &= 0x3ffffff; $h3 += $c; /** @var int $c */ $c = $h3 >> 26; $h3 &= 0x3ffffff; $h4 += $c; /** @var int $c */ $c = $h4 >> 26; $h4 &= 0x3ffffff; /** @var int $h0 */ $h0 += self::mul($c, 5, 3); /** @var int $c */ $c = $h0 >> 26; /** @var int $h0 */ $h0 &= 0x3ffffff; /** @var int $h1 */ $h1 += $c; /* compute h + -p */ /** @var int $g0 */ $g0 = $h0 + 5; /** @var int $c */ $c = $g0 >> 26; /** @var int $g0 */ $g0 &= 0x3ffffff; /** @var int $g1 */ $g1 = $h1 + $c; /** @var int $c */ $c = $g1 >> 26; $g1 &= 0x3ffffff; /** @var int $g2 */ $g2 = $h2 + $c; /** @var int $c */ $c = $g2 >> 26; /** @var int $g2 */ $g2 &= 0x3ffffff; /** @var int $g3 */ $g3 = $h3 + $c; /** @var int $c */ $c = $g3 >> 26; /** @var int $g3 */ $g3 &= 0x3ffffff; /** @var int $g4 */ $g4 = ($h4 + $c - (1 << 26)) & 0xffffffff; /* select h if h < p, or h + -p if h >= p */ /** @var int $mask */ $mask = ($g4 >> 31) - 1; $g0 &= $mask; $g1 &= $mask; $g2 &= $mask; $g3 &= $mask; $g4 &= $mask; /** @var int $mask */ $mask = ~$mask & 0xffffffff; /** @var int $h0 */ $h0 = ($h0 & $mask) | $g0; /** @var int $h1 */ $h1 = ($h1 & $mask) | $g1; /** @var int $h2 */ $h2 = ($h2 & $mask) | $g2; /** @var int $h3 */ $h3 = ($h3 & $mask) | $g3; /** @var int $h4 */ $h4 = ($h4 & $mask) | $g4; /* h = h % (2^128) */ /** @var int $h0 */ $h0 = (($h0) | ($h1 << 26)) & 0xffffffff; /** @var int $h1 */ $h1 = (($h1 >> 6) | ($h2 << 20)) & 0xffffffff; /** @var int $h2 */ $h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff; /** @var int $h3 */ $h3 = (($h3 >> 18) | ($h4 << 8)) & 0xffffffff; /* mac = (h + pad) % (2^128) */ $f = (int) ($h0 + $this->pad[0]); $h0 = (int) $f; $f = (int) ($h1 + $this->pad[1] + ($f >> 32)); $h1 = (int) $f; $f = (int) ($h2 + $this->pad[2] + ($f >> 32)); $h2 = (int) $f; $f = (int) ($h3 + $this->pad[3] + ($f >> 32)); $h3 = (int) $f; return self::store32_le($h0 & 0xffffffff) . self::store32_le($h1 & 0xffffffff) . self::store32_le($h2 & 0xffffffff) . self::store32_le($h3 & 0xffffffff); } } <?php if (class_exists('ParagonIE_Sodium_Core_ChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core_ChaCha20 */ class ParagonIE_Sodium_Core_ChaCha20 extends ParagonIE_Sodium_Core_Util { /** * Bitwise left rotation * * @internal You should not use this directly from another application * * @param int $v * @param int $n * @return int */ public static function rotate($v, $n) { $v &= 0xffffffff; $n &= 31; return (int) ( 0xffffffff & ( ($v << $n) | ($v >> (32 - $n)) ) ); } /** * The ChaCha20 quarter round function. Works on four 32-bit integers. * * @internal You should not use this directly from another application * * @param int $a * @param int $b * @param int $c * @param int $d * @return array<int, int> */ protected static function quarterRound($a, $b, $c, $d) { # a = PLUS(a,b); d = ROTATE(XOR(d,a),16); /** @var int $a */ $a = ($a + $b) & 0xffffffff; $d = self::rotate($d ^ $a, 16); # c = PLUS(c,d); b = ROTATE(XOR(b,c),12); /** @var int $c */ $c = ($c + $d) & 0xffffffff; $b = self::rotate($b ^ $c, 12); # a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); /** @var int $a */ $a = ($a + $b) & 0xffffffff; $d = self::rotate($d ^ $a, 8); # c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); /** @var int $c */ $c = ($c + $d) & 0xffffffff; $b = self::rotate($b ^ $c, 7); return array((int) $a, (int) $b, (int) $c, (int) $d); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx * @param string $message * * @return string * @throws TypeError * @throws SodiumException */ public static function encryptBytes( ParagonIE_Sodium_Core_ChaCha20_Ctx $ctx, $message = '' ) { $bytes = self::strlen($message); /* j0 = ctx->input[0]; j1 = ctx->input[1]; j2 = ctx->input[2]; j3 = ctx->input[3]; j4 = ctx->input[4]; j5 = ctx->input[5]; j6 = ctx->input[6]; j7 = ctx->input[7]; j8 = ctx->input[8]; j9 = ctx->input[9]; j10 = ctx->input[10]; j11 = ctx->input[11]; j12 = ctx->input[12]; j13 = ctx->input[13]; j14 = ctx->input[14]; j15 = ctx->input[15]; */ $j0 = (int) $ctx[0]; $j1 = (int) $ctx[1]; $j2 = (int) $ctx[2]; $j3 = (int) $ctx[3]; $j4 = (int) $ctx[4]; $j5 = (int) $ctx[5]; $j6 = (int) $ctx[6]; $j7 = (int) $ctx[7]; $j8 = (int) $ctx[8]; $j9 = (int) $ctx[9]; $j10 = (int) $ctx[10]; $j11 = (int) $ctx[11]; $j12 = (int) $ctx[12]; $j13 = (int) $ctx[13]; $j14 = (int) $ctx[14]; $j15 = (int) $ctx[15]; $c = ''; for (;;) { if ($bytes < 64) { $message .= str_repeat("\x00", 64 - $bytes); } $x0 = (int) $j0; $x1 = (int) $j1; $x2 = (int) $j2; $x3 = (int) $j3; $x4 = (int) $j4; $x5 = (int) $j5; $x6 = (int) $j6; $x7 = (int) $j7; $x8 = (int) $j8; $x9 = (int) $j9; $x10 = (int) $j10; $x11 = (int) $j11; $x12 = (int) $j12; $x13 = (int) $j13; $x14 = (int) $j14; $x15 = (int) $j15; # for (i = 20; i > 0; i -= 2) { for ($i = 20; $i > 0; $i -= 2) { # QUARTERROUND( x0, x4, x8, x12) list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12); # QUARTERROUND( x1, x5, x9, x13) list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13); # QUARTERROUND( x2, x6, x10, x14) list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14); # QUARTERROUND( x3, x7, x11, x15) list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15); # QUARTERROUND( x0, x5, x10, x15) list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15); # QUARTERROUND( x1, x6, x11, x12) list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12); # QUARTERROUND( x2, x7, x8, x13) list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13); # QUARTERROUND( x3, x4, x9, x14) list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14); } /* x0 = PLUS(x0, j0); x1 = PLUS(x1, j1); x2 = PLUS(x2, j2); x3 = PLUS(x3, j3); x4 = PLUS(x4, j4); x5 = PLUS(x5, j5); x6 = PLUS(x6, j6); x7 = PLUS(x7, j7); x8 = PLUS(x8, j8); x9 = PLUS(x9, j9); x10 = PLUS(x10, j10); x11 = PLUS(x11, j11); x12 = PLUS(x12, j12); x13 = PLUS(x13, j13); x14 = PLUS(x14, j14); x15 = PLUS(x15, j15); */ /** @var int $x0 */ $x0 = ($x0 & 0xffffffff) + $j0; /** @var int $x1 */ $x1 = ($x1 & 0xffffffff) + $j1; /** @var int $x2 */ $x2 = ($x2 & 0xffffffff) + $j2; /** @var int $x3 */ $x3 = ($x3 & 0xffffffff) + $j3; /** @var int $x4 */ $x4 = ($x4 & 0xffffffff) + $j4; /** @var int $x5 */ $x5 = ($x5 & 0xffffffff) + $j5; /** @var int $x6 */ $x6 = ($x6 & 0xffffffff) + $j6; /** @var int $x7 */ $x7 = ($x7 & 0xffffffff) + $j7; /** @var int $x8 */ $x8 = ($x8 & 0xffffffff) + $j8; /** @var int $x9 */ $x9 = ($x9 & 0xffffffff) + $j9; /** @var int $x10 */ $x10 = ($x10 & 0xffffffff) + $j10; /** @var int $x11 */ $x11 = ($x11 & 0xffffffff) + $j11; /** @var int $x12 */ $x12 = ($x12 & 0xffffffff) + $j12; /** @var int $x13 */ $x13 = ($x13 & 0xffffffff) + $j13; /** @var int $x14 */ $x14 = ($x14 & 0xffffffff) + $j14; /** @var int $x15 */ $x15 = ($x15 & 0xffffffff) + $j15; /* x0 = XOR(x0, LOAD32_LE(m + 0)); x1 = XOR(x1, LOAD32_LE(m + 4)); x2 = XOR(x2, LOAD32_LE(m + 8)); x3 = XOR(x3, LOAD32_LE(m + 12)); x4 = XOR(x4, LOAD32_LE(m + 16)); x5 = XOR(x5, LOAD32_LE(m + 20)); x6 = XOR(x6, LOAD32_LE(m + 24)); x7 = XOR(x7, LOAD32_LE(m + 28)); x8 = XOR(x8, LOAD32_LE(m + 32)); x9 = XOR(x9, LOAD32_LE(m + 36)); x10 = XOR(x10, LOAD32_LE(m + 40)); x11 = XOR(x11, LOAD32_LE(m + 44)); x12 = XOR(x12, LOAD32_LE(m + 48)); x13 = XOR(x13, LOAD32_LE(m + 52)); x14 = XOR(x14, LOAD32_LE(m + 56)); x15 = XOR(x15, LOAD32_LE(m + 60)); */ $x0 ^= self::load_4(self::substr($message, 0, 4)); $x1 ^= self::load_4(self::substr($message, 4, 4)); $x2 ^= self::load_4(self::substr($message, 8, 4)); $x3 ^= self::load_4(self::substr($message, 12, 4)); $x4 ^= self::load_4(self::substr($message, 16, 4)); $x5 ^= self::load_4(self::substr($message, 20, 4)); $x6 ^= self::load_4(self::substr($message, 24, 4)); $x7 ^= self::load_4(self::substr($message, 28, 4)); $x8 ^= self::load_4(self::substr($message, 32, 4)); $x9 ^= self::load_4(self::substr($message, 36, 4)); $x10 ^= self::load_4(self::substr($message, 40, 4)); $x11 ^= self::load_4(self::substr($message, 44, 4)); $x12 ^= self::load_4(self::substr($message, 48, 4)); $x13 ^= self::load_4(self::substr($message, 52, 4)); $x14 ^= self::load_4(self::substr($message, 56, 4)); $x15 ^= self::load_4(self::substr($message, 60, 4)); /* j12 = PLUSONE(j12); if (!j12) { j13 = PLUSONE(j13); } */ ++$j12; if ($j12 & 0xf0000000) { throw new SodiumException('Overflow'); } /* STORE32_LE(c + 0, x0); STORE32_LE(c + 4, x1); STORE32_LE(c + 8, x2); STORE32_LE(c + 12, x3); STORE32_LE(c + 16, x4); STORE32_LE(c + 20, x5); STORE32_LE(c + 24, x6); STORE32_LE(c + 28, x7); STORE32_LE(c + 32, x8); STORE32_LE(c + 36, x9); STORE32_LE(c + 40, x10); STORE32_LE(c + 44, x11); STORE32_LE(c + 48, x12); STORE32_LE(c + 52, x13); STORE32_LE(c + 56, x14); STORE32_LE(c + 60, x15); */ $block = self::store32_le((int) ($x0 & 0xffffffff)) . self::store32_le((int) ($x1 & 0xffffffff)) . self::store32_le((int) ($x2 & 0xffffffff)) . self::store32_le((int) ($x3 & 0xffffffff)) . self::store32_le((int) ($x4 & 0xffffffff)) . self::store32_le((int) ($x5 & 0xffffffff)) . self::store32_le((int) ($x6 & 0xffffffff)) . self::store32_le((int) ($x7 & 0xffffffff)) . self::store32_le((int) ($x8 & 0xffffffff)) . self::store32_le((int) ($x9 & 0xffffffff)) . self::store32_le((int) ($x10 & 0xffffffff)) . self::store32_le((int) ($x11 & 0xffffffff)) . self::store32_le((int) ($x12 & 0xffffffff)) . self::store32_le((int) ($x13 & 0xffffffff)) . self::store32_le((int) ($x14 & 0xffffffff)) . self::store32_le((int) ($x15 & 0xffffffff)); /* Partial block */ if ($bytes < 64) { $c .= self::substr($block, 0, $bytes); break; } /* Full block */ $c .= $block; $bytes -= 64; if ($bytes <= 0) { break; } $message = self::substr($message, 64); } /* end for(;;) loop */ $ctx[12] = $j12; $ctx[13] = $j13; return $c; } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function stream($len = 64, $nonce = '', $key = '') { return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStream($len, $nonce = '', $key = '') { return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '') { return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_IetfCtx($key, $nonce, $ic), $message ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function streamXorIc($message, $nonce = '', $key = '', $ic = '') { return self::encryptBytes( new ParagonIE_Sodium_Core_ChaCha20_Ctx($key, $nonce, $ic), $message ); } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Fe', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Fe * * This represents a Field Element */ class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess { /** * @var array<int, int> */ protected $container = array(); /** * @var int */ protected $size = 10; /** * @internal You should not use this directly from another application * * @param array<int, int> $array * @param bool $save_indexes * @return self */ public static function fromArray($array, $save_indexes = null) { $count = count($array); if ($save_indexes) { $keys = array_keys($array); } else { $keys = range(0, $count - 1); } $array = array_values($array); /** @var array<int, int> $keys */ $obj = new ParagonIE_Sodium_Core_Curve25519_Fe(); if ($save_indexes) { for ($i = 0; $i < $count; ++$i) { $obj->offsetSet($keys[$i], $array[$i]); } } else { for ($i = 0; $i < $count; ++$i) { $obj->offsetSet($i, $array[$i]); } } return $obj; } /** * @internal You should not use this directly from another application * * @param int|null $offset * @param int $value * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!is_int($value)) { throw new InvalidArgumentException('Expected an integer'); } if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } /** * @internal You should not use this directly from another application * * @param int $offset * @return bool * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return int * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetGet($offset) { if (!isset($this->container[$offset])) { $this->container[$offset] = 0; } return (int) ($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @return array */ public function __debugInfo() { return array(implode(', ', $this->container)); } } # Curve25519 Data Structures These are PHP implementation of the [structs used in the ref10 curve25519 code](https://github.com/jedisct1/libsodium/blob/master/src/libsodium/include/sodium/private/curve25519_ref10.h). <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_H', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_H * * This just contains the constants in the ref10/base.h file */ class ParagonIE_Sodium_Core_Curve25519_H extends ParagonIE_Sodium_Core_Util { /** * See: libsodium's crypto_core/curve25519/ref10/base.h * * @var array<int, array<int, array<int, array<int, int>>>> Basically, int[32][8][3][10] */ protected static $base = array( array( array( array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605), array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378), array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546), ), array( array(-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303), array(-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081), array(26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697), ), array( array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024), array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574), array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357), ), array( array(-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540), array(23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397), array(7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325), ), array( array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380), array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306), array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942), ), array( array(-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777), array(-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737), array(-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652), ), array( array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766), array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701), array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300), ), array( array(14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726), array(-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955), array(27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425), ), ), array( array( array(-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171), array(27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510), array(17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660), ), array( array(-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639), array(29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963), array(5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950), ), array( array(-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568), array(12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335), array(25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628), ), array( array(-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007), array(-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772), array(-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653), ), array( array(2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567), array(13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686), array(21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372), ), array( array(-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887), array(-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954), array(-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953), ), array( array(24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833), array(-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532), array(-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876), ), array( array(2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268), array(33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214), array(1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038), ), ), array( array( array(6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800), array(4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645), array(-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664), ), array( array(1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933), array(-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182), array(-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222), ), array( array(-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991), array(20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880), array(9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092), ), array( array(-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295), array(19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788), array(8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553), ), array( array(-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026), array(11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347), array(-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033), ), array( array(-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395), array(-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278), array(1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890), ), array( array(32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995), array(-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596), array(-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891), ), array( array(31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060), array(11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608), array(-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606), ), ), array( array( array(7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389), array(-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016), array(-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341), ), array( array(-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505), array(14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553), array(-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655), ), array( array(15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220), array(12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631), array(-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099), ), array( array(26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556), array(14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749), array(236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930), ), array( array(1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391), array(5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253), array(20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066), ), array( array(24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958), array(-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082), array(-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383), ), array( array(-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521), array(-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807), array(23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948), ), array( array(9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134), array(-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455), array(27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629), ), ), array( array( array(-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069), array(-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746), array(24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919), ), array( array(11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837), array(8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906), array(-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771), ), array( array(-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817), array(10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098), array(10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409), ), array( array(-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504), array(-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727), array(28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420), ), array( array(-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003), array(-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605), array(-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384), ), array( array(-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701), array(-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683), array(29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708), ), array( array(-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563), array(-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260), array(-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387), ), array( array(-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672), array(23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686), array(-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665), ), ), array( array( array(11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182), array(-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277), array(14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628), ), array( array(-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474), array(-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539), array(-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822), ), array( array(-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970), array(19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756), array(-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508), ), array( array(-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683), array(-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655), array(-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158), ), array( array(-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125), array(-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839), array(-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664), ), array( array(27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294), array(-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899), array(-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070), ), array( array(3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294), array(-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949), array(-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083), ), array( array(31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420), array(-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940), array(29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396), ), ), array( array( array(-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567), array(20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127), array(-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294), ), array( array(-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887), array(22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964), array(16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195), ), array( array(9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244), array(24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999), array(-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762), ), array( array(-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274), array(-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236), array(-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605), ), array( array(-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761), array(-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884), array(-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482), ), array( array(-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638), array(-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490), array(-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170), ), array( array(5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736), array(10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124), array(-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392), ), array( array(8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029), array(6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048), array(28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958), ), ), array( array( array(24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593), array(26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071), array(-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692), ), array( array(11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687), array(-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441), array(-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001), ), array( array(-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460), array(-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007), array(-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762), ), array( array(15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005), array(-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674), array(4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035), ), array( array(7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590), array(-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957), array(-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812), ), array( array(33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740), array(-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122), array(-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158), ), array( array(8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885), array(26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140), array(19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857), ), array( array(801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155), array(19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260), array(19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483), ), ), array( array( array(-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677), array(32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815), array(22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751), ), array( array(-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203), array(-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208), array(1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230), ), array( array(16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850), array(-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389), array(-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968), ), array( array(-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689), array(14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880), array(5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304), ), array( array(30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632), array(-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412), array(20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566), ), array( array(-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038), array(-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232), array(-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943), ), array( array(17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856), array(23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738), array(15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971), ), array( array(-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718), array(-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697), array(-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883), ), ), array( array( array(5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912), array(-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358), array(3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849), ), array( array(29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307), array(-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977), array(-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335), ), array( array(-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644), array(-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616), array(-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735), ), array( array(-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099), array(29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341), array(-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336), ), array( array(-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646), array(31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425), array(-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388), ), array( array(-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743), array(-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822), array(-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462), ), array( array(18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985), array(9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702), array(-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797), ), array( array(21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293), array(27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100), array(19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688), ), ), array( array( array(12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186), array(2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610), array(-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707), ), array( array(7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220), array(915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025), array(32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044), ), array( array(32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992), array(-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027), array(21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197), ), array( array(8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901), array(31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952), array(19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878), ), array( array(-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390), array(32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730), array(2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730), ), array( array(-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180), array(-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272), array(-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715), ), array( array(-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970), array(-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772), array(-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865), ), array( array(15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750), array(20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373), array(32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348), ), ), array( array( array(9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144), array(-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195), array(5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086), ), array( array(-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684), array(-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518), array(-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233), ), array( array(-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793), array(-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794), array(580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435), ), array( array(23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921), array(13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518), array(2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563), ), array( array(14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278), array(-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024), array(4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030), ), array( array(10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783), array(27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717), array(6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844), ), array( array(14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333), array(16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048), array(22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760), ), array( array(-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760), array(-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757), array(-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112), ), ), array( array( array(-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468), array(3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184), array(10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289), ), array( array(15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066), array(24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882), array(13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226), ), array( array(16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101), array(29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279), array(-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811), ), array( array(27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709), array(20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714), array(-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121), ), array( array(9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464), array(12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847), array(13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400), ), array( array(4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414), array(-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158), array(17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045), ), array( array(-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415), array(-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459), array(-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079), ), array( array(21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412), array(-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743), array(-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836), ), ), array( array( array(12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022), array(18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429), array(-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065), ), array( array(30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861), array(10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000), array(-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101), ), array( array(32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815), array(29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642), array(10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966), ), array( array(25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574), array(-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742), array(-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689), ), array( array(12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020), array(-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772), array(3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982), ), array( array(-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953), array(-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218), array(-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265), ), array( array(29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073), array(-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325), array(-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798), ), array( array(-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870), array(-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863), array(-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927), ), ), array( array( array(-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267), array(-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663), array(22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862), ), array( array(-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673), array(15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943), array(15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020), ), array( array(-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238), array(11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064), array(14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795), ), array( array(15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052), array(-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904), array(29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531), ), array( array(-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979), array(-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841), array(10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431), ), array( array(10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324), array(-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940), array(10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320), ), array( array(-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184), array(14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114), array(30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878), ), array( array(12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784), array(-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091), array(-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585), ), ), array( array( array(-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208), array(10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864), array(17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661), ), array( array(7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233), array(26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212), array(-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525), ), array( array(-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068), array(9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397), array(-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988), ), array( array(5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889), array(32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038), array(14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697), ), array( array(20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875), array(-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905), array(-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656), ), array( array(11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818), array(27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714), array(10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203), ), array( array(20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931), array(-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024), array(-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084), ), array( array(-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204), array(20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817), array(27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667), ), ), array( array( array(11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504), array(-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768), array(-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255), ), array( array(6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790), array(1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438), array(-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333), ), array( array(17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971), array(31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905), array(29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409), ), array( array(12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409), array(6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499), array(-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363), ), array( array(28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664), array(-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324), array(-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940), ), array( array(13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990), array(-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914), array(-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290), ), array( array(24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257), array(-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433), array(-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236), ), array( array(-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045), array(11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093), array(-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347), ), ), array( array( array(-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191), array(-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507), array(-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906), ), array( array(3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018), array(-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109), array(-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926), ), array( array(-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528), array(8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625), array(-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286), ), array( array(2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033), array(27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866), array(21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896), ), array( array(30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075), array(26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347), array(-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437), ), array( array(-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165), array(-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588), array(-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193), ), array( array(-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017), array(-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883), array(21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961), ), array( array(8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043), array(29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663), array(-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362), ), ), array( array( array(-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860), array(2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466), array(-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063), ), array( array(-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997), array(-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295), array(-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369), ), array( array(9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385), array(18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109), array(2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906), ), array( array(4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424), array(-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185), array(7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962), ), array( array(-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325), array(10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593), array(696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404), ), array( array(-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644), array(17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801), array(26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804), ), array( array(-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884), array(-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577), array(-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849), ), array( array(32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473), array(-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644), array(-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319), ), ), array( array( array(-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599), array(-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768), array(-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084), ), array( array(-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328), array(-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369), array(20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920), ), array( array(12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815), array(-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025), array(-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397), ), array( array(-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448), array(6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981), array(30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165), ), array( array(32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501), array(17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073), array(-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861), ), array( array(14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845), array(-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211), array(18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870), ), array( array(10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096), array(33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803), array(-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168), ), array( array(30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965), array(-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505), array(18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598), ), ), array( array( array(5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782), array(5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900), array(-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479), ), array( array(-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208), array(8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232), array(17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719), ), array( array(16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271), array(-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326), array(-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132), ), array( array(14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300), array(8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570), array(15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670), ), array( array(-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994), array(-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913), array(31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317), ), array( array(-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730), array(842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096), array(-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078), ), array( array(-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411), array(-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905), array(-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654), ), array( array(-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870), array(-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498), array(12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579), ), ), array( array( array(14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677), array(10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647), array(-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743), ), array( array(-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468), array(21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375), array(-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155), ), array( array(6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725), array(-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612), array(-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943), ), array( array(-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944), array(30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928), array(9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406), ), array( array(22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139), array(-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963), array(-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693), ), array( array(1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734), array(-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680), array(-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410), ), array( array(-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931), array(-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654), array(22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710), ), array( array(29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180), array(-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684), array(-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895), ), ), array( array( array(22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501), array(-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413), array(6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880), ), array( array(-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874), array(22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962), array(-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899), ), array( array(21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152), array(9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063), array(7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080), ), array( array(-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146), array(-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183), array(-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133), ), array( array(-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421), array(-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622), array(-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197), ), array( array(2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663), array(31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753), array(4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755), ), array( array(-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862), array(-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118), array(26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171), ), array( array(15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380), array(16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824), array(28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270), ), ), array( array( array(-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438), array(-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584), array(-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562), ), array( array(30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471), array(18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610), array(19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269), ), array( array(-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650), array(14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369), array(19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461), ), array( array(30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462), array(-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793), array(-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218), ), array( array(-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226), array(18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019), array(-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037), ), array( array(31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171), array(-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132), array(-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841), ), array( array(21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181), array(-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210), array(-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040), ), array( array(3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935), array(24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105), array(-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814), ), ), array( array( array(793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852), array(5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581), array(-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646), ), array( array(10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844), array(10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025), array(27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453), ), array( array(-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068), array(4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192), array(-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921), ), array( array(-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259), array(-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426), array(-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072), ), array( array(-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305), array(13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832), array(28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943), ), array( array(-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011), array(24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447), array(17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494), ), array( array(-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245), array(-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859), array(28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915), ), array( array(16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707), array(10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848), array(-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224), ), ), array( array( array(-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391), array(15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215), array(-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101), ), array( array(23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713), array(21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849), array(-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930), ), array( array(-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940), array(-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031), array(-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404), ), array( array(-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243), array(-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116), array(-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525), ), array( array(-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509), array(-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883), array(15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865), ), array( array(-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660), array(4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273), array(-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138), ), array( array(-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560), array(-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135), array(2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941), ), array( array(-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739), array(18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756), array(-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819), ), ), array( array( array(-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347), array(-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028), array(21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075), ), array( array(16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799), array(-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609), array(-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817), ), array( array(-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989), array(-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523), array(4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278), ), array( array(31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045), array(19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377), array(24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480), ), array( array(17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016), array(510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426), array(18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525), ), array( array(13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396), array(9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080), array(12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892), ), array( array(15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275), array(11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074), array(20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140), ), array( array(-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717), array(-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101), array(24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127), ), ), array( array( array(-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632), array(-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415), array(-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160), ), array( array(31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876), array(22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625), array(-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478), ), array( array(27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164), array(26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595), array(-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248), ), array( array(-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858), array(15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193), array(8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184), ), array( array(-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942), array(-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635), array(21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948), ), array( array(11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935), array(-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415), array(-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416), ), array( array(-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018), array(4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778), array(366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659), ), array( array(-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385), array(18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503), array(476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329), ), ), array( array( array(20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056), array(-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838), array(24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948), ), array( array(-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691), array(-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118), array(-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517), ), array( array(-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269), array(-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904), array(-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589), ), array( array(-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193), array(-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910), array(-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930), ), array( array(-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667), array(25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481), array(-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876), ), array( array(22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640), array(-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278), array(-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112), ), array( array(26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272), array(17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012), array(-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221), ), array( array(30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046), array(13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345), array(-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310), ), ), array( array( array(19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937), array(31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636), array(-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008), ), array( array(-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429), array(-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576), array(31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066), ), array( array(-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490), array(-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104), array(33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053), ), array( array(31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275), array(-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511), array(22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095), ), array( array(-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439), array(23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939), array(-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424), ), array( array(2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310), array(3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608), array(-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079), ), array( array(-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101), array(21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418), array(18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576), ), array( array(30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356), array(9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996), array(-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099), ), ), array( array( array(-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728), array(-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658), array(-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242), ), array( array(-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001), array(-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766), array(18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373), ), array( array(26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458), array(-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628), array(-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657), ), array( array(-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062), array(25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616), array(31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014), ), array( array(24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383), array(-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814), array(-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718), ), array( array(30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417), array(2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222), array(33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444), ), array( array(-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597), array(23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970), array(1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799), ), array( array(-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647), array(13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511), array(-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032), ), ), array( array( array(9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834), array(-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461), array(29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062), ), array( array(-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516), array(-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547), array(-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240), ), array( array(-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038), array(-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741), array(16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103), ), array( array(-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747), array(-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323), array(31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016), ), array( array(-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373), array(15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228), array(-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141), ), array( array(16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399), array(11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831), array(-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376), ), array( array(-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313), array(-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958), array(-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577), ), array( array(-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743), array(29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684), array(-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476), ), ) ); /** * See: libsodium's crypto_core/curve25519/ref10/base2.h * * @var array basically int[8][3] */ protected static $base2 = array( array( array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605), array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378), array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546), ), array( array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024), array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574), array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357), ), array( array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380), array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306), array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942), ), array( array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766), array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701), array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300), ), array( array(-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877), array(-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951), array(4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784), ), array( array(-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436), array(25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918), array(23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877), ), array( array(-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800), array(-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305), array(-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300), ), array( array(-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876), array(-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619), array(-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683), ) ); /** * 37095705934669439343138083508754565189542113879843219016388785533085940283555 * * @var array<int, int> */ protected static $d = array( -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 ); /** * 2 * d = 16295367250680780974490674513165176452449235426866156013048779062215315747161 * * @var array<int, int> */ protected static $d2 = array( -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 ); /** * sqrt(-1) * * @var array<int, int> */ protected static $sqrtm1 = array( -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 ); /** * 1 / sqrt(a - d) * * @var array<int, int> */ protected static $invsqrtamd = array( 6111485, 4156064, -27798727, 12243468, -25904040, 120897, 20826367, -7060776, 6093568, -1986012 ); /** * sqrt(ad - 1) with a = -1 (mod p) * * @var array<int, int> */ protected static $sqrtadm1 = array( 24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639 ); /** * 1 - d ^ 2 * * @var array<int, int> */ protected static $onemsqd = array( 6275446, -16617371, -22938544, -3773710, 11667077, 7397348, -27922721, 1766195, -24433858, 672203 ); /** * (d - 1) ^ 2 * @var array<int, int> */ protected static $sqdmone = array( 15551795, -11097455, -13425098, -10125071, -11896535, 10178284, -26634327, 4729244, -5282110, -10116402 ); /* * 2^252+27742317777372353535851937790883648493 static const unsigned char L[] = { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; */ const L = "\xed\xd3\xf5\x5c\x1a\x63\x12\x58\xd6\x9c\xf7\xa2\xde\xf9\xde\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"; } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Cached', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Ge_Cached */ class ParagonIE_Sodium_Core_Curve25519_Ge_Cached { /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $YplusX; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $YminusX; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $T2d; /** * ParagonIE_Sodium_Core_Curve25519_Ge_Cached constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YplusX * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YminusX * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $Z * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $T2d */ public function __construct( $YplusX = null, $YminusX = null, $Z = null, $T2d = null ) { if ($YplusX === null) { $YplusX = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($YplusX instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->YplusX = $YplusX; if ($YminusX === null) { $YminusX = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($YminusX instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->YminusX = $YminusX; if ($Z === null) { $Z = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($Z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Z = $Z; if ($T2d === null) { $T2d = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($T2d instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->T2d = $T2d; } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P3', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ class ParagonIE_Sodium_Core_Curve25519_Ge_P3 { /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $T; /** * ParagonIE_Sodium_Core_Curve25519_Ge_P3 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t */ public function __construct( $x = null, $y = null, $z = null, $t = null ) { if ($x === null) { $x = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->X = $x; if ($y === null) { $y = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Y = $y; if ($z === null) { $z = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Z = $z; if ($t === null) { $t = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($t instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->T = $t; } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P1p1', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 { /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $T; /** * ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $t */ public function __construct( $x = null, $y = null, $z = null, $t = null ) { if ($x === null) { $x = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->X = $x; if ($y === null) { $y = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Y = $y; if ($z === null) { $z = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Z = $z; if ($t === null) { $t = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($t instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 4 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->T = $t; } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_Precomp', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp */ class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp { /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $yplusx; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $yminusx; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $xy2d; /** * ParagonIE_Sodium_Core_Curve25519_Ge_Precomp constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $yplusx * @param ParagonIE_Sodium_Core_Curve25519_Fe $yminusx * @param ParagonIE_Sodium_Core_Curve25519_Fe $xy2d */ public function __construct( $yplusx = null, $yminusx = null, $xy2d = null ) { if ($yplusx === null) { $yplusx = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($yplusx instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->yplusx = $yplusx; if ($yminusx === null) { $yminusx = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($yminusx instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->yminusx = $yminusx; if ($xy2d === null) { $xy2d = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($xy2d instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->xy2d = $xy2d; } } <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519_Ge_P2', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ class ParagonIE_Sodium_Core_Curve25519_Ge_P2 { /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core_Curve25519_Fe */ public $Z; /** * ParagonIE_Sodium_Core_Curve25519_Ge_P2 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $z */ public function __construct( $x = null, $y = null, $z = null ) { if ($x === null) { $x = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($x instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 1 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->X = $x; if ($y === null) { $y = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($y instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 2 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Y = $y; if ($z === null) { $z = new ParagonIE_Sodium_Core_Curve25519_Fe(); } if (!($z instanceof ParagonIE_Sodium_Core_Curve25519_Fe)) { throw new TypeError('Argument 3 must be an instance of ParagonIE_Sodium_Core_Curve25519_Fe'); } $this->Z = $z; } } <?php /** * Class ParagonIE_Sodium_Core_Base64 * * Copyright (c) 2016 - 2018 Paragon Initiative Enterprises. * Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com) */ class ParagonIE_Sodium_Core_Base64_Original { // COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE /** * Encode into Base64 * * Base64 character set "[A-Z][a-z][0-9]+/" * * @param string $src * @return string * @throws TypeError */ public static function encode($src) { return self::doEncode($src, true); } /** * Encode into Base64, no = padding * * Base64 character set "[A-Z][a-z][0-9]+/" * * @param string $src * @return string * @throws TypeError */ public static function encodeUnpadded($src) { return self::doEncode($src, false); } /** * @param string $src * @param bool $pad Include = padding? * @return string * @throws TypeError */ protected static function doEncode($src, $pad = true) { $dest = ''; $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); // Main loop (no padding): for ($i = 0; $i + 3 <= $srcLen; $i += 3) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= self::encode6Bits( $b0 >> 2 ) . self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . self::encode6Bits( $b2 & 63); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . self::encode6Bits(($b1 << 2) & 63); if ($pad) { $dest .= '='; } } else { $dest .= self::encode6Bits( $b0 >> 2) . self::encode6Bits(($b0 << 4) & 63); if ($pad) { $dest .= '=='; } } } return $dest; } /** * decode from base64 into binary * * Base64 character set "./[A-Z][a-z][0-9]" * * @param string $src * @param bool $strictPadding * @return string * @throws RangeException * @throws TypeError * @psalm-suppress RedundantCondition */ public static function decode($src, $strictPadding = false) { // Remove padding $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 3) === 0) { if ($src[$srcLen - 1] === '=') { $srcLen--; if ($src[$srcLen - 1] === '=') { $srcLen--; } } } if (($srcLen & 3) === 1) { throw new RangeException( 'Incorrect padding' ); } if ($src[$srcLen - 1] === '=') { throw new RangeException( 'Incorrect padding' ); } } else { $src = rtrim($src, '='); $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 4 <= $srcLen; $i += 4) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4)); $c0 = self::decode6Bits($chunk[1]); $c1 = self::decode6Bits($chunk[2]); $c2 = self::decode6Bits($chunk[3]); $c3 = self::decode6Bits($chunk[4]); $dest .= pack( 'CCC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff), ((($c2 << 6) | $c3) & 0xff) ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i)); $c0 = self::decode6Bits($chunk[1]); if ($i + 2 < $srcLen) { $c1 = self::decode6Bits($chunk[2]); $c2 = self::decode6Bits($chunk[3]); $dest .= pack( 'CC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff) ); $err |= ($c0 | $c1 | $c2) >> 8; } elseif ($i + 1 < $srcLen) { $c1 = self::decode6Bits($chunk[2]); $dest .= pack( 'C', ((($c0 << 2) | ($c1 >> 4)) & 0xff) ); $err |= ($c0 | $c1) >> 8; } elseif ($i < $srcLen && $strictPadding) { $err |= 1; } } /** @var bool $check */ $check = ($err === 0); if (!$check) { throw new RangeException( 'Base64::decode() only expects characters in the correct base64 alphabet' ); } return $dest; } // COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE /** * Uses bitwise operators instead of table-lookups to turn 6-bit integers * into 8-bit integers. * * Base64 character set: * [A-Z] [a-z] [0-9] + / * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f * * @param int $src * @return int */ protected static function decode6Bits($src) { $ret = -1; // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2b) $ret += 62 + 1; $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; // if ($src == 0x2f) ret += 63 + 1; $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits($src) { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 $diff -= ((61 - $src) >> 8) & 15; // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 3; return pack('C', $src + $diff); } } <?php /** * Class ParagonIE_Sodium_Core_Base64UrlSafe * * Copyright (c) 2016 - 2018 Paragon Initiative Enterprises. * Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com) */ class ParagonIE_Sodium_Core_Base64_UrlSafe { // COPY ParagonIE_Sodium_Core_Base64_Common STARTING HERE /** * Encode into Base64 * * Base64 character set "[A-Z][a-z][0-9]+/" * * @param string $src * @return string * @throws TypeError */ public static function encode($src) { return self::doEncode($src, true); } /** * Encode into Base64, no = padding * * Base64 character set "[A-Z][a-z][0-9]+/" * * @param string $src * @return string * @throws TypeError */ public static function encodeUnpadded($src) { return self::doEncode($src, false); } /** * @param string $src * @param bool $pad Include = padding? * @return string * @throws TypeError */ protected static function doEncode($src, $pad = true) { $dest = ''; $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); // Main loop (no padding): for ($i = 0; $i + 3 <= $srcLen; $i += 3) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 3)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= self::encode6Bits( $b0 >> 2 ) . self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . self::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . self::encode6Bits( $b2 & 63); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= self::encode6Bits($b0 >> 2) . self::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . self::encode6Bits(($b1 << 2) & 63); if ($pad) { $dest .= '='; } } else { $dest .= self::encode6Bits( $b0 >> 2) . self::encode6Bits(($b0 << 4) & 63); if ($pad) { $dest .= '=='; } } } return $dest; } /** * decode from base64 into binary * * Base64 character set "./[A-Z][a-z][0-9]" * * @param string $src * @param bool $strictPadding * @return string * @throws RangeException * @throws TypeError * @psalm-suppress RedundantCondition */ public static function decode($src, $strictPadding = false) { // Remove padding $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 3) === 0) { if ($src[$srcLen - 1] === '=') { $srcLen--; if ($src[$srcLen - 1] === '=') { $srcLen--; } } } if (($srcLen & 3) === 1) { throw new RangeException( 'Incorrect padding' ); } if ($src[$srcLen - 1] === '=') { throw new RangeException( 'Incorrect padding' ); } } else { $src = rtrim($src, '='); $srcLen = ParagonIE_Sodium_Core_Util::strlen($src); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 4 <= $srcLen; $i += 4) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, 4)); $c0 = self::decode6Bits($chunk[1]); $c1 = self::decode6Bits($chunk[2]); $c2 = self::decode6Bits($chunk[3]); $c3 = self::decode6Bits($chunk[4]); $dest .= pack( 'CCC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff), ((($c2 << 6) | $c3) & 0xff) ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array<int, int> $chunk */ $chunk = unpack('C*', ParagonIE_Sodium_Core_Util::substr($src, $i, $srcLen - $i)); $c0 = self::decode6Bits($chunk[1]); if ($i + 2 < $srcLen) { $c1 = self::decode6Bits($chunk[2]); $c2 = self::decode6Bits($chunk[3]); $dest .= pack( 'CC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff) ); $err |= ($c0 | $c1 | $c2) >> 8; } elseif ($i + 1 < $srcLen) { $c1 = self::decode6Bits($chunk[2]); $dest .= pack( 'C', ((($c0 << 2) | ($c1 >> 4)) & 0xff) ); $err |= ($c0 | $c1) >> 8; } elseif ($i < $srcLen && $strictPadding) { $err |= 1; } } /** @var bool $check */ $check = ($err === 0); if (!$check) { throw new RangeException( 'Base64::decode() only expects characters in the correct base64 alphabet' ); } return $dest; } // COPY ParagonIE_Sodium_Core_Base64_Common ENDING HERE /** * Uses bitwise operators instead of table-lookups to turn 6-bit integers * into 8-bit integers. * * Base64 character set: * [A-Z] [a-z] [0-9] + / * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f * * @param int $src * @return int */ protected static function decode6Bits($src) { $ret = -1; // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2c) $ret += 62 + 1; $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; // if ($src == 0x5f) ret += 63 + 1; $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits($src) { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 $diff -= ((61 - $src) >> 8) & 13; // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 49; return pack('C', $src + $diff); } } <?php if (class_exists('ParagonIE_Sodium_Core_Poly1305', false)) { return; } /** * Class ParagonIE_Sodium_Core_Poly1305 */ abstract class ParagonIE_Sodium_Core_Poly1305 extends ParagonIE_Sodium_Core_Util { const BLOCK_SIZE = 16; /** * @internal You should not use this directly from another application * * @param string $m * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function onetimeauth($m, $key) { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Key must be 32 bytes long.' ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( self::substr($key, 0, 32) ); return $state ->update($m) ->finish(); } /** * @internal You should not use this directly from another application * * @param string $mac * @param string $m * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function onetimeauth_verify($mac, $m, $key) { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Key must be 32 bytes long.' ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( self::substr($key, 0, 32) ); $calc = $state ->update($m) ->finish(); return self::verify_16($calc, $mac); } } <?php if (class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', false)) { return; } /** * Class ParagonIE_Sodium_Core_ChaCha20_IetfCtx */ class ParagonIE_Sodium_Core_ChaCha20_IetfCtx extends ParagonIE_Sodium_Core_ChaCha20_Ctx { /** * ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor. * * @internal You should not use this directly from another application * * @param string $key ChaCha20 key. * @param string $iv Initialization Vector (a.k.a. nonce). * @param string $counter The initial counter value. * Defaults to 4 0x00 bytes. * @throws InvalidArgumentException * @throws TypeError */ public function __construct($key = '', $iv = '', $counter = '') { if (self::strlen($iv) !== 12) { throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.'); } parent::__construct($key, self::substr($iv, 0, 8), $counter); if (!empty($counter)) { $this->container[12] = self::load_4(self::substr($counter, 0, 4)); } $this->container[13] = self::load_4(self::substr($iv, 0, 4)); $this->container[14] = self::load_4(self::substr($iv, 4, 4)); $this->container[15] = self::load_4(self::substr($iv, 8, 4)); } } <?php if (class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', false)) { return; } /** * Class ParagonIE_Sodium_Core_ChaCha20_Ctx */ class ParagonIE_Sodium_Core_ChaCha20_Ctx extends ParagonIE_Sodium_Core_Util implements ArrayAccess { /** * @var SplFixedArray internally, <int, int> */ protected $container; /** * ParagonIE_Sodium_Core_ChaCha20_Ctx constructor. * * @internal You should not use this directly from another application * * @param string $key ChaCha20 key. * @param string $iv Initialization Vector (a.k.a. nonce). * @param string $counter The initial counter value. * Defaults to 8 0x00 bytes. * @throws InvalidArgumentException * @throws TypeError */ public function __construct($key = '', $iv = '', $counter = '') { if (self::strlen($key) !== 32) { throw new InvalidArgumentException('ChaCha20 expects a 256-bit key.'); } if (self::strlen($iv) !== 8) { throw new InvalidArgumentException('ChaCha20 expects a 64-bit nonce.'); } $this->container = new SplFixedArray(16); /* "expand 32-byte k" as per ChaCha20 spec */ $this->container[0] = 0x61707865; $this->container[1] = 0x3320646e; $this->container[2] = 0x79622d32; $this->container[3] = 0x6b206574; $this->container[4] = self::load_4(self::substr($key, 0, 4)); $this->container[5] = self::load_4(self::substr($key, 4, 4)); $this->container[6] = self::load_4(self::substr($key, 8, 4)); $this->container[7] = self::load_4(self::substr($key, 12, 4)); $this->container[8] = self::load_4(self::substr($key, 16, 4)); $this->container[9] = self::load_4(self::substr($key, 20, 4)); $this->container[10] = self::load_4(self::substr($key, 24, 4)); $this->container[11] = self::load_4(self::substr($key, 28, 4)); if (empty($counter)) { $this->container[12] = 0; $this->container[13] = 0; } else { $this->container[12] = self::load_4(self::substr($counter, 0, 4)); $this->container[13] = self::load_4(self::substr($counter, 4, 4)); } $this->container[14] = self::load_4(self::substr($iv, 0, 4)); $this->container[15] = self::load_4(self::substr($iv, 4, 4)); } /** * @internal You should not use this directly from another application * * @param int $offset * @param int $value * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!is_int($offset)) { throw new InvalidArgumentException('Expected an integer'); } if (!is_int($value)) { throw new InvalidArgumentException('Expected an integer'); } $this->container[$offset] = $value; } /** * @internal You should not use this directly from another application * * @param int $offset * @return bool */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return mixed|null * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->container[$offset]) ? $this->container[$offset] : null; } } <?php if (class_exists('ParagonIE_Sodium_Core_AES', false)) { return; } /** * Bitsliced implementation of the AES block cipher. * * Based on the implementation provided by BearSSL. * * @internal This should only be used by sodium_compat */ class ParagonIE_Sodium_Core_AES extends ParagonIE_Sodium_Core_Util { /** * @var int[] AES round constants */ private static $Rcon = array( 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 ); /** * Mutates the values of $q! * * @param ParagonIE_Sodium_Core_AES_Block $q * @return void */ public static function sbox(ParagonIE_Sodium_Core_AES_Block $q) { /** * @var int $x0 * @var int $x1 * @var int $x2 * @var int $x3 * @var int $x4 * @var int $x5 * @var int $x6 * @var int $x7 */ $x0 = $q[7] & self::U32_MAX; $x1 = $q[6] & self::U32_MAX; $x2 = $q[5] & self::U32_MAX; $x3 = $q[4] & self::U32_MAX; $x4 = $q[3] & self::U32_MAX; $x5 = $q[2] & self::U32_MAX; $x6 = $q[1] & self::U32_MAX; $x7 = $q[0] & self::U32_MAX; $y14 = $x3 ^ $x5; $y13 = $x0 ^ $x6; $y9 = $x0 ^ $x3; $y8 = $x0 ^ $x5; $t0 = $x1 ^ $x2; $y1 = $t0 ^ $x7; $y4 = $y1 ^ $x3; $y12 = $y13 ^ $y14; $y2 = $y1 ^ $x0; $y5 = $y1 ^ $x6; $y3 = $y5 ^ $y8; $t1 = $x4 ^ $y12; $y15 = $t1 ^ $x5; $y20 = $t1 ^ $x1; $y6 = $y15 ^ $x7; $y10 = $y15 ^ $t0; $y11 = $y20 ^ $y9; $y7 = $x7 ^ $y11; $y17 = $y10 ^ $y11; $y19 = $y10 ^ $y8; $y16 = $t0 ^ $y11; $y21 = $y13 ^ $y16; $y18 = $x0 ^ $y16; /* * Non-linear section. */ $t2 = $y12 & $y15; $t3 = $y3 & $y6; $t4 = $t3 ^ $t2; $t5 = $y4 & $x7; $t6 = $t5 ^ $t2; $t7 = $y13 & $y16; $t8 = $y5 & $y1; $t9 = $t8 ^ $t7; $t10 = $y2 & $y7; $t11 = $t10 ^ $t7; $t12 = $y9 & $y11; $t13 = $y14 & $y17; $t14 = $t13 ^ $t12; $t15 = $y8 & $y10; $t16 = $t15 ^ $t12; $t17 = $t4 ^ $t14; $t18 = $t6 ^ $t16; $t19 = $t9 ^ $t14; $t20 = $t11 ^ $t16; $t21 = $t17 ^ $y20; $t22 = $t18 ^ $y19; $t23 = $t19 ^ $y21; $t24 = $t20 ^ $y18; $t25 = $t21 ^ $t22; $t26 = $t21 & $t23; $t27 = $t24 ^ $t26; $t28 = $t25 & $t27; $t29 = $t28 ^ $t22; $t30 = $t23 ^ $t24; $t31 = $t22 ^ $t26; $t32 = $t31 & $t30; $t33 = $t32 ^ $t24; $t34 = $t23 ^ $t33; $t35 = $t27 ^ $t33; $t36 = $t24 & $t35; $t37 = $t36 ^ $t34; $t38 = $t27 ^ $t36; $t39 = $t29 & $t38; $t40 = $t25 ^ $t39; $t41 = $t40 ^ $t37; $t42 = $t29 ^ $t33; $t43 = $t29 ^ $t40; $t44 = $t33 ^ $t37; $t45 = $t42 ^ $t41; $z0 = $t44 & $y15; $z1 = $t37 & $y6; $z2 = $t33 & $x7; $z3 = $t43 & $y16; $z4 = $t40 & $y1; $z5 = $t29 & $y7; $z6 = $t42 & $y11; $z7 = $t45 & $y17; $z8 = $t41 & $y10; $z9 = $t44 & $y12; $z10 = $t37 & $y3; $z11 = $t33 & $y4; $z12 = $t43 & $y13; $z13 = $t40 & $y5; $z14 = $t29 & $y2; $z15 = $t42 & $y9; $z16 = $t45 & $y14; $z17 = $t41 & $y8; /* * Bottom linear transformation. */ $t46 = $z15 ^ $z16; $t47 = $z10 ^ $z11; $t48 = $z5 ^ $z13; $t49 = $z9 ^ $z10; $t50 = $z2 ^ $z12; $t51 = $z2 ^ $z5; $t52 = $z7 ^ $z8; $t53 = $z0 ^ $z3; $t54 = $z6 ^ $z7; $t55 = $z16 ^ $z17; $t56 = $z12 ^ $t48; $t57 = $t50 ^ $t53; $t58 = $z4 ^ $t46; $t59 = $z3 ^ $t54; $t60 = $t46 ^ $t57; $t61 = $z14 ^ $t57; $t62 = $t52 ^ $t58; $t63 = $t49 ^ $t58; $t64 = $z4 ^ $t59; $t65 = $t61 ^ $t62; $t66 = $z1 ^ $t63; $s0 = $t59 ^ $t63; $s6 = $t56 ^ ~$t62; $s7 = $t48 ^ ~$t60; $t67 = $t64 ^ $t65; $s3 = $t53 ^ $t66; $s4 = $t51 ^ $t66; $s5 = $t47 ^ $t65; $s1 = $t64 ^ ~$s3; $s2 = $t55 ^ ~$t67; $q[7] = $s0 & self::U32_MAX; $q[6] = $s1 & self::U32_MAX; $q[5] = $s2 & self::U32_MAX; $q[4] = $s3 & self::U32_MAX; $q[3] = $s4 & self::U32_MAX; $q[2] = $s5 & self::U32_MAX; $q[1] = $s6 & self::U32_MAX; $q[0] = $s7 & self::U32_MAX; } /** * Mutates the values of $q! * * @param ParagonIE_Sodium_Core_AES_Block $q * @return void */ public static function invSbox(ParagonIE_Sodium_Core_AES_Block $q) { self::processInversion($q); self::sbox($q); self::processInversion($q); } /** * This is some boilerplate code needed to invert an S-box. Rather than repeat the code * twice, I moved it to a protected method. * * Mutates $q * * @param ParagonIE_Sodium_Core_AES_Block $q * @return void */ protected static function processInversion(ParagonIE_Sodium_Core_AES_Block $q) { $q0 = (~$q[0]) & self::U32_MAX; $q1 = (~$q[1]) & self::U32_MAX; $q2 = $q[2] & self::U32_MAX; $q3 = $q[3] & self::U32_MAX; $q4 = $q[4] & self::U32_MAX; $q5 = (~$q[5]) & self::U32_MAX; $q6 = (~$q[6]) & self::U32_MAX; $q7 = $q[7] & self::U32_MAX; $q[7] = ($q1 ^ $q4 ^ $q6) & self::U32_MAX; $q[6] = ($q0 ^ $q3 ^ $q5) & self::U32_MAX; $q[5] = ($q7 ^ $q2 ^ $q4) & self::U32_MAX; $q[4] = ($q6 ^ $q1 ^ $q3) & self::U32_MAX; $q[3] = ($q5 ^ $q0 ^ $q2) & self::U32_MAX; $q[2] = ($q4 ^ $q7 ^ $q1) & self::U32_MAX; $q[1] = ($q3 ^ $q6 ^ $q0) & self::U32_MAX; $q[0] = ($q2 ^ $q5 ^ $q7) & self::U32_MAX; } /** * @param int $x * @return int */ public static function subWord($x) { $q = ParagonIE_Sodium_Core_AES_Block::fromArray( array($x, $x, $x, $x, $x, $x, $x, $x) ); $q->orthogonalize(); self::sbox($q); $q->orthogonalize(); return $q[0] & self::U32_MAX; } /** * Calculate the key schedule from a given random key * * @param string $key * @return ParagonIE_Sodium_Core_AES_KeySchedule * @throws SodiumException */ public static function keySchedule($key) { $key_len = self::strlen($key); switch ($key_len) { case 16: $num_rounds = 10; break; case 24: $num_rounds = 12; break; case 32: $num_rounds = 14; break; default: throw new SodiumException('Invalid key length: ' . $key_len); } $skey = array(); $comp_skey = array(); $nk = $key_len >> 2; $nkf = ($num_rounds + 1) << 2; $tmp = 0; for ($i = 0; $i < $nk; ++$i) { $tmp = self::load_4(self::substr($key, $i << 2, 4)); $skey[($i << 1)] = $tmp; $skey[($i << 1) + 1] = $tmp; } for ($i = $nk, $j = 0, $k = 0; $i < $nkf; ++$i) { if ($j === 0) { $tmp = (($tmp & 0xff) << 24) | ($tmp >> 8); $tmp = (self::subWord($tmp) ^ self::$Rcon[$k]) & self::U32_MAX; } elseif ($nk > 6 && $j === 4) { $tmp = self::subWord($tmp); } $tmp ^= $skey[($i - $nk) << 1]; $skey[($i << 1)] = $tmp & self::U32_MAX; $skey[($i << 1) + 1] = $tmp & self::U32_MAX; if (++$j === $nk) { /** @psalm-suppress LoopInvalidation */ $j = 0; ++$k; } } for ($i = 0; $i < $nkf; $i += 4) { $q = ParagonIE_Sodium_Core_AES_Block::fromArray( array_slice($skey, $i << 1, 8) ); $q->orthogonalize(); // We have to overwrite $skey since we're not using C pointers like BearSSL did for ($j = 0; $j < 8; ++$j) { $skey[($i << 1) + $j] = $q[$j]; } } for ($i = 0, $j = 0; $i < $nkf; ++$i, $j += 2) { $comp_skey[$i] = ($skey[$j] & 0x55555555) | ($skey[$j + 1] & 0xAAAAAAAA); } return new ParagonIE_Sodium_Core_AES_KeySchedule($comp_skey, $num_rounds); } /** * Mutates $q * * @param ParagonIE_Sodium_Core_AES_KeySchedule $skey * @param ParagonIE_Sodium_Core_AES_Block $q * @param int $offset * @return void */ public static function addRoundKey( ParagonIE_Sodium_Core_AES_Block $q, ParagonIE_Sodium_Core_AES_KeySchedule $skey, $offset = 0 ) { $block = $skey->getRoundKey($offset); for ($j = 0; $j < 8; ++$j) { $q[$j] = ($q[$j] ^ $block[$j]) & ParagonIE_Sodium_Core_Util::U32_MAX; } } /** * This mainly exists for testing, as we need the round key features for AEGIS. * * @param string $message * @param string $key * @return string * @throws SodiumException */ public static function decryptBlockECB($message, $key) { if (self::strlen($message) !== 16) { throw new SodiumException('decryptBlockECB() expects a 16 byte message'); } $skey = self::keySchedule($key)->expand(); $q = ParagonIE_Sodium_Core_AES_Block::init(); $q[0] = self::load_4(self::substr($message, 0, 4)); $q[2] = self::load_4(self::substr($message, 4, 4)); $q[4] = self::load_4(self::substr($message, 8, 4)); $q[6] = self::load_4(self::substr($message, 12, 4)); $q->orthogonalize(); self::bitsliceDecryptBlock($skey, $q); $q->orthogonalize(); return self::store32_le($q[0]) . self::store32_le($q[2]) . self::store32_le($q[4]) . self::store32_le($q[6]); } /** * This mainly exists for testing, as we need the round key features for AEGIS. * * @param string $message * @param string $key * @return string * @throws SodiumException */ public static function encryptBlockECB($message, $key) { if (self::strlen($message) !== 16) { throw new SodiumException('encryptBlockECB() expects a 16 byte message'); } $comp_skey = self::keySchedule($key); $skey = $comp_skey->expand(); $q = ParagonIE_Sodium_Core_AES_Block::init(); $q[0] = self::load_4(self::substr($message, 0, 4)); $q[2] = self::load_4(self::substr($message, 4, 4)); $q[4] = self::load_4(self::substr($message, 8, 4)); $q[6] = self::load_4(self::substr($message, 12, 4)); $q->orthogonalize(); self::bitsliceEncryptBlock($skey, $q); $q->orthogonalize(); return self::store32_le($q[0]) . self::store32_le($q[2]) . self::store32_le($q[4]) . self::store32_le($q[6]); } /** * Mutates $q * * @param ParagonIE_Sodium_Core_AES_Expanded $skey * @param ParagonIE_Sodium_Core_AES_Block $q * @return void */ public static function bitsliceEncryptBlock( ParagonIE_Sodium_Core_AES_Expanded $skey, ParagonIE_Sodium_Core_AES_Block $q ) { self::addRoundKey($q, $skey); for ($u = 1; $u < $skey->getNumRounds(); ++$u) { self::sbox($q); $q->shiftRows(); $q->mixColumns(); self::addRoundKey($q, $skey, ($u << 3)); } self::sbox($q); $q->shiftRows(); self::addRoundKey($q, $skey, ($skey->getNumRounds() << 3)); } /** * @param string $x * @param string $y * @return string */ public static function aesRound($x, $y) { $q = ParagonIE_Sodium_Core_AES_Block::init(); $q[0] = self::load_4(self::substr($x, 0, 4)); $q[2] = self::load_4(self::substr($x, 4, 4)); $q[4] = self::load_4(self::substr($x, 8, 4)); $q[6] = self::load_4(self::substr($x, 12, 4)); $rk = ParagonIE_Sodium_Core_AES_Block::init(); $rk[0] = $rk[1] = self::load_4(self::substr($y, 0, 4)); $rk[2] = $rk[3] = self::load_4(self::substr($y, 4, 4)); $rk[4] = $rk[5] = self::load_4(self::substr($y, 8, 4)); $rk[6] = $rk[7] = self::load_4(self::substr($y, 12, 4)); $q->orthogonalize(); self::sbox($q); $q->shiftRows(); $q->mixColumns(); $q->orthogonalize(); // add round key without key schedule: for ($i = 0; $i < 8; ++$i) { $q[$i] ^= $rk[$i]; } return self::store32_le($q[0]) . self::store32_le($q[2]) . self::store32_le($q[4]) . self::store32_le($q[6]); } /** * Process two AES blocks in one shot. * * @param string $b0 First AES block * @param string $rk0 First round key * @param string $b1 Second AES block * @param string $rk1 Second round key * @return string[] */ public static function doubleRound($b0, $rk0, $b1, $rk1) { $q = ParagonIE_Sodium_Core_AES_Block::init(); // First block $q[0] = self::load_4(self::substr($b0, 0, 4)); $q[2] = self::load_4(self::substr($b0, 4, 4)); $q[4] = self::load_4(self::substr($b0, 8, 4)); $q[6] = self::load_4(self::substr($b0, 12, 4)); // Second block $q[1] = self::load_4(self::substr($b1, 0, 4)); $q[3] = self::load_4(self::substr($b1, 4, 4)); $q[5] = self::load_4(self::substr($b1, 8, 4)); $q[7] = self::load_4(self::substr($b1, 12, 4));; $rk = ParagonIE_Sodium_Core_AES_Block::init(); // First round key $rk[0] = self::load_4(self::substr($rk0, 0, 4)); $rk[2] = self::load_4(self::substr($rk0, 4, 4)); $rk[4] = self::load_4(self::substr($rk0, 8, 4)); $rk[6] = self::load_4(self::substr($rk0, 12, 4)); // Second round key $rk[1] = self::load_4(self::substr($rk1, 0, 4)); $rk[3] = self::load_4(self::substr($rk1, 4, 4)); $rk[5] = self::load_4(self::substr($rk1, 8, 4)); $rk[7] = self::load_4(self::substr($rk1, 12, 4)); $q->orthogonalize(); self::sbox($q); $q->shiftRows(); $q->mixColumns(); $q->orthogonalize(); // add round key without key schedule: for ($i = 0; $i < 8; ++$i) { $q[$i] ^= $rk[$i]; } return array( self::store32_le($q[0]) . self::store32_le($q[2]) . self::store32_le($q[4]) . self::store32_le($q[6]), self::store32_le($q[1]) . self::store32_le($q[3]) . self::store32_le($q[5]) . self::store32_le($q[7]), ); } /** * @param ParagonIE_Sodium_Core_AES_Expanded $skey * @param ParagonIE_Sodium_Core_AES_Block $q * @return void */ public static function bitsliceDecryptBlock( ParagonIE_Sodium_Core_AES_Expanded $skey, ParagonIE_Sodium_Core_AES_Block $q ) { self::addRoundKey($q, $skey, ($skey->getNumRounds() << 3)); for ($u = $skey->getNumRounds() - 1; $u > 0; --$u) { $q->inverseShiftRows(); self::invSbox($q); self::addRoundKey($q, $skey, ($u << 3)); $q->inverseMixColumns(); } $q->inverseShiftRows(); self::invSbox($q); self::addRoundKey($q, $skey, ($u << 3)); } } <?php if (class_exists('ParagonIE_Sodium_Core_AEGIS_State128L', false)) { return; } if (!defined('SODIUM_COMPAT_AEGIS_C0')) { define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62"); } if (!defined('SODIUM_COMPAT_AEGIS_C1')) { define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd"); } class ParagonIE_Sodium_Core_AEGIS_State128L { /** @var array<int, string> $state */ protected $state; public function __construct() { $this->state = array_fill(0, 8, ''); } /** * @internal Only use this for unit tests! * @return string[] */ public function getState() { return array_values($this->state); } /** * @param array $input * @return self * @throws SodiumException * * @internal Only for unit tests */ public static function initForUnitTests(array $input) { if (count($input) < 8) { throw new SodiumException('invalid input'); } $state = new self(); for ($i = 0; $i < 8; ++$i) { $state->state[$i] = $input[$i]; } return $state; } /** * @param string $key * @param string $nonce * @return self */ public static function init($key, $nonce) { $state = new self(); // S0 = key ^ nonce $state->state[0] = $key ^ $nonce; // S1 = C1 $state->state[1] = SODIUM_COMPAT_AEGIS_C1; // S2 = C0 $state->state[2] = SODIUM_COMPAT_AEGIS_C0; // S3 = C1 $state->state[3] = SODIUM_COMPAT_AEGIS_C1; // S4 = key ^ nonce $state->state[4] = $key ^ $nonce; // S5 = key ^ C0 $state->state[5] = $key ^ SODIUM_COMPAT_AEGIS_C0; // S6 = key ^ C1 $state->state[6] = $key ^ SODIUM_COMPAT_AEGIS_C1; // S7 = key ^ C0 $state->state[7] = $key ^ SODIUM_COMPAT_AEGIS_C0; // Repeat(10, Update(nonce, key)) for ($i = 0; $i < 10; ++$i) { $state->update($nonce, $key); } return $state; } /** * @param string $ai * @return self */ public function absorb($ai) { if (ParagonIE_Sodium_Core_Util::strlen($ai) !== 32) { throw new SodiumException('Input must be two AES blocks in size'); } $t0 = ParagonIE_Sodium_Core_Util::substr($ai, 0, 16); $t1 = ParagonIE_Sodium_Core_Util::substr($ai, 16, 16); return $this->update($t0, $t1); } /** * @param string $ci * @return string * @throws SodiumException */ public function dec($ci) { if (ParagonIE_Sodium_Core_Util::strlen($ci) !== 32) { throw new SodiumException('Input must be two AES blocks in size'); } // z0 = S6 ^ S1 ^ (S2 & S3) $z0 = $this->state[6] ^ $this->state[1] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); // z1 = S2 ^ S5 ^ (S6 & S7) $z1 = $this->state[2] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]); // t0, t1 = Split(xi, 128) $t0 = ParagonIE_Sodium_Core_Util::substr($ci, 0, 16); $t1 = ParagonIE_Sodium_Core_Util::substr($ci, 16, 16); // out0 = t0 ^ z0 // out1 = t1 ^ z1 $out0 = $t0 ^ $z0; $out1 = $t1 ^ $z1; // Update(out0, out1) // xi = out0 || out1 $this->update($out0, $out1); return $out0 . $out1; } /** * @param string $cn * @return string */ public function decPartial($cn) { $len = ParagonIE_Sodium_Core_Util::strlen($cn); // z0 = S6 ^ S1 ^ (S2 & S3) $z0 = $this->state[6] ^ $this->state[1] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); // z1 = S2 ^ S5 ^ (S6 & S7) $z1 = $this->state[2] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]); // t0, t1 = Split(ZeroPad(cn, 256), 128) $cn = str_pad($cn, 32, "\0", STR_PAD_RIGHT); $t0 = ParagonIE_Sodium_Core_Util::substr($cn, 0, 16); $t1 = ParagonIE_Sodium_Core_Util::substr($cn, 16, 16); // out0 = t0 ^ z0 // out1 = t1 ^ z1 $out0 = $t0 ^ $z0; $out1 = $t1 ^ $z1; // xn = Truncate(out0 || out1, |cn|) $xn = ParagonIE_Sodium_Core_Util::substr($out0 . $out1, 0, $len); // v0, v1 = Split(ZeroPad(xn, 256), 128) $padded = str_pad($xn, 32, "\0", STR_PAD_RIGHT); $v0 = ParagonIE_Sodium_Core_Util::substr($padded, 0, 16); $v1 = ParagonIE_Sodium_Core_Util::substr($padded, 16, 16); // Update(v0, v1) $this->update($v0, $v1); // return xn return $xn; } /** * @param string $xi * @return string * @throws SodiumException */ public function enc($xi) { if (ParagonIE_Sodium_Core_Util::strlen($xi) !== 32) { throw new SodiumException('Input must be two AES blocks in size'); } // z0 = S6 ^ S1 ^ (S2 & S3) $z0 = $this->state[6] ^ $this->state[1] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); // z1 = S2 ^ S5 ^ (S6 & S7) $z1 = $this->state[2] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[6], $this->state[7]); // t0, t1 = Split(xi, 128) $t0 = ParagonIE_Sodium_Core_Util::substr($xi, 0, 16); $t1 = ParagonIE_Sodium_Core_Util::substr($xi, 16, 16); // out0 = t0 ^ z0 // out1 = t1 ^ z1 $out0 = $t0 ^ $z0; $out1 = $t1 ^ $z1; // Update(t0, t1) // ci = out0 || out1 $this->update($t0, $t1); // return ci return $out0 . $out1; } /** * @param int $ad_len_bits * @param int $msg_len_bits * @return string */ public function finalize($ad_len_bits, $msg_len_bits) { $encoded = ParagonIE_Sodium_Core_Util::store64_le($ad_len_bits) . ParagonIE_Sodium_Core_Util::store64_le($msg_len_bits); $t = $this->state[2] ^ $encoded; for ($i = 0; $i < 7; ++$i) { $this->update($t, $t); } return ($this->state[0] ^ $this->state[1] ^ $this->state[2] ^ $this->state[3]) . ($this->state[4] ^ $this->state[5] ^ $this->state[6] ^ $this->state[7]); } /** * @param string $m0 * @param string $m1 * @return self */ public function update($m0, $m1) { /* S'0 = AESRound(S7, S0 ^ M0) S'1 = AESRound(S0, S1) S'2 = AESRound(S1, S2) S'3 = AESRound(S2, S3) S'4 = AESRound(S3, S4 ^ M1) S'5 = AESRound(S4, S5) S'6 = AESRound(S5, S6) S'7 = AESRound(S6, S7) */ list($s_0, $s_1) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[7], $this->state[0] ^ $m0, $this->state[0], $this->state[1] ); list($s_2, $s_3) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[1], $this->state[2], $this->state[2], $this->state[3] ); list($s_4, $s_5) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[3], $this->state[4] ^ $m1, $this->state[4], $this->state[5] ); list($s_6, $s_7) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[5], $this->state[6], $this->state[6], $this->state[7] ); /* S0 = S'0 S1 = S'1 S2 = S'2 S3 = S'3 S4 = S'4 S5 = S'5 S6 = S'6 S7 = S'7 */ $this->state[0] = $s_0; $this->state[1] = $s_1; $this->state[2] = $s_2; $this->state[3] = $s_3; $this->state[4] = $s_4; $this->state[5] = $s_5; $this->state[6] = $s_6; $this->state[7] = $s_7; return $this; } }<?php if (class_exists('ParagonIE_Sodium_Core_AEGIS_State256', false)) { return; } if (!defined('SODIUM_COMPAT_AEGIS_C0')) { define('SODIUM_COMPAT_AEGIS_C0', "\x00\x01\x01\x02\x03\x05\x08\x0d\x15\x22\x37\x59\x90\xe9\x79\x62"); } if (!defined('SODIUM_COMPAT_AEGIS_C1')) { define('SODIUM_COMPAT_AEGIS_C1', "\xdb\x3d\x18\x55\x6d\xc2\x2f\xf1\x20\x11\x31\x42\x73\xb5\x28\xdd"); } class ParagonIE_Sodium_Core_AEGIS_State256 { /** @var array<int, string> $state */ protected $state; public function __construct() { $this->state = array_fill(0, 6, ''); } /** * @internal Only use this for unit tests! * @return string[] */ public function getState() { return array_values($this->state); } /** * @param array $input * @return self * @throws SodiumException * * @internal Only for unit tests */ public static function initForUnitTests(array $input) { if (count($input) < 6) { throw new SodiumException('invalid input'); } $state = new self(); for ($i = 0; $i < 6; ++$i) { $state->state[$i] = $input[$i]; } return $state; } /** * @param string $key * @param string $nonce * @return self */ public static function init($key, $nonce) { $state = new self(); $k0 = ParagonIE_Sodium_Core_Util::substr($key, 0, 16); $k1 = ParagonIE_Sodium_Core_Util::substr($key, 16, 16); $n0 = ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16); $n1 = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 16); // S0 = k0 ^ n0 // S1 = k1 ^ n1 // S2 = C1 // S3 = C0 // S4 = k0 ^ C0 // S5 = k1 ^ C1 $k0_n0 = $k0 ^ $n0; $k1_n1 = $k1 ^ $n1; $state->state[0] = $k0_n0; $state->state[1] = $k1_n1; $state->state[2] = SODIUM_COMPAT_AEGIS_C1; $state->state[3] = SODIUM_COMPAT_AEGIS_C0; $state->state[4] = $k0 ^ SODIUM_COMPAT_AEGIS_C0; $state->state[5] = $k1 ^ SODIUM_COMPAT_AEGIS_C1; // Repeat(4, // Update(k0) // Update(k1) // Update(k0 ^ n0) // Update(k1 ^ n1) // ) for ($i = 0; $i < 4; ++$i) { $state->update($k0); $state->update($k1); $state->update($k0 ^ $n0); $state->update($k1 ^ $n1); } return $state; } /** * @param string $ai * @return self * @throws SodiumException */ public function absorb($ai) { if (ParagonIE_Sodium_Core_Util::strlen($ai) !== 16) { throw new SodiumException('Input must be an AES block in size'); } return $this->update($ai); } /** * @param string $ci * @return string * @throws SodiumException */ public function dec($ci) { if (ParagonIE_Sodium_Core_Util::strlen($ci) !== 16) { throw new SodiumException('Input must be an AES block in size'); } // z = S1 ^ S4 ^ S5 ^ (S2 & S3) $z = $this->state[1] ^ $this->state[4] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); $xi = $ci ^ $z; $this->update($xi); return $xi; } /** * @param string $cn * @return string */ public function decPartial($cn) { $len = ParagonIE_Sodium_Core_Util::strlen($cn); // z = S1 ^ S4 ^ S5 ^ (S2 & S3) $z = $this->state[1] ^ $this->state[4] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); // t = ZeroPad(cn, 128) $t = str_pad($cn, 16, "\0", STR_PAD_RIGHT); // out = t ^ z $out = $t ^ $z; // xn = Truncate(out, |cn|) $xn = ParagonIE_Sodium_Core_Util::substr($out, 0, $len); // v = ZeroPad(xn, 128) $v = str_pad($xn, 16, "\0", STR_PAD_RIGHT); // Update(v) $this->update($v); // return xn return $xn; } /** * @param string $xi * @return string * @throws SodiumException */ public function enc($xi) { if (ParagonIE_Sodium_Core_Util::strlen($xi) !== 16) { throw new SodiumException('Input must be an AES block in size'); } // z = S1 ^ S4 ^ S5 ^ (S2 & S3) $z = $this->state[1] ^ $this->state[4] ^ $this->state[5] ^ ParagonIE_Sodium_Core_Util::andStrings($this->state[2], $this->state[3]); $this->update($xi); return $xi ^ $z; } /** * @param int $ad_len_bits * @param int $msg_len_bits * @return string */ public function finalize($ad_len_bits, $msg_len_bits) { $encoded = ParagonIE_Sodium_Core_Util::store64_le($ad_len_bits) . ParagonIE_Sodium_Core_Util::store64_le($msg_len_bits); $t = $this->state[3] ^ $encoded; for ($i = 0; $i < 7; ++$i) { $this->update($t); } return ($this->state[0] ^ $this->state[1] ^ $this->state[2]) . ($this->state[3] ^ $this->state[4] ^ $this->state[5]); } /** * @param string $m * @return self */ public function update($m) { /* S'0 = AESRound(S5, S0 ^ M) S'1 = AESRound(S0, S1) S'2 = AESRound(S1, S2) S'3 = AESRound(S2, S3) S'4 = AESRound(S3, S4) S'5 = AESRound(S4, S5) */ list($s_0, $s_1) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[5],$this->state[0] ^ $m, $this->state[0], $this->state[1] ); list($s_2, $s_3) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[1], $this->state[2], $this->state[2], $this->state[3] ); list($s_4, $s_5) = ParagonIE_Sodium_Core_AES::doubleRound( $this->state[3], $this->state[4], $this->state[4], $this->state[5] ); /* S0 = S'0 S1 = S'1 S2 = S'2 S3 = S'3 S4 = S'4 S5 = S'5 */ $this->state[0] = $s_0; $this->state[1] = $s_1; $this->state[2] = $s_2; $this->state[3] = $s_3; $this->state[4] = $s_4; $this->state[5] = $s_5; return $this; } } <?php if (class_exists('ParagonIE_Sodium_Core_BLAKE2b', false)) { return; } /** * Class ParagonIE_Sodium_Core_BLAKE2b * * Based on the work of Devi Mandiri in devi/salt. */ abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util { /** * @var SplFixedArray */ protected static $iv; /** * @var array<int, array<int, int>> */ protected static $sigma = array( array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), array( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), array( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), array( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), array( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), array( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), array( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), array( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), array( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0), array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3) ); const BLOCKBYTES = 128; const OUTBYTES = 64; const KEYBYTES = 64; /** * Turn two 32-bit integers into a fixed array representing a 64-bit integer. * * @internal You should not use this directly from another application * * @param int $high * @param int $low * @return SplFixedArray * @psalm-suppress MixedAssignment */ public static function new64($high, $low) { if (PHP_INT_SIZE === 4) { throw new SodiumException("Error, use 32-bit"); } $i64 = new SplFixedArray(2); $i64[0] = $high & 0xffffffff; $i64[1] = $low & 0xffffffff; return $i64; } /** * Convert an arbitrary number into an SplFixedArray of two 32-bit integers * that represents a 64-bit integer. * * @internal You should not use this directly from another application * * @param int $num * @return SplFixedArray */ protected static function to64($num) { list($hi, $lo) = self::numericTo64BitInteger($num); return self::new64($hi, $lo); } /** * Adds two 64-bit integers together, returning their sum as a SplFixedArray * containing two 32-bit integers (representing a 64-bit integer). * * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param SplFixedArray $y * @return SplFixedArray * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ protected static function add64($x, $y) { if (PHP_INT_SIZE === 4) { throw new SodiumException("Error, use 32-bit"); } $l = ($x[1] + $y[1]) & 0xffffffff; return self::new64( (int) ($x[0] + $y[0] + ( ($l < $x[1]) ? 1 : 0 )), (int) $l ); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param SplFixedArray $y * @param SplFixedArray $z * @return SplFixedArray */ protected static function add364($x, $y, $z) { return self::add64($x, self::add64($y, $z)); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param SplFixedArray $y * @return SplFixedArray * @throws SodiumException * @throws TypeError */ protected static function xor64(SplFixedArray $x, SplFixedArray $y) { if (PHP_INT_SIZE === 4) { throw new SodiumException("Error, use 32-bit"); } if (!is_numeric($x[0])) { throw new SodiumException('x[0] is not an integer'); } if (!is_numeric($x[1])) { throw new SodiumException('x[1] is not an integer'); } if (!is_numeric($y[0])) { throw new SodiumException('y[0] is not an integer'); } if (!is_numeric($y[1])) { throw new SodiumException('y[1] is not an integer'); } return self::new64( (int) (($x[0] ^ $y[0]) & 0xffffffff), (int) (($x[1] ^ $y[1]) & 0xffffffff) ); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param int $c * @return SplFixedArray * @psalm-suppress MixedAssignment */ public static function rotr64($x, $c) { if (PHP_INT_SIZE === 4) { throw new SodiumException("Error, use 32-bit"); } if ($c >= 64) { $c %= 64; } if ($c >= 32) { /** @var int $tmp */ $tmp = $x[0]; $x[0] = $x[1]; $x[1] = $tmp; $c -= 32; } if ($c === 0) { return $x; } $l0 = 0; $c = 64 - $c; /** @var int $c */ if ($c < 32) { $h0 = ((int) ($x[0]) << $c) | ( ( (int) ($x[1]) & ((1 << $c) - 1) << (32 - $c) ) >> (32 - $c) ); $l0 = (int) ($x[1]) << $c; } else { $h0 = (int) ($x[1]) << ($c - 32); } $h1 = 0; $c1 = 64 - $c; if ($c1 < 32) { $h1 = (int) ($x[0]) >> $c1; $l1 = ((int) ($x[1]) >> $c1) | ((int) ($x[0]) & ((1 << $c1) - 1)) << (32 - $c1); } else { $l1 = (int) ($x[0]) >> ($c1 - 32); } return self::new64($h0 | $h1, $l0 | $l1); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @return int * @psalm-suppress MixedOperand */ protected static function flatten64($x) { return (int) ($x[0] * 4294967296 + $x[1]); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param int $i * @return SplFixedArray * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayOffset */ protected static function load64(SplFixedArray $x, $i) { /** @var int $l */ $l = (int) ($x[$i]) | ((int) ($x[$i+1]) << 8) | ((int) ($x[$i+2]) << 16) | ((int) ($x[$i+3]) << 24); /** @var int $h */ $h = (int) ($x[$i+4]) | ((int) ($x[$i+5]) << 8) | ((int) ($x[$i+6]) << 16) | ((int) ($x[$i+7]) << 24); return self::new64($h, $l); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param int $i * @param SplFixedArray $u * @return void * @psalm-suppress MixedAssignment */ protected static function store64(SplFixedArray $x, $i, SplFixedArray $u) { $maxLength = $x->getSize() - 1; for ($j = 0; $j < 8; ++$j) { /* [0, 1, 2, 3, 4, 5, 6, 7] ... becomes ... [0, 0, 0, 0, 1, 1, 1, 1] */ /** @var int $uIdx */ $uIdx = ((7 - $j) & 4) >> 2; $x[$i] = ((int) ($u[$uIdx]) & 0xff); if (++$i > $maxLength) { return; } /** @psalm-suppress MixedOperand */ $u[$uIdx] >>= 8; } } /** * This just sets the $iv static variable. * * @internal You should not use this directly from another application * * @return void */ public static function pseudoConstructor() { static $called = false; if ($called) { return; } self::$iv = new SplFixedArray(8); self::$iv[0] = self::new64(0x6a09e667, 0xf3bcc908); self::$iv[1] = self::new64(0xbb67ae85, 0x84caa73b); self::$iv[2] = self::new64(0x3c6ef372, 0xfe94f82b); self::$iv[3] = self::new64(0xa54ff53a, 0x5f1d36f1); self::$iv[4] = self::new64(0x510e527f, 0xade682d1); self::$iv[5] = self::new64(0x9b05688c, 0x2b3e6c1f); self::$iv[6] = self::new64(0x1f83d9ab, 0xfb41bd6b); self::$iv[7] = self::new64(0x5be0cd19, 0x137e2179); $called = true; } /** * Returns a fresh BLAKE2 context. * * @internal You should not use this directly from another application * * @return SplFixedArray * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment */ protected static function context() { $ctx = new SplFixedArray(6); $ctx[0] = new SplFixedArray(8); // h $ctx[1] = new SplFixedArray(2); // t $ctx[2] = new SplFixedArray(2); // f $ctx[3] = new SplFixedArray(256); // buf $ctx[4] = 0; // buflen $ctx[5] = 0; // last_node (uint8_t) for ($i = 8; $i--;) { $ctx[0][$i] = self::$iv[$i]; } for ($i = 256; $i--;) { $ctx[3][$i] = 0; } $zero = self::new64(0, 0); $ctx[1][0] = $zero; $ctx[1][1] = $zero; $ctx[2][0] = $zero; $ctx[2][1] = $zero; return $ctx; } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $buf * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset */ protected static function compress(SplFixedArray $ctx, SplFixedArray $buf) { $m = new SplFixedArray(16); $v = new SplFixedArray(16); for ($i = 16; $i--;) { $m[$i] = self::load64($buf, $i << 3); } for ($i = 8; $i--;) { $v[$i] = $ctx[0][$i]; } $v[ 8] = self::$iv[0]; $v[ 9] = self::$iv[1]; $v[10] = self::$iv[2]; $v[11] = self::$iv[3]; $v[12] = self::xor64($ctx[1][0], self::$iv[4]); $v[13] = self::xor64($ctx[1][1], self::$iv[5]); $v[14] = self::xor64($ctx[2][0], self::$iv[6]); $v[15] = self::xor64($ctx[2][1], self::$iv[7]); for ($r = 0; $r < 12; ++$r) { $v = self::G($r, 0, 0, 4, 8, 12, $v, $m); $v = self::G($r, 1, 1, 5, 9, 13, $v, $m); $v = self::G($r, 2, 2, 6, 10, 14, $v, $m); $v = self::G($r, 3, 3, 7, 11, 15, $v, $m); $v = self::G($r, 4, 0, 5, 10, 15, $v, $m); $v = self::G($r, 5, 1, 6, 11, 12, $v, $m); $v = self::G($r, 6, 2, 7, 8, 13, $v, $m); $v = self::G($r, 7, 3, 4, 9, 14, $v, $m); } for ($i = 8; $i--;) { $ctx[0][$i] = self::xor64( $ctx[0][$i], self::xor64($v[$i], $v[$i+8]) ); } } /** * @internal You should not use this directly from another application * * @param int $r * @param int $i * @param int $a * @param int $b * @param int $c * @param int $d * @param SplFixedArray $v * @param SplFixedArray $m * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayOffset */ public static function G($r, $i, $a, $b, $c, $d, SplFixedArray $v, SplFixedArray $m) { $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][$i << 1]]); $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 32); $v[$c] = self::add64($v[$c], $v[$d]); $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 24); $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][($i << 1) + 1]]); $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 16); $v[$c] = self::add64($v[$c], $v[$d]); $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 63); return $v; } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param int $inc * @return void * @throws SodiumException * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment */ public static function increment_counter($ctx, $inc) { if ($inc < 0) { throw new SodiumException('Increasing by a negative number makes no sense.'); } $t = self::to64($inc); # S->t is $ctx[1] in our implementation # S->t[0] = ( uint64_t )( t >> 0 ); $ctx[1][0] = self::add64($ctx[1][0], $t); # S->t[1] += ( S->t[0] < inc ); if (self::flatten64($ctx[1][0]) < $inc) { $ctx[1][1] = self::add64($ctx[1][1], self::to64(1)); } } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $p * @param int $plen * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedOperand */ public static function update(SplFixedArray $ctx, SplFixedArray $p, $plen) { self::pseudoConstructor(); $offset = 0; while ($plen > 0) { $left = $ctx[4]; $fill = 256 - $left; if ($plen > $fill) { # memcpy( S->buf + left, in, fill ); /* Fill buffer */ for ($i = $fill; $i--;) { $ctx[3][$i + $left] = $p[$i + $offset]; } # S->buflen += fill; $ctx[4] += $fill; # blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); self::increment_counter($ctx, 128); # blake2b_compress( S, S->buf ); /* Compress */ self::compress($ctx, $ctx[3]); # memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ for ($i = 128; $i--;) { $ctx[3][$i] = $ctx[3][$i + 128]; } # S->buflen -= BLAKE2B_BLOCKBYTES; $ctx[4] -= 128; # in += fill; $offset += $fill; # inlen -= fill; $plen -= $fill; } else { for ($i = $plen; $i--;) { $ctx[3][$i + $left] = $p[$i + $offset]; } $ctx[4] += $plen; $offset += $plen; $plen -= $plen; } } } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $out * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedOperand */ public static function finish(SplFixedArray $ctx, SplFixedArray $out) { self::pseudoConstructor(); if ($ctx[4] > 128) { self::increment_counter($ctx, 128); self::compress($ctx, $ctx[3]); $ctx[4] -= 128; if ($ctx[4] > 128) { throw new SodiumException('Failed to assert that buflen <= 128 bytes'); } for ($i = $ctx[4]; $i--;) { $ctx[3][$i] = $ctx[3][$i + 128]; } } self::increment_counter($ctx, $ctx[4]); $ctx[2][0] = self::new64(0xffffffff, 0xffffffff); for ($i = 256 - $ctx[4]; $i--;) { $ctx[3][$i+$ctx[4]] = 0; } self::compress($ctx, $ctx[3]); $i = (int) (($out->getSize() - 1) / 8); for (; $i >= 0; --$i) { self::store64($out, $i << 3, $ctx[0][$i]); } return $out; } /** * @internal You should not use this directly from another application * * @param SplFixedArray|null $key * @param int $outlen * @param SplFixedArray|null $salt * @param SplFixedArray|null $personal * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset */ public static function init( $key = null, $outlen = 64, $salt = null, $personal = null ) { self::pseudoConstructor(); $klen = 0; if ($key !== null) { if (count($key) > 64) { throw new SodiumException('Invalid key size'); } $klen = count($key); } if ($outlen > 64) { throw new SodiumException('Invalid output size'); } $ctx = self::context(); $p = new SplFixedArray(64); // Zero our param buffer... for ($i = 64; --$i;) { $p[$i] = 0; } $p[0] = $outlen; // digest_length $p[1] = $klen; // key_length $p[2] = 1; // fanout $p[3] = 1; // depth if ($salt instanceof SplFixedArray) { // salt: [32] through [47] for ($i = 0; $i < 16; ++$i) { $p[32 + $i] = (int) $salt[$i]; } } if ($personal instanceof SplFixedArray) { // personal: [48] through [63] for ($i = 0; $i < 16; ++$i) { $p[48 + $i] = (int) $personal[$i]; } } $ctx[0][0] = self::xor64( $ctx[0][0], self::load64($p, 0) ); if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) { // We need to do what blake2b_init_param() does: for ($i = 1; $i < 8; ++$i) { $ctx[0][$i] = self::xor64( $ctx[0][$i], self::load64($p, $i << 3) ); } } if ($klen > 0 && $key instanceof SplFixedArray) { $block = new SplFixedArray(128); for ($i = 128; $i--;) { $block[$i] = 0; } for ($i = $klen; $i--;) { $block[$i] = $key[$i]; } self::update($ctx, $block, 128); $ctx[4] = 128; } return $ctx; } /** * Convert a string into an SplFixedArray of integers * * @internal You should not use this directly from another application * * @param string $str * @return SplFixedArray * @psalm-suppress MixedArgumentTypeCoercion */ public static function stringToSplFixedArray($str = '') { $values = unpack('C*', $str); return SplFixedArray::fromArray(array_values($values)); } /** * Convert an SplFixedArray of integers into a string * * @internal You should not use this directly from another application * * @param SplFixedArray $a * @return string * @throws TypeError */ public static function SplFixedArrayToString(SplFixedArray $a) { /** * @var array<int, int|string> $arr */ $arr = $a->toArray(); $c = $a->count(); array_unshift($arr, str_repeat('C', $c)); return (string) (call_user_func_array('pack', $arr)); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @return string * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedMethodCall */ public static function contextToString(SplFixedArray $ctx) { $str = ''; /** @var array<int, array<int, int>> $ctxA */ $ctxA = $ctx[0]->toArray(); # uint64_t h[8]; for ($i = 0; $i < 8; ++$i) { $str .= self::store32_le($ctxA[$i][1]); $str .= self::store32_le($ctxA[$i][0]); } # uint64_t t[2]; # uint64_t f[2]; for ($i = 1; $i < 3; ++$i) { $ctxA = $ctx[$i]->toArray(); $str .= self::store32_le($ctxA[0][1]); $str .= self::store32_le($ctxA[0][0]); $str .= self::store32_le($ctxA[1][1]); $str .= self::store32_le($ctxA[1][0]); } # uint8_t buf[2 * 128]; $str .= self::SplFixedArrayToString($ctx[3]); /** @var int $ctx4 */ $ctx4 = (int) $ctx[4]; # size_t buflen; $str .= implode('', array( self::intToChr($ctx4 & 0xff), self::intToChr(($ctx4 >> 8) & 0xff), self::intToChr(($ctx4 >> 16) & 0xff), self::intToChr(($ctx4 >> 24) & 0xff), self::intToChr(($ctx4 >> 32) & 0xff), self::intToChr(($ctx4 >> 40) & 0xff), self::intToChr(($ctx4 >> 48) & 0xff), self::intToChr(($ctx4 >> 56) & 0xff) )); # uint8_t last_node; return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23); } /** * Creates an SplFixedArray containing other SplFixedArray elements, from * a string (compatible with \Sodium\crypto_generichash_{init, update, final}) * * @internal You should not use this directly from another application * * @param string $string * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAssignment */ public static function stringToContext($string) { $ctx = self::context(); # uint64_t h[8]; for ($i = 0; $i < 8; ++$i) { $ctx[0][$i] = SplFixedArray::fromArray( array( self::load_4( self::substr($string, (($i << 3) + 4), 4) ), self::load_4( self::substr($string, (($i << 3) + 0), 4) ) ) ); } # uint64_t t[2]; # uint64_t f[2]; for ($i = 1; $i < 3; ++$i) { $ctx[$i][1] = SplFixedArray::fromArray( array( self::load_4(self::substr($string, 76 + (($i - 1) << 4), 4)), self::load_4(self::substr($string, 72 + (($i - 1) << 4), 4)) ) ); $ctx[$i][0] = SplFixedArray::fromArray( array( self::load_4(self::substr($string, 68 + (($i - 1) << 4), 4)), self::load_4(self::substr($string, 64 + (($i - 1) << 4), 4)) ) ); } # uint8_t buf[2 * 128]; $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); # uint8_t buf[2 * 128]; $int = 0; for ($i = 0; $i < 8; ++$i) { $int |= self::chrToInt($string[352 + $i]) << ($i << 3); } $ctx[4] = $int; return $ctx; } } <?php if (class_exists('ParagonIE_Sodium_Core_Util', false)) { return; } /** * Class ParagonIE_Sodium_Core_Util */ abstract class ParagonIE_Sodium_Core_Util { const U32_MAX = 0xFFFFFFFF; /** * @param int $integer * @param int $size (16, 32, 64) * @return int */ public static function abs($integer, $size = 0) { /** @var int $realSize */ $realSize = (PHP_INT_SIZE << 3) - 1; if ($size) { --$size; } else { /** @var int $size */ $size = $realSize; } $negative = -(($integer >> $size) & 1); return (int) ( ($integer ^ $negative) + (($negative >> $realSize) & 1) ); } /** * @param string $a * @param string $b * @return string * @throws SodiumException */ public static function andStrings($a, $b) { /* Type checks: */ if (!is_string($a)) { throw new TypeError('Argument 1 must be a string'); } if (!is_string($b)) { throw new TypeError('Argument 2 must be a string'); } $len = self::strlen($a); if (self::strlen($b) !== $len) { throw new SodiumException('Both strings must be of equal length to combine with bitwise AND'); } return $a & $b; } /** * Convert a binary string into a hexadecimal string without cache-timing * leaks * * @internal You should not use this directly from another application * * @param string $binaryString (raw binary) * @return string * @throws TypeError */ public static function bin2hex($binaryString) { /* Type checks: */ if (!is_string($binaryString)) { throw new TypeError('Argument 1 must be a string, ' . gettype($binaryString) . ' given.'); } $hex = ''; $len = self::strlen($binaryString); for ($i = 0; $i < $len; ++$i) { /** @var array<int, int> $chunk */ $chunk = unpack('C', $binaryString[$i]); /** @var int $c */ $c = $chunk[1] & 0xf; /** @var int $b */ $b = $chunk[1] >> 4; $hex .= pack( 'CC', (87 + $b + ((($b - 10) >> 8) & ~38)), (87 + $c + ((($c - 10) >> 8) & ~38)) ); } return $hex; } /** * Convert a binary string into a hexadecimal string without cache-timing * leaks, returning uppercase letters (as per RFC 4648) * * @internal You should not use this directly from another application * * @param string $bin_string (raw binary) * @return string * @throws TypeError */ public static function bin2hexUpper($bin_string) { $hex = ''; $len = self::strlen($bin_string); for ($i = 0; $i < $len; ++$i) { /** @var array<int, int> $chunk */ $chunk = unpack('C', $bin_string[$i]); /** * Lower 16 bits * * @var int $c */ $c = $chunk[1] & 0xf; /** * Upper 16 bits * @var int $b */ $b = $chunk[1] >> 4; /** * Use pack() and binary operators to turn the two integers * into hexadecimal characters. We don't use chr() here, because * it uses a lookup table internally and we want to avoid * cache-timing side-channels. */ $hex .= pack( 'CC', (55 + $b + ((($b - 10) >> 8) & ~6)), (55 + $c + ((($c - 10) >> 8) & ~6)) ); } return $hex; } /** * Cache-timing-safe variant of ord() * * @internal You should not use this directly from another application * * @param string $chr * @return int * @throws SodiumException * @throws TypeError */ public static function chrToInt($chr) { /* Type checks: */ if (!is_string($chr)) { throw new TypeError('Argument 1 must be a string, ' . gettype($chr) . ' given.'); } if (self::strlen($chr) !== 1) { throw new SodiumException('chrToInt() expects a string that is exactly 1 character long'); } /** @var array<int, int> $chunk */ $chunk = unpack('C', $chr); return (int) ($chunk[1]); } /** * Compares two strings. * * @internal You should not use this directly from another application * * @param string $left * @param string $right * @param int $len * @return int * @throws SodiumException * @throws TypeError */ public static function compare($left, $right, $len = null) { $leftLen = self::strlen($left); $rightLen = self::strlen($right); if ($len === null) { $len = max($leftLen, $rightLen); $left = str_pad($left, $len, "\x00", STR_PAD_RIGHT); $right = str_pad($right, $len, "\x00", STR_PAD_RIGHT); } $gt = 0; $eq = 1; $i = $len; while ($i !== 0) { --$i; $gt |= ((self::chrToInt($right[$i]) - self::chrToInt($left[$i])) >> 8) & $eq; $eq &= ((self::chrToInt($right[$i]) ^ self::chrToInt($left[$i])) - 1) >> 8; } return ($gt + $gt + $eq) - 1; } /** * If a variable does not match a given type, throw a TypeError. * * @param mixed $mixedVar * @param string $type * @param int $argumentIndex * @throws TypeError * @throws SodiumException * @return void */ public static function declareScalarType(&$mixedVar = null, $type = 'void', $argumentIndex = 0) { if (func_num_args() === 0) { /* Tautology, by default */ return; } if (func_num_args() === 1) { throw new TypeError('Declared void, but passed a variable'); } $realType = strtolower(gettype($mixedVar)); $type = strtolower($type); switch ($type) { case 'null': if ($mixedVar !== null) { throw new TypeError('Argument ' . $argumentIndex . ' must be null, ' . $realType . ' given.'); } break; case 'integer': case 'int': $allow = array('int', 'integer'); if (!in_array($type, $allow)) { throw new TypeError('Argument ' . $argumentIndex . ' must be an integer, ' . $realType . ' given.'); } $mixedVar = (int) $mixedVar; break; case 'boolean': case 'bool': $allow = array('bool', 'boolean'); if (!in_array($type, $allow)) { throw new TypeError('Argument ' . $argumentIndex . ' must be a boolean, ' . $realType . ' given.'); } $mixedVar = (bool) $mixedVar; break; case 'string': if (!is_string($mixedVar)) { throw new TypeError('Argument ' . $argumentIndex . ' must be a string, ' . $realType . ' given.'); } $mixedVar = (string) $mixedVar; break; case 'decimal': case 'double': case 'float': $allow = array('decimal', 'double', 'float'); if (!in_array($type, $allow)) { throw new TypeError('Argument ' . $argumentIndex . ' must be a float, ' . $realType . ' given.'); } $mixedVar = (float) $mixedVar; break; case 'object': if (!is_object($mixedVar)) { throw new TypeError('Argument ' . $argumentIndex . ' must be an object, ' . $realType . ' given.'); } break; case 'array': if (!is_array($mixedVar)) { if (is_object($mixedVar)) { if ($mixedVar instanceof ArrayAccess) { return; } } throw new TypeError('Argument ' . $argumentIndex . ' must be an array, ' . $realType . ' given.'); } break; default: throw new SodiumException('Unknown type (' . $realType .') does not match expect type (' . $type . ')'); } } /** * Evaluate whether or not two strings are equal (in constant-time) * * @param string $left * @param string $right * @return bool * @throws SodiumException * @throws TypeError */ public static function hashEquals($left, $right) { /* Type checks: */ if (!is_string($left)) { throw new TypeError('Argument 1 must be a string, ' . gettype($left) . ' given.'); } if (!is_string($right)) { throw new TypeError('Argument 2 must be a string, ' . gettype($right) . ' given.'); } if (is_callable('hash_equals')) { return hash_equals($left, $right); } $d = 0; /** @var int $len */ $len = self::strlen($left); if ($len !== self::strlen($right)) { return false; } for ($i = 0; $i < $len; ++$i) { $d |= self::chrToInt($left[$i]) ^ self::chrToInt($right[$i]); } if ($d !== 0) { return false; } return $left === $right; } /** * Catch hash_update() failures and throw instead of silently proceeding * * @param HashContext|resource &$hs * @param string $data * @return void * @throws SodiumException * @psalm-suppress PossiblyInvalidArgument */ protected static function hash_update(&$hs, $data) { if (!hash_update($hs, $data)) { throw new SodiumException('hash_update() failed'); } } /** * Convert a hexadecimal string into a binary string without cache-timing * leaks * * @internal You should not use this directly from another application * * @param string $hexString * @param string $ignore * @param bool $strictPadding * @return string (raw binary) * @throws RangeException * @throws TypeError */ public static function hex2bin($hexString, $ignore = '', $strictPadding = false) { /* Type checks: */ if (!is_string($hexString)) { throw new TypeError('Argument 1 must be a string, ' . gettype($hexString) . ' given.'); } if (!is_string($ignore)) { throw new TypeError('Argument 2 must be a string, ' . gettype($hexString) . ' given.'); } $hex_pos = 0; $bin = ''; $c_acc = 0; $hex_len = self::strlen($hexString); $state = 0; if (($hex_len & 1) !== 0) { if ($strictPadding) { throw new RangeException( 'Expected an even number of hexadecimal characters' ); } else { $hexString = '0' . $hexString; ++$hex_len; } } $chunk = unpack('C*', $hexString); while ($hex_pos < $hex_len) { ++$hex_pos; /** @var int $c */ $c = $chunk[$hex_pos]; $c_num = $c ^ 48; $c_num0 = ($c_num - 10) >> 8; $c_alpha = ($c & ~32) - 55; $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; if (($c_num0 | $c_alpha0) === 0) { if ($ignore && $state === 0 && strpos($ignore, self::intToChr($c)) !== false) { continue; } throw new RangeException( 'hex2bin() only expects hexadecimal characters' ); } $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); if ($state === 0) { $c_acc = $c_val * 16; } else { $bin .= pack('C', $c_acc | $c_val); } $state ^= 1; } return $bin; } /** * Turn an array of integers into a string * * @internal You should not use this directly from another application * * @param array<int, int> $ints * @return string */ public static function intArrayToString(array $ints) { $args = $ints; foreach ($args as $i => $v) { $args[$i] = (int) ($v & 0xff); } array_unshift($args, str_repeat('C', count($ints))); return (string) (call_user_func_array('pack', $args)); } /** * Cache-timing-safe variant of ord() * * @internal You should not use this directly from another application * * @param int $int * @return string * @throws TypeError */ public static function intToChr($int) { return pack('C', $int); } /** * Load a 3 character substring into an integer * * @internal You should not use this directly from another application * * @param string $string * @return int * @throws RangeException * @throws TypeError */ public static function load_3($string) { /* Type checks: */ if (!is_string($string)) { throw new TypeError('Argument 1 must be a string, ' . gettype($string) . ' given.'); } /* Input validation: */ if (self::strlen($string) < 3) { throw new RangeException( 'String must be 3 bytes or more; ' . self::strlen($string) . ' given.' ); } /** @var array<int, int> $unpacked */ $unpacked = unpack('V', $string . "\0"); return (int) ($unpacked[1] & 0xffffff); } /** * Load a 4 character substring into an integer * * @internal You should not use this directly from another application * * @param string $string * @return int * @throws RangeException * @throws TypeError */ public static function load_4($string) { /* Type checks: */ if (!is_string($string)) { throw new TypeError('Argument 1 must be a string, ' . gettype($string) . ' given.'); } /* Input validation: */ if (self::strlen($string) < 4) { throw new RangeException( 'String must be 4 bytes or more; ' . self::strlen($string) . ' given.' ); } /** @var array<int, int> $unpacked */ $unpacked = unpack('V', $string); return (int) $unpacked[1]; } /** * Load a 8 character substring into an integer * * @internal You should not use this directly from another application * * @param string $string * @return int * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function load64_le($string) { /* Type checks: */ if (!is_string($string)) { throw new TypeError('Argument 1 must be a string, ' . gettype($string) . ' given.'); } /* Input validation: */ if (self::strlen($string) < 4) { throw new RangeException( 'String must be 4 bytes or more; ' . self::strlen($string) . ' given.' ); } if (PHP_VERSION_ID >= 50603 && PHP_INT_SIZE === 8) { /** @var array<int, int> $unpacked */ $unpacked = unpack('P', $string); return (int) $unpacked[1]; } /** @var int $result */ $result = (self::chrToInt($string[0]) & 0xff); $result |= (self::chrToInt($string[1]) & 0xff) << 8; $result |= (self::chrToInt($string[2]) & 0xff) << 16; $result |= (self::chrToInt($string[3]) & 0xff) << 24; $result |= (self::chrToInt($string[4]) & 0xff) << 32; $result |= (self::chrToInt($string[5]) & 0xff) << 40; $result |= (self::chrToInt($string[6]) & 0xff) << 48; $result |= (self::chrToInt($string[7]) & 0xff) << 56; return (int) $result; } /** * @internal You should not use this directly from another application * * @param string $left * @param string $right * @return int * @throws SodiumException * @throws TypeError */ public static function memcmp($left, $right) { if (self::hashEquals($left, $right)) { return 0; } return -1; } /** * Multiply two integers in constant-time * * Micro-architecture timing side-channels caused by how your CPU * implements multiplication are best prevented by never using the * multiplication operators and ensuring that our code always takes * the same number of operations to complete, regardless of the values * of $a and $b. * * @internal You should not use this directly from another application * * @param int $a * @param int $b * @param int $size Limits the number of operations (useful for small, * constant operands) * @return int */ public static function mul($a, $b, $size = 0) { if (ParagonIE_Sodium_Compat::$fastMult) { return (int) ($a * $b); } static $defaultSize = null; /** @var int $defaultSize */ if (!$defaultSize) { /** @var int $defaultSize */ $defaultSize = (PHP_INT_SIZE << 3) - 1; } if ($size < 1) { /** @var int $size */ $size = $defaultSize; } /** @var int $size */ $c = 0; /** * Mask is either -1 or 0. * * -1 in binary looks like 0x1111 ... 1111 * 0 in binary looks like 0x0000 ... 0000 * * @var int */ $mask = -(($b >> ((int) $defaultSize)) & 1); /** * Ensure $b is a positive integer, without creating * a branching side-channel * * @var int $b */ $b = ($b & ~$mask) | ($mask & -$b); /** * Unless $size is provided: * * This loop always runs 32 times when PHP_INT_SIZE is 4. * This loop always runs 64 times when PHP_INT_SIZE is 8. */ for ($i = $size; $i >= 0; --$i) { $c += (int) ($a & -($b & 1)); $a <<= 1; $b >>= 1; } $c = (int) @($c & -1); /** * If $b was negative, we then apply the same value to $c here. * It doesn't matter much if $a was negative; the $c += above would * have produced a negative integer to begin with. But a negative $b * makes $b >>= 1 never return 0, so we would end up with incorrect * results. * * The end result is what we'd expect from integer multiplication. */ return (int) (($c & ~$mask) | ($mask & -$c)); } /** * Convert any arbitrary numbers into two 32-bit integers that represent * a 64-bit integer. * * @internal You should not use this directly from another application * * @param int|float $num * @return array<int, int> */ public static function numericTo64BitInteger($num) { $high = 0; /** @var int $low */ if (PHP_INT_SIZE === 4) { $low = (int) $num; } else { $low = $num & 0xffffffff; } if ((+(abs($num))) >= 1) { if ($num > 0) { /** @var int $high */ $high = min((+(floor($num/4294967296))), 4294967295); } else { /** @var int $high */ $high = ~~((+(ceil(($num - (+((~~($num)))))/4294967296)))); } } return array((int) $high, (int) $low); } /** * Store a 24-bit integer into a string, treating it as big-endian. * * @internal You should not use this directly from another application * * @param int $int * @return string * @throws TypeError */ public static function store_3($int) { /* Type checks: */ if (!is_int($int)) { if (is_numeric($int)) { $int = (int) $int; } else { throw new TypeError('Argument 1 must be an integer, ' . gettype($int) . ' given.'); } } /** @var string $packed */ $packed = pack('N', $int); return self::substr($packed, 1, 3); } /** * Store a 32-bit integer into a string, treating it as little-endian. * * @internal You should not use this directly from another application * * @param int $int * @return string * @throws TypeError */ public static function store32_le($int) { /* Type checks: */ if (!is_int($int)) { if (is_numeric($int)) { $int = (int) $int; } else { throw new TypeError('Argument 1 must be an integer, ' . gettype($int) . ' given.'); } } /** @var string $packed */ $packed = pack('V', $int); return $packed; } /** * Store a 32-bit integer into a string, treating it as big-endian. * * @internal You should not use this directly from another application * * @param int $int * @return string * @throws TypeError */ public static function store_4($int) { /* Type checks: */ if (!is_int($int)) { if (is_numeric($int)) { $int = (int) $int; } else { throw new TypeError('Argument 1 must be an integer, ' . gettype($int) . ' given.'); } } /** @var string $packed */ $packed = pack('N', $int); return $packed; } /** * Stores a 64-bit integer as an string, treating it as little-endian. * * @internal You should not use this directly from another application * * @param int $int * @return string * @throws TypeError */ public static function store64_le($int) { /* Type checks: */ if (!is_int($int)) { if (is_numeric($int)) { $int = (int) $int; } else { throw new TypeError('Argument 1 must be an integer, ' . gettype($int) . ' given.'); } } if (PHP_INT_SIZE === 8) { if (PHP_VERSION_ID >= 50603) { /** @var string $packed */ $packed = pack('P', $int); return $packed; } return self::intToChr($int & 0xff) . self::intToChr(($int >> 8) & 0xff) . self::intToChr(($int >> 16) & 0xff) . self::intToChr(($int >> 24) & 0xff) . self::intToChr(($int >> 32) & 0xff) . self::intToChr(($int >> 40) & 0xff) . self::intToChr(($int >> 48) & 0xff) . self::intToChr(($int >> 56) & 0xff); } if ($int > PHP_INT_MAX) { list($hiB, $int) = self::numericTo64BitInteger($int); } else { $hiB = 0; } return self::intToChr(($int ) & 0xff) . self::intToChr(($int >> 8) & 0xff) . self::intToChr(($int >> 16) & 0xff) . self::intToChr(($int >> 24) & 0xff) . self::intToChr($hiB & 0xff) . self::intToChr(($hiB >> 8) & 0xff) . self::intToChr(($hiB >> 16) & 0xff) . self::intToChr(($hiB >> 24) & 0xff); } /** * Safe string length * * @internal You should not use this directly from another application * * @ref mbstring.func_overload * * @param string $str * @return int * @throws TypeError */ public static function strlen($str) { /* Type checks: */ if (!is_string($str)) { throw new TypeError('String expected'); } return (int) ( self::isMbStringOverride() ? mb_strlen($str, '8bit') : strlen($str) ); } /** * Turn a string into an array of integers * * @internal You should not use this directly from another application * * @param string $string * @return array<int, int> * @throws TypeError */ public static function stringToIntArray($string) { if (!is_string($string)) { throw new TypeError('String expected'); } /** * @var array<int, int> */ $values = array_values( unpack('C*', $string) ); return $values; } /** * Safe substring * * @internal You should not use this directly from another application * * @ref mbstring.func_overload * * @param string $str * @param int $start * @param int $length * @return string * @throws TypeError */ public static function substr($str, $start = 0, $length = null) { /* Type checks: */ if (!is_string($str)) { throw new TypeError('String expected'); } if ($length === 0) { return ''; } if (self::isMbStringOverride()) { if (PHP_VERSION_ID < 50400 && $length === null) { $length = self::strlen($str); } $sub = (string) mb_substr($str, $start, $length, '8bit'); } elseif ($length === null) { $sub = (string) substr($str, $start); } else { $sub = (string) substr($str, $start, $length); } if ($sub !== '') { return $sub; } return ''; } /** * Compare a 16-character byte string in constant time. * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @return bool * @throws SodiumException * @throws TypeError */ public static function verify_16($a, $b) { /* Type checks: */ if (!is_string($a)) { throw new TypeError('String expected'); } if (!is_string($b)) { throw new TypeError('String expected'); } return self::hashEquals( self::substr($a, 0, 16), self::substr($b, 0, 16) ); } /** * Compare a 32-character byte string in constant time. * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @return bool * @throws SodiumException * @throws TypeError */ public static function verify_32($a, $b) { /* Type checks: */ if (!is_string($a)) { throw new TypeError('String expected'); } if (!is_string($b)) { throw new TypeError('String expected'); } return self::hashEquals( self::substr($a, 0, 32), self::substr($b, 0, 32) ); } /** * Calculate $a ^ $b for two strings. * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @return string * @throws TypeError */ public static function xorStrings($a, $b) { /* Type checks: */ if (!is_string($a)) { throw new TypeError('Argument 1 must be a string'); } if (!is_string($b)) { throw new TypeError('Argument 2 must be a string'); } return (string) ($a ^ $b); } /** * Returns whether or not mbstring.func_overload is in effect. * * @internal You should not use this directly from another application * * Note: MB_OVERLOAD_STRING === 2, but we don't reference the constant * (for nuisance-free PHP 8 support) * * @return bool */ protected static function isMbStringOverride() { static $mbstring = null; if ($mbstring === null) { if (!defined('MB_OVERLOAD_STRING')) { $mbstring = false; return $mbstring; } $mbstring = extension_loaded('mbstring') && defined('MB_OVERLOAD_STRING') && ((int) (ini_get('mbstring.func_overload')) & 2); // MB_OVERLOAD_STRING === 2 } /** @var bool $mbstring */ return $mbstring; } } <?php if (class_exists('ParagonIE_Sodium_Core_Salsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core_Salsa20 */ abstract class ParagonIE_Sodium_Core_Salsa20 extends ParagonIE_Sodium_Core_Util { const ROUNDS = 20; /** * Calculate an salsa20 hash of a single block * * @internal You should not use this directly from another application * * @param string $in * @param string $k * @param string|null $c * @return string * @throws TypeError */ public static function core_salsa20($in, $k, $c = null) { if (self::strlen($k) < 32) { throw new RangeException('Key must be 32 bytes long'); } if ($c === null) { $j0 = $x0 = 0x61707865; $j5 = $x5 = 0x3320646e; $j10 = $x10 = 0x79622d32; $j15 = $x15 = 0x6b206574; } else { $j0 = $x0 = self::load_4(self::substr($c, 0, 4)); $j5 = $x5 = self::load_4(self::substr($c, 4, 4)); $j10 = $x10 = self::load_4(self::substr($c, 8, 4)); $j15 = $x15 = self::load_4(self::substr($c, 12, 4)); } $j1 = $x1 = self::load_4(self::substr($k, 0, 4)); $j2 = $x2 = self::load_4(self::substr($k, 4, 4)); $j3 = $x3 = self::load_4(self::substr($k, 8, 4)); $j4 = $x4 = self::load_4(self::substr($k, 12, 4)); $j6 = $x6 = self::load_4(self::substr($in, 0, 4)); $j7 = $x7 = self::load_4(self::substr($in, 4, 4)); $j8 = $x8 = self::load_4(self::substr($in, 8, 4)); $j9 = $x9 = self::load_4(self::substr($in, 12, 4)); $j11 = $x11 = self::load_4(self::substr($k, 16, 4)); $j12 = $x12 = self::load_4(self::substr($k, 20, 4)); $j13 = $x13 = self::load_4(self::substr($k, 24, 4)); $j14 = $x14 = self::load_4(self::substr($k, 28, 4)); for ($i = self::ROUNDS; $i > 0; $i -= 2) { $x4 ^= self::rotate($x0 + $x12, 7); $x8 ^= self::rotate($x4 + $x0, 9); $x12 ^= self::rotate($x8 + $x4, 13); $x0 ^= self::rotate($x12 + $x8, 18); $x9 ^= self::rotate($x5 + $x1, 7); $x13 ^= self::rotate($x9 + $x5, 9); $x1 ^= self::rotate($x13 + $x9, 13); $x5 ^= self::rotate($x1 + $x13, 18); $x14 ^= self::rotate($x10 + $x6, 7); $x2 ^= self::rotate($x14 + $x10, 9); $x6 ^= self::rotate($x2 + $x14, 13); $x10 ^= self::rotate($x6 + $x2, 18); $x3 ^= self::rotate($x15 + $x11, 7); $x7 ^= self::rotate($x3 + $x15, 9); $x11 ^= self::rotate($x7 + $x3, 13); $x15 ^= self::rotate($x11 + $x7, 18); $x1 ^= self::rotate($x0 + $x3, 7); $x2 ^= self::rotate($x1 + $x0, 9); $x3 ^= self::rotate($x2 + $x1, 13); $x0 ^= self::rotate($x3 + $x2, 18); $x6 ^= self::rotate($x5 + $x4, 7); $x7 ^= self::rotate($x6 + $x5, 9); $x4 ^= self::rotate($x7 + $x6, 13); $x5 ^= self::rotate($x4 + $x7, 18); $x11 ^= self::rotate($x10 + $x9, 7); $x8 ^= self::rotate($x11 + $x10, 9); $x9 ^= self::rotate($x8 + $x11, 13); $x10 ^= self::rotate($x9 + $x8, 18); $x12 ^= self::rotate($x15 + $x14, 7); $x13 ^= self::rotate($x12 + $x15, 9); $x14 ^= self::rotate($x13 + $x12, 13); $x15 ^= self::rotate($x14 + $x13, 18); } $x0 += $j0; $x1 += $j1; $x2 += $j2; $x3 += $j3; $x4 += $j4; $x5 += $j5; $x6 += $j6; $x7 += $j7; $x8 += $j8; $x9 += $j9; $x10 += $j10; $x11 += $j11; $x12 += $j12; $x13 += $j13; $x14 += $j14; $x15 += $j15; return self::store32_le($x0) . self::store32_le($x1) . self::store32_le($x2) . self::store32_le($x3) . self::store32_le($x4) . self::store32_le($x5) . self::store32_le($x6) . self::store32_le($x7) . self::store32_le($x8) . self::store32_le($x9) . self::store32_le($x10) . self::store32_le($x11) . self::store32_le($x12) . self::store32_le($x13) . self::store32_le($x14) . self::store32_le($x15); } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20($len, $nonce, $key) { if (self::strlen($key) !== 32) { throw new RangeException('Key must be 32 bytes long'); } $kcopy = '' . $key; $in = self::substr($nonce, 0, 8) . str_repeat("\0", 8); $c = ''; while ($len >= 64) { $c .= self::core_salsa20($in, $kcopy, null); $u = 1; // Internal counter. for ($i = 8; $i < 16; ++$i) { $u += self::chrToInt($in[$i]); $in[$i] = self::intToChr($u & 0xff); $u >>= 8; } $len -= 64; } if ($len > 0) { $c .= self::substr( self::core_salsa20($in, $kcopy, null), 0, $len ); } try { ParagonIE_Sodium_Compat::memzero($kcopy); } catch (SodiumException $ex) { $kcopy = null; } return $c; } /** * @internal You should not use this directly from another application * * @param string $m * @param string $n * @param int $ic * @param string $k * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20_xor_ic($m, $n, $ic, $k) { $mlen = self::strlen($m); if ($mlen < 1) { return ''; } $kcopy = self::substr($k, 0, 32); $in = self::substr($n, 0, 8); // Initialize the counter $in .= ParagonIE_Sodium_Core_Util::store64_le($ic); $c = ''; while ($mlen >= 64) { $block = self::core_salsa20($in, $kcopy, null); $c .= self::xorStrings( self::substr($m, 0, 64), self::substr($block, 0, 64) ); $u = 1; for ($i = 8; $i < 16; ++$i) { $u += self::chrToInt($in[$i]); $in[$i] = self::intToChr($u & 0xff); $u >>= 8; } $mlen -= 64; $m = self::substr($m, 64); } if ($mlen) { $block = self::core_salsa20($in, $kcopy, null); $c .= self::xorStrings( self::substr($m, 0, $mlen), self::substr($block, 0, $mlen) ); } try { ParagonIE_Sodium_Compat::memzero($block); ParagonIE_Sodium_Compat::memzero($kcopy); } catch (SodiumException $ex) { $block = null; $kcopy = null; } return $c; } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20_xor($message, $nonce, $key) { return self::xorStrings( $message, self::salsa20( self::strlen($message), $nonce, $key ) ); } /** * @internal You should not use this directly from another application * * @param int $u * @param int $c * @return int */ public static function rotate($u, $c) { $u &= 0xffffffff; $c %= 32; return (int) (0xffffffff & ( ($u << $c) | ($u >> (32 - $c)) ) ); } } <?php if (class_exists('ParagonIE_Sodium_Core_AES_Block', false)) { return; } /** * @internal This should only be used by sodium_compat */ class ParagonIE_Sodium_Core_AES_Block extends SplFixedArray { /** * @var array<int, int> */ protected $values = array(); /** * @var int */ protected $size; /** * @param int $size */ public function __construct($size = 8) { parent::__construct($size); $this->size = $size; $this->values = array_fill(0, $size, 0); } /** * @return self */ public static function init() { return new self(8); } /** * @internal You should not use this directly from another application * * @param array<int, int> $array * @param bool $save_indexes * @return self * * @psalm-suppress MethodSignatureMismatch */ #[ReturnTypeWillChange] public static function fromArray($array, $save_indexes = null) { $count = count($array); if ($save_indexes) { $keys = array_keys($array); } else { $keys = range(0, $count - 1); } $array = array_values($array); /** @var array<int, int> $keys */ $obj = new ParagonIE_Sodium_Core_AES_Block(); if ($save_indexes) { for ($i = 0; $i < $count; ++$i) { $obj->offsetSet($keys[$i], $array[$i]); } } else { for ($i = 0; $i < $count; ++$i) { $obj->offsetSet($i, $array[$i]); } } return $obj; } /** * @internal You should not use this directly from another application * * @param int|null $offset * @param int $value * @return void * * @psalm-suppress MethodSignatureMismatch * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!is_int($value)) { throw new InvalidArgumentException('Expected an integer'); } if (is_null($offset)) { $this->values[] = $value; } else { $this->values[$offset] = $value; } } /** * @internal You should not use this directly from another application * * @param int $offset * @return bool * * @psalm-suppress MethodSignatureMismatch * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->values[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return void * * @psalm-suppress MethodSignatureMismatch * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->values[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return int * * @psalm-suppress MethodSignatureMismatch * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetGet($offset) { if (!isset($this->values[$offset])) { $this->values[$offset] = 0; } return (int) ($this->values[$offset]); } /** * @internal You should not use this directly from another application * * @return array */ public function __debugInfo() { $out = array(); foreach ($this->values as $v) { $out[] = str_pad(dechex($v), 8, '0', STR_PAD_LEFT); } return array(implode(', ', $out)); /* return array(implode(', ', $this->values)); */ } /** * @param int $cl low bit mask * @param int $ch high bit mask * @param int $s shift * @param int $x index 1 * @param int $y index 2 * @return self */ public function swapN($cl, $ch, $s, $x, $y) { static $u32mask = ParagonIE_Sodium_Core_Util::U32_MAX; $a = $this->values[$x] & $u32mask; $b = $this->values[$y] & $u32mask; // (x) = (a & cl) | ((b & cl) << (s)); $this->values[$x] = ($a & $cl) | ((($b & $cl) << $s) & $u32mask); // (y) = ((a & ch) >> (s)) | (b & ch); $this->values[$y] = ((($a & $ch) & $u32mask) >> $s) | ($b & $ch); return $this; } /** * @param int $x index 1 * @param int $y index 2 * @return self */ public function swap2($x, $y) { return $this->swapN(0x55555555, 0xAAAAAAAA, 1, $x, $y); } /** * @param int $x index 1 * @param int $y index 2 * @return self */ public function swap4($x, $y) { return $this->swapN(0x33333333, 0xCCCCCCCC, 2, $x, $y); } /** * @param int $x index 1 * @param int $y index 2 * @return self */ public function swap8($x, $y) { return $this->swapN(0x0F0F0F0F, 0xF0F0F0F0, 4, $x, $y); } /** * @return self */ public function orthogonalize() { return $this ->swap2(0, 1) ->swap2(2, 3) ->swap2(4, 5) ->swap2(6, 7) ->swap4(0, 2) ->swap4(1, 3) ->swap4(4, 6) ->swap4(5, 7) ->swap8(0, 4) ->swap8(1, 5) ->swap8(2, 6) ->swap8(3, 7); } /** * @return self */ public function shiftRows() { for ($i = 0; $i < 8; ++$i) { $x = $this->values[$i] & ParagonIE_Sodium_Core_Util::U32_MAX; $this->values[$i] = ( ($x & 0x000000FF) | (($x & 0x0000FC00) >> 2) | (($x & 0x00000300) << 6) | (($x & 0x00F00000) >> 4) | (($x & 0x000F0000) << 4) | (($x & 0xC0000000) >> 6) | (($x & 0x3F000000) << 2) ) & ParagonIE_Sodium_Core_Util::U32_MAX; } return $this; } /** * @param int $x * @return int */ public static function rotr16($x) { return (($x << 16) & ParagonIE_Sodium_Core_Util::U32_MAX) | ($x >> 16); } /** * @return self */ public function mixColumns() { $q0 = $this->values[0]; $q1 = $this->values[1]; $q2 = $this->values[2]; $q3 = $this->values[3]; $q4 = $this->values[4]; $q5 = $this->values[5]; $q6 = $this->values[6]; $q7 = $this->values[7]; $r0 = (($q0 >> 8) | ($q0 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r1 = (($q1 >> 8) | ($q1 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r2 = (($q2 >> 8) | ($q2 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r3 = (($q3 >> 8) | ($q3 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r4 = (($q4 >> 8) | ($q4 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r5 = (($q5 >> 8) | ($q5 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r6 = (($q6 >> 8) | ($q6 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r7 = (($q7 >> 8) | ($q7 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $this->values[0] = $q7 ^ $r7 ^ $r0 ^ self::rotr16($q0 ^ $r0); $this->values[1] = $q0 ^ $r0 ^ $q7 ^ $r7 ^ $r1 ^ self::rotr16($q1 ^ $r1); $this->values[2] = $q1 ^ $r1 ^ $r2 ^ self::rotr16($q2 ^ $r2); $this->values[3] = $q2 ^ $r2 ^ $q7 ^ $r7 ^ $r3 ^ self::rotr16($q3 ^ $r3); $this->values[4] = $q3 ^ $r3 ^ $q7 ^ $r7 ^ $r4 ^ self::rotr16($q4 ^ $r4); $this->values[5] = $q4 ^ $r4 ^ $r5 ^ self::rotr16($q5 ^ $r5); $this->values[6] = $q5 ^ $r5 ^ $r6 ^ self::rotr16($q6 ^ $r6); $this->values[7] = $q6 ^ $r6 ^ $r7 ^ self::rotr16($q7 ^ $r7); return $this; } /** * @return self */ public function inverseMixColumns() { $q0 = $this->values[0]; $q1 = $this->values[1]; $q2 = $this->values[2]; $q3 = $this->values[3]; $q4 = $this->values[4]; $q5 = $this->values[5]; $q6 = $this->values[6]; $q7 = $this->values[7]; $r0 = (($q0 >> 8) | ($q0 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r1 = (($q1 >> 8) | ($q1 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r2 = (($q2 >> 8) | ($q2 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r3 = (($q3 >> 8) | ($q3 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r4 = (($q4 >> 8) | ($q4 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r5 = (($q5 >> 8) | ($q5 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r6 = (($q6 >> 8) | ($q6 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $r7 = (($q7 >> 8) | ($q7 << 24)) & ParagonIE_Sodium_Core_Util::U32_MAX; $this->values[0] = $q5 ^ $q6 ^ $q7 ^ $r0 ^ $r5 ^ $r7 ^ self::rotr16($q0 ^ $q5 ^ $q6 ^ $r0 ^ $r5); $this->values[1] = $q0 ^ $q5 ^ $r0 ^ $r1 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q1 ^ $q5 ^ $q7 ^ $r1 ^ $r5 ^ $r6); $this->values[2] = $q0 ^ $q1 ^ $q6 ^ $r1 ^ $r2 ^ $r6 ^ $r7 ^ self::rotr16($q0 ^ $q2 ^ $q6 ^ $r2 ^ $r6 ^ $r7); $this->values[3] = $q0 ^ $q1 ^ $q2 ^ $q5 ^ $q6 ^ $r0 ^ $r2 ^ $r3 ^ $r5 ^ self::rotr16($q0 ^ $q1 ^ $q3 ^ $q5 ^ $q6 ^ $q7 ^ $r0 ^ $r3 ^ $r5 ^ $r7); $this->values[4] = $q1 ^ $q2 ^ $q3 ^ $q5 ^ $r1 ^ $r3 ^ $r4 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q1 ^ $q2 ^ $q4 ^ $q5 ^ $q7 ^ $r1 ^ $r4 ^ $r5 ^ $r6); $this->values[5] = $q2 ^ $q3 ^ $q4 ^ $q6 ^ $r2 ^ $r4 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q2 ^ $q3 ^ $q5 ^ $q6 ^ $r2 ^ $r5 ^ $r6 ^ $r7); $this->values[6] = $q3 ^ $q4 ^ $q5 ^ $q7 ^ $r3 ^ $r5 ^ $r6 ^ $r7 ^ self::rotr16($q3 ^ $q4 ^ $q6 ^ $q7 ^ $r3 ^ $r6 ^ $r7); $this->values[7] = $q4 ^ $q5 ^ $q6 ^ $r4 ^ $r6 ^ $r7 ^ self::rotr16($q4 ^ $q5 ^ $q7 ^ $r4 ^ $r7); return $this; } /** * @return self */ public function inverseShiftRows() { for ($i = 0; $i < 8; ++$i) { $x = $this->values[$i]; $this->values[$i] = ParagonIE_Sodium_Core_Util::U32_MAX & ( ($x & 0x000000FF) | (($x & 0x00003F00) << 2) | (($x & 0x0000C000) >> 6) | (($x & 0x000F0000) << 4) | (($x & 0x00F00000) >> 4) | (($x & 0x03000000) << 6) | (($x & 0xFC000000) >> 2) ); } return $this; } } <?php if (class_exists('ParagonIE_Sodium_Core_AES_Expanded', false)) { return; } /** * @internal This should only be used by sodium_compat */ class ParagonIE_Sodium_Core_AES_Expanded extends ParagonIE_Sodium_Core_AES_KeySchedule { /** @var bool $expanded */ protected $expanded = true; } <?php if (class_exists('ParagonIE_Sodium_Core_AES_KeySchedule', false)) { return; } /** * @internal This should only be used by sodium_compat */ class ParagonIE_Sodium_Core_AES_KeySchedule { /** @var array<int, int> $skey -- has size 120 */ protected $skey; /** @var bool $expanded */ protected $expanded = false; /** @var int $numRounds */ private $numRounds; /** * @param array $skey * @param int $numRounds */ public function __construct(array $skey, $numRounds = 10) { $this->skey = $skey; $this->numRounds = $numRounds; } /** * Get a value at an arbitrary index. Mostly used for unit testing. * * @param int $i * @return int */ public function get($i) { return $this->skey[$i]; } /** * @return int */ public function getNumRounds() { return $this->numRounds; } /** * @param int $offset * @return ParagonIE_Sodium_Core_AES_Block */ public function getRoundKey($offset) { return ParagonIE_Sodium_Core_AES_Block::fromArray( array_slice($this->skey, $offset, 8) ); } /** * Return an expanded key schedule * * @return ParagonIE_Sodium_Core_AES_Expanded */ public function expand() { $exp = new ParagonIE_Sodium_Core_AES_Expanded( array_fill(0, 120, 0), $this->numRounds ); $n = ($exp->numRounds + 1) << 2; for ($u = 0, $v = 0; $u < $n; ++$u, $v += 2) { $x = $y = $this->skey[$u]; $x &= 0x55555555; $exp->skey[$v] = ($x | ($x << 1)) & ParagonIE_Sodium_Core_Util::U32_MAX; $y &= 0xAAAAAAAA; $exp->skey[$v + 1] = ($y | ($y >> 1)) & ParagonIE_Sodium_Core_Util::U32_MAX; } return $exp; } } <?php if (class_exists('ParagonIE_Sodium_Core_X25519', false)) { return; } /** * Class ParagonIE_Sodium_Core_X25519 */ abstract class ParagonIE_Sodium_Core_X25519 extends ParagonIE_Sodium_Core_Curve25519 { /** * Alters the objects passed to this method in place. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @param int $b * @return void * @psalm-suppress MixedAssignment */ public static function fe_cswap( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g, $b = 0 ) { $f0 = (int) $f[0]; $f1 = (int) $f[1]; $f2 = (int) $f[2]; $f3 = (int) $f[3]; $f4 = (int) $f[4]; $f5 = (int) $f[5]; $f6 = (int) $f[6]; $f7 = (int) $f[7]; $f8 = (int) $f[8]; $f9 = (int) $f[9]; $g0 = (int) $g[0]; $g1 = (int) $g[1]; $g2 = (int) $g[2]; $g3 = (int) $g[3]; $g4 = (int) $g[4]; $g5 = (int) $g[5]; $g6 = (int) $g[6]; $g7 = (int) $g[7]; $g8 = (int) $g[8]; $g9 = (int) $g[9]; $b = -$b; $x0 = ($f0 ^ $g0) & $b; $x1 = ($f1 ^ $g1) & $b; $x2 = ($f2 ^ $g2) & $b; $x3 = ($f3 ^ $g3) & $b; $x4 = ($f4 ^ $g4) & $b; $x5 = ($f5 ^ $g5) & $b; $x6 = ($f6 ^ $g6) & $b; $x7 = ($f7 ^ $g7) & $b; $x8 = ($f8 ^ $g8) & $b; $x9 = ($f9 ^ $g9) & $b; $f[0] = $f0 ^ $x0; $f[1] = $f1 ^ $x1; $f[2] = $f2 ^ $x2; $f[3] = $f3 ^ $x3; $f[4] = $f4 ^ $x4; $f[5] = $f5 ^ $x5; $f[6] = $f6 ^ $x6; $f[7] = $f7 ^ $x7; $f[8] = $f8 ^ $x8; $f[9] = $f9 ^ $x9; $g[0] = $g0 ^ $x0; $g[1] = $g1 ^ $x1; $g[2] = $g2 ^ $x2; $g[3] = $g3 ^ $x3; $g[4] = $g4 ^ $x4; $g[5] = $g5 ^ $x5; $g[6] = $g6 ^ $x6; $g[7] = $g7 ^ $x7; $g[8] = $g8 ^ $x8; $g[9] = $g9 ^ $x9; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_mul121666(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $h = array( self::mul((int) $f[0], 121666, 17), self::mul((int) $f[1], 121666, 17), self::mul((int) $f[2], 121666, 17), self::mul((int) $f[3], 121666, 17), self::mul((int) $f[4], 121666, 17), self::mul((int) $f[5], 121666, 17), self::mul((int) $f[6], 121666, 17), self::mul((int) $f[7], 121666, 17), self::mul((int) $f[8], 121666, 17), self::mul((int) $f[9], 121666, 17) ); /** @var int $carry9 */ $carry9 = ($h[9] + (1 << 24)) >> 25; $h[0] += self::mul($carry9, 19, 5); $h[9] -= $carry9 << 25; /** @var int $carry1 */ $carry1 = ($h[1] + (1 << 24)) >> 25; $h[2] += $carry1; $h[1] -= $carry1 << 25; /** @var int $carry3 */ $carry3 = ($h[3] + (1 << 24)) >> 25; $h[4] += $carry3; $h[3] -= $carry3 << 25; /** @var int $carry5 */ $carry5 = ($h[5] + (1 << 24)) >> 25; $h[6] += $carry5; $h[5] -= $carry5 << 25; /** @var int $carry7 */ $carry7 = ($h[7] + (1 << 24)) >> 25; $h[8] += $carry7; $h[7] -= $carry7 << 25; /** @var int $carry0 */ $carry0 = ($h[0] + (1 << 25)) >> 26; $h[1] += $carry0; $h[0] -= $carry0 << 26; /** @var int $carry2 */ $carry2 = ($h[2] + (1 << 25)) >> 26; $h[3] += $carry2; $h[2] -= $carry2 << 26; /** @var int $carry4 */ $carry4 = ($h[4] + (1 << 25)) >> 26; $h[5] += $carry4; $h[4] -= $carry4 << 26; /** @var int $carry6 */ $carry6 = ($h[6] + (1 << 25)) >> 26; $h[7] += $carry6; $h[6] -= $carry6 << 26; /** @var int $carry8 */ $carry8 = ($h[8] + (1 << 25)) >> 26; $h[9] += $carry8; $h[8] -= $carry8 << 26; foreach ($h as $i => $value) { $h[$i] = (int) $value; } return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h); } /** * @internal You should not use this directly from another application * * Inline comments preceded by # are from libsodium's ref10 code. * * @param string $n * @param string $p * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_scalarmult_curve25519_ref10($n, $p) { # for (i = 0;i < 32;++i) e[i] = n[i]; $e = '' . $n; # e[0] &= 248; $e[0] = self::intToChr( self::chrToInt($e[0]) & 248 ); # e[31] &= 127; # e[31] |= 64; $e[31] = self::intToChr( (self::chrToInt($e[31]) & 127) | 64 ); # fe_frombytes(x1,p); $x1 = self::fe_frombytes($p); # fe_1(x2); $x2 = self::fe_1(); # fe_0(z2); $z2 = self::fe_0(); # fe_copy(x3,x1); $x3 = self::fe_copy($x1); # fe_1(z3); $z3 = self::fe_1(); # swap = 0; /** @var int $swap */ $swap = 0; # for (pos = 254;pos >= 0;--pos) { for ($pos = 254; $pos >= 0; --$pos) { # b = e[pos / 8] >> (pos & 7); /** @var int $b */ $b = self::chrToInt( $e[(int) floor($pos / 8)] ) >> ($pos & 7); # b &= 1; $b &= 1; # swap ^= b; $swap ^= $b; # fe_cswap(x2,x3,swap); self::fe_cswap($x2, $x3, $swap); # fe_cswap(z2,z3,swap); self::fe_cswap($z2, $z3, $swap); # swap = b; $swap = $b; # fe_sub(tmp0,x3,z3); $tmp0 = self::fe_sub($x3, $z3); # fe_sub(tmp1,x2,z2); $tmp1 = self::fe_sub($x2, $z2); # fe_add(x2,x2,z2); $x2 = self::fe_add($x2, $z2); # fe_add(z2,x3,z3); $z2 = self::fe_add($x3, $z3); # fe_mul(z3,tmp0,x2); $z3 = self::fe_mul($tmp0, $x2); # fe_mul(z2,z2,tmp1); $z2 = self::fe_mul($z2, $tmp1); # fe_sq(tmp0,tmp1); $tmp0 = self::fe_sq($tmp1); # fe_sq(tmp1,x2); $tmp1 = self::fe_sq($x2); # fe_add(x3,z3,z2); $x3 = self::fe_add($z3, $z2); # fe_sub(z2,z3,z2); $z2 = self::fe_sub($z3, $z2); # fe_mul(x2,tmp1,tmp0); $x2 = self::fe_mul($tmp1, $tmp0); # fe_sub(tmp1,tmp1,tmp0); $tmp1 = self::fe_sub($tmp1, $tmp0); # fe_sq(z2,z2); $z2 = self::fe_sq($z2); # fe_mul121666(z3,tmp1); $z3 = self::fe_mul121666($tmp1); # fe_sq(x3,x3); $x3 = self::fe_sq($x3); # fe_add(tmp0,tmp0,z3); $tmp0 = self::fe_add($tmp0, $z3); # fe_mul(z3,x1,z2); $z3 = self::fe_mul($x1, $z2); # fe_mul(z2,tmp1,tmp0); $z2 = self::fe_mul($tmp1, $tmp0); } # fe_cswap(x2,x3,swap); self::fe_cswap($x2, $x3, $swap); # fe_cswap(z2,z3,swap); self::fe_cswap($z2, $z3, $swap); # fe_invert(z2,z2); $z2 = self::fe_invert($z2); # fe_mul(x2,x2,z2); $x2 = self::fe_mul($x2, $z2); # fe_tobytes(q,x2); return self::fe_tobytes($x2); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY * @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function edwards_to_montgomery( ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY, ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ ) { $tempX = self::fe_add($edwardsZ, $edwardsY); $tempZ = self::fe_sub($edwardsZ, $edwardsY); $tempZ = self::fe_invert($tempZ); return self::fe_mul($tempX, $tempZ); } /** * @internal You should not use this directly from another application * * @param string $n * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_scalarmult_curve25519_ref10_base($n) { # for (i = 0;i < 32;++i) e[i] = n[i]; $e = '' . $n; # e[0] &= 248; $e[0] = self::intToChr( self::chrToInt($e[0]) & 248 ); # e[31] &= 127; # e[31] |= 64; $e[31] = self::intToChr( (self::chrToInt($e[31]) & 127) | 64 ); $A = self::ge_scalarmult_base($e); if ( !($A->Y instanceof ParagonIE_Sodium_Core_Curve25519_Fe) || !($A->Z instanceof ParagonIE_Sodium_Core_Curve25519_Fe) ) { throw new TypeError('Null points encountered'); } $pk = self::edwards_to_montgomery($A->Y, $A->Z); return self::fe_tobytes($pk); } } <?php if (class_exists('SplFixedArray')) { return; } /** * The SplFixedArray class provides the main functionalities of array. The * main differences between a SplFixedArray and a normal PHP array is that * the SplFixedArray is of fixed length and allows only integers within * the range as indexes. The advantage is that it allows a faster array * implementation. */ class SplFixedArray implements Iterator, ArrayAccess, Countable { /** @var array<int, mixed> */ private $internalArray = array(); /** @var int $size */ private $size = 0; /** * SplFixedArray constructor. * @param int $size */ public function __construct($size = 0) { $this->size = $size; $this->internalArray = array(); } /** * @return int */ public function count() { return count($this->internalArray); } /** * @return array */ public function toArray() { ksort($this->internalArray); return (array) $this->internalArray; } /** * @param array $array * @param bool $save_indexes * @return SplFixedArray * @psalm-suppress MixedAssignment */ public static function fromArray(array $array, $save_indexes = true) { $self = new SplFixedArray(count($array)); if($save_indexes) { foreach($array as $key => $value) { $self[(int) $key] = $value; } } else { $i = 0; foreach (array_values($array) as $value) { $self[$i] = $value; $i++; } } return $self; } /** * @return int */ public function getSize() { return $this->size; } /** * @param int $size * @return bool */ public function setSize($size) { $this->size = $size; return true; } /** * @param string|int $index * @return bool */ public function offsetExists($index) { return array_key_exists((int) $index, $this->internalArray); } /** * @param string|int $index * @return mixed */ public function offsetGet($index) { /** @psalm-suppress MixedReturnStatement */ return $this->internalArray[(int) $index]; } /** * @param string|int $index * @param mixed $newval * @psalm-suppress MixedAssignment */ public function offsetSet($index, $newval) { $this->internalArray[(int) $index] = $newval; } /** * @param string|int $index */ public function offsetUnset($index) { unset($this->internalArray[(int) $index]); } /** * Rewind iterator back to the start * @link https://php.net/manual/en/splfixedarray.rewind.php * @return void * @since 5.3.0 */ public function rewind() { reset($this->internalArray); } /** * Return current array entry * @link https://php.net/manual/en/splfixedarray.current.php * @return mixed The current element value. * @since 5.3.0 */ public function current() { /** @psalm-suppress MixedReturnStatement */ return current($this->internalArray); } /** * Return current array index * @return int The current array index. */ public function key() { return key($this->internalArray); } /** * @return void */ public function next() { next($this->internalArray); } /** * Check whether the array contains more elements * @link https://php.net/manual/en/splfixedarray.valid.php * @return bool true if the array contains any more elements, false otherwise. */ public function valid() { if (empty($this->internalArray)) { return false; } $result = next($this->internalArray) !== false; prev($this->internalArray); return $result; } /** * Do nothing. */ public function __wakeup() { // NOP } }<?php if (class_exists('ParagonIE_Sodium_Crypto', false)) { return; } /** * Class ParagonIE_Sodium_Crypto * * ATTENTION! * * If you are using this library, you should be using * ParagonIE_Sodium_Compat in your code, not this class. */ abstract class ParagonIE_Sodium_Crypto { const aead_chacha20poly1305_KEYBYTES = 32; const aead_chacha20poly1305_NSECBYTES = 0; const aead_chacha20poly1305_NPUBBYTES = 8; const aead_chacha20poly1305_ABYTES = 16; const aead_chacha20poly1305_IETF_KEYBYTES = 32; const aead_chacha20poly1305_IETF_NSECBYTES = 0; const aead_chacha20poly1305_IETF_NPUBBYTES = 12; const aead_chacha20poly1305_IETF_ABYTES = 16; const aead_xchacha20poly1305_IETF_KEYBYTES = 32; const aead_xchacha20poly1305_IETF_NSECBYTES = 0; const aead_xchacha20poly1305_IETF_NPUBBYTES = 24; const aead_xchacha20poly1305_IETF_ABYTES = 16; const box_curve25519xsalsa20poly1305_SEEDBYTES = 32; const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; const box_curve25519xsalsa20poly1305_NONCEBYTES = 24; const box_curve25519xsalsa20poly1305_MACBYTES = 16; const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; const box_curve25519xsalsa20poly1305_ZEROBYTES = 32; const onetimeauth_poly1305_BYTES = 16; const onetimeauth_poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_NONCEBYTES = 24; const secretbox_xsalsa20poly1305_MACBYTES = 16; const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; const secretbox_xsalsa20poly1305_ZEROBYTES = 32; const secretbox_xchacha20poly1305_KEYBYTES = 32; const secretbox_xchacha20poly1305_NONCEBYTES = 24; const secretbox_xchacha20poly1305_MACBYTES = 16; const secretbox_xchacha20poly1305_BOXZEROBYTES = 16; const secretbox_xchacha20poly1305_ZEROBYTES = 32; const stream_salsa20_KEYBYTES = 32; /** * AEAD Decryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_ABYTES; /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core_Util::substr( $message, $clen, self::aead_chacha20poly1305_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr($message, 0, $clen); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 32, $nonce, $key ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); $state->update($ad); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES; /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::ietfStream( 32, $nonce, $key ); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core_Util::substr( $message, $len - self::aead_chacha20poly1305_IETF_ABYTES, self::aead_chacha20poly1305_IETF_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr( $message, 0, $len - self::aead_chacha20poly1305_IETF_ABYTES ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", (0x10 - $clen) & 0xf)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core_ChaCha20::ietfStream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core_Util::store64_le(1) ); $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); $state->update(ParagonIE_Sodium_Core_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_decrypt($message, $ad, $nonceLast, $subkey); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_encrypt($message, $ad, $nonceLast, $subkey); } /** * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $key * @return string * @throws TypeError */ public static function auth($message, $key) { return ParagonIE_Sodium_Core_Util::substr( hash_hmac('sha512', $message, $key, true), 0, 32 ); } /** * HMAC-SHA-512-256 validation. Constant-time via hash_equals(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $mac * @param string $message * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function auth_verify($mac, $message, $key) { return ParagonIE_Sodium_Core_Util::hashEquals( $mac, self::auth($message, $key) ); } /** * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box($plaintext, $nonce, $keypair) { $c = self::secretbox( $plaintext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); return $c; } /** * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $publicKey * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal($message, $publicKey) { /** @var string $ephemeralKeypair */ $ephemeralKeypair = self::box_keypair(); /** @var string $ephemeralSK */ $ephemeralSK = self::box_secretkey($ephemeralKeypair); /** @var string $ephemeralPK */ $ephemeralPK = self::box_publickey($ephemeralKeypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair - The combined keypair used in crypto_box() */ $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey); /** @var string $ciphertext Ciphertext + MAC from crypto_box */ $ciphertext = self::box($message, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($ephemeralKeypair); ParagonIE_Sodium_Compat::memzero($ephemeralSK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $ephemeralKeypair = null; $ephemeralSK = null; $nonce = null; } return $ephemeralPK . $ciphertext; } /** * Opens a message encrypted via box_seal(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal_open($message, $keypair) { /** @var string $ephemeralPK */ $ephemeralPK = ParagonIE_Sodium_Core_Util::substr($message, 0, 32); /** @var string $ciphertext (ciphertext + MAC) */ $ciphertext = ParagonIE_Sodium_Core_Util::substr($message, 32); /** @var string $secretKey */ $secretKey = self::box_secretkey($keypair); /** @var string $publicKey */ $publicKey = self::box_publickey($keypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair */ $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK); /** @var string $m */ $m = self::box_open($ciphertext, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($secretKey); ParagonIE_Sodium_Compat::memzero($ephemeralPK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $secretKey = null; $ephemeralPK = null; $nonce = null; } return $m; } /** * Used by crypto_box() to get the crypto_secretbox() key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sk * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function box_beforenm($sk, $pk) { return ParagonIE_Sodium_Core_HSalsa20::hsalsa20( str_repeat("\x00", 16), self::scalarmult($sk, $pk) ); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @return string * @throws Exception * @throws SodiumException * @throws TypeError */ public static function box_keypair() { $sKey = random_bytes(32); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function box_seed_keypair($seed) { $sKey = ParagonIE_Sodium_Core_Util::substr( hash('sha512', $seed, true), 0, 32 ); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * @throws TypeError */ public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey) { return ParagonIE_Sodium_Core_Util::substr($sKey, 0, 32) . ParagonIE_Sodium_Core_Util::substr($pKey, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_secretkey($keypair) { if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== 64) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core_Util::substr($keypair, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_publickey($keypair) { if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core_Util::substr($keypair, 32, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function box_publickey_from_secretkey($sKey) { if (ParagonIE_Sodium_Core_Util::strlen($sKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES bytes long.' ); } return self::scalarmult_base($sKey); } /** * Decrypt a message encrypted with box(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_open($ciphertext, $nonce, $keypair) { return self::secretbox_open( $ciphertext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * Calculate a BLAKE2b hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string|null $key * @param int $outlen * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash($message, $key = '', $outlen = 32) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { /** @var SplFixedArray $k */ $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message); /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outlen); ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $in, $in->count()); /** @var SplFixedArray $out */ $out = new SplFixedArray($outlen); $out = ParagonIE_Sodium_Core_BLAKE2b::finish($ctx, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core_Util::intArrayToString($outArray); } /** * Finalize a BLAKE2b hashing context, returning the hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param int $outlen * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_final($ctx, $outlen = 32) { if (!is_string($ctx)) { throw new TypeError('Context must be a string'); } $out = new SplFixedArray($outlen); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $out */ $out = ParagonIE_Sodium_Core_BLAKE2b::finish($context, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core_Util::intArrayToString($outArray); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init($key = '', $outputLength = 32) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @param string $salt * @param string $personal * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init_salt_personal( $key = '', $outputLength = 32, $salt = '', $personal = '' ) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } if (!empty($salt)) { $s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($salt); } else { $s = null; } if (!empty($salt)) { $p = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($personal); } else { $p = null; } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength, $s, $p); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); } /** * Update a hashing context for BLAKE2b with $message * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param string $message * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_update($ctx, $message) { // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message); ParagonIE_Sodium_Core_BLAKE2b::update($context, $in, $in->count()); return ParagonIE_Sodium_Core_BLAKE2b::contextToString($context); } /** * Libsodium's crypto_kx(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $my_sk * @param string $their_pk * @param string $client_pk * @param string $server_pk * @return string * @throws SodiumException * @throws TypeError */ public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) { return ParagonIE_Sodium_Compat::crypto_generichash( ParagonIE_Sodium_Compat::crypto_scalarmult($my_sk, $their_pk) . $client_pk . $server_pk ); } /** * ECDH over Curve25519 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult($sKey, $pKey) { $q = ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10($sKey, $pKey); self::scalarmult_throw_if_zero($q); return $q; } /** * ECDH over Curve25519, using the basepoint. * Used to get a secret key from a public key. * * @param string $secret * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult_base($secret) { $q = ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10_base($secret); self::scalarmult_throw_if_zero($q); return $q; } /** * This throws an Error if a zero public key was passed to the function. * * @param string $q * @return void * @throws SodiumException * @throws TypeError */ protected static function scalarmult_throw_if_zero($q) { $d = 0; for ($i = 0; $i < self::box_curve25519xsalsa20poly1305_SECRETKEYBYTES; ++$i) { $d |= ParagonIE_Sodium_Core_Util::chrToInt($q[$i]); } /* branch-free variant of === 0 */ if (-(1 & (($d - 1) >> 8))) { throw new SodiumException('Zero public key is not allowed'); } } /** * XSalsa20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20_xor( $block0, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $block0, self::secretbox_xsalsa20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core_Util::substr( $plaintext, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), 1, $subkey ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $ciphertext, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20( 64, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core_Util::xorStrings( ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core_Util::substr( $c, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), 1, (string) $subkey ); } return $m; } /** * XChaCha20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($nonce, 0, 16), $key ); $nonceLast = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xchacha20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xchacha20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_ChaCha20::streamXorIc( $block0, $nonceLast, $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $block0, self::secretbox_xchacha20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core_ChaCha20::streamXorIc( ParagonIE_Sodium_Core_Util::substr( $plaintext, self::secretbox_xchacha20poly1305_ZEROBYTES ), $nonceLast, $subkey, ParagonIE_Sodium_Core_Util::store64_le(1) ); } $state = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox_xchacha20poly1305(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core_Util::substr( $ciphertext, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HChaCha20::hchacha20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_ChaCha20::stream( 64, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core_Util::xorStrings( ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core_ChaCha20::streamXorIc( ParagonIE_Sodium_Core_Util::substr( $c, self::secretbox_xchacha20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), (string) $subkey, ParagonIE_Sodium_Core_Util::store64_le(1) ); } return $m; } /** * @param string $key * @return array<int, string> Returns a state and a header. * @throws Exception * @throws SodiumException */ public static function secretstream_xchacha20poly1305_init_push($key) { # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); $out = random_bytes(24); # crypto_core_hchacha20(state->k, out, k, NULL); $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key); $state = new ParagonIE_Sodium_Core_SecretStream_State( $subkey, ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4) ); # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $state->counterReset(); # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); return array( $state->toString(), $out ); } /** * @param string $key * @param string $header * @return string Returns a state. * @throws Exception */ public static function secretstream_xchacha20poly1305_init_pull($key, $header) { # crypto_core_hchacha20(state->k, in, k, NULL); $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( ParagonIE_Sodium_Core_Util::substr($header, 0, 16), $key ); $state = new ParagonIE_Sodium_Core_SecretStream_State( $subkey, ParagonIE_Sodium_Core_Util::substr($header, 16) ); $state->counterReset(); # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); # return 0; return $state->toString(); } /** * @param string $state * @param string $msg * @param string $aad * @param int $tag * @return string * @throws SodiumException */ public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); # crypto_onetimeauth_poly1305_state poly1305_state; # unsigned char block[64U]; # unsigned char slen[8U]; # unsigned char *c; # unsigned char *mac; $msglen = ParagonIE_Sodium_Core_Util::strlen($msg); $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # if (outlen_p != NULL) { # *outlen_p = 0U; # } # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = tag; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(1) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $auth->update($block); # out[0] = block[0]; $out = $block[0]; # c = out + (sizeof tag); # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); $cipher = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $msg, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(2) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update($cipher); $out .= $cipher; unset($cipher); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # mac = c + mlen; # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); $mac = $auth->finish(); $out .= $mac; # sodium_memzero(&poly1305_state, sizeof poly1305_state); unset($auth); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } # if (outlen_p != NULL) { # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; # } return $out; } /** * @param string $state * @param string $cipher * @param string $aad * @return bool|array{0: string, 1: int} * @throws SodiumException */ public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); $cipherlen = ParagonIE_Sodium_Core_Util::strlen($cipher); # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = in[0]; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $cipher[0] . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(1) ); # tag = block[0]; # block[0] = in[0]; # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $tag = ParagonIE_Sodium_Core_Util::chrToInt($block[0]); $block[0] = $cipher[0]; $auth->update($block); # c = in + (sizeof tag); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update(ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen)); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); $auth->update($slen); # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); # sodium_memzero(&poly1305_state, sizeof poly1305_state); $mac = $auth->finish(); # stored_mac = c + mlen; # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { # sodium_memzero(mac, sizeof mac); # return -1; # } $stored = ParagonIE_Sodium_Core_Util::substr($cipher, $msglen + 1, 16); if (!ParagonIE_Sodium_Core_Util::hashEquals($mac, $stored)) { return false; } # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); $out = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(2) ); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } return array($out, $tag); } /** * @param string $state * @return void * @throws SodiumException */ public static function secretstream_xchacha20poly1305_rekey(&$state) { $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; # size_t i; # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # new_key_and_inonce[i] = state->k[i]; # } $new_key_and_inonce = $st->getKey(); # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = # STATE_INONCE(state)[i]; # } $new_key_and_inonce .= ParagonIE_Sodium_Core_Util::substR($st->getNonce(), 0, 8); # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, # sizeof new_key_and_inonce, # state->nonce, state->k); $st->rekey(ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( $new_key_and_inonce, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core_Util::store64_le(0) )); # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # state->k[i] = new_key_and_inonce[i]; # } # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # STATE_INONCE(state)[i] = # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; # } # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $st->counterReset(); $state = $st->toString(); } /** * Detached Ed25519 signature. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_detached($message, $sk) { return ParagonIE_Sodium_Core_Ed25519::sign_detached($message, $sk); } /** * Attached Ed25519 signature. (Returns a signed message.) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { return ParagonIE_Sodium_Core_Ed25519::sign($message, $sk); } /** * Opens a signed message. If valid, returns the message. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signedMessage * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_open($signedMessage, $pk) { return ParagonIE_Sodium_Core_Ed25519::sign_open($signedMessage, $pk); } /** * Verify a detached signature of a given message and public key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signature * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function sign_verify_detached($signature, $message, $pk) { return ParagonIE_Sodium_Core_Ed25519::verify_detached($signature, $message, $pk); } } <?php if (!class_exists('SodiumException', false)) { /** * Class SodiumException */ class SodiumException extends Exception { } } <?php /** * Class ParagonIE_Sodium_Core32_SecretStream_State */ class ParagonIE_Sodium_Core32_SecretStream_State { /** @var string $key */ protected $key; /** @var int $counter */ protected $counter; /** @var string $nonce */ protected $nonce; /** @var string $_pad */ protected $_pad; /** * ParagonIE_Sodium_Core32_SecretStream_State constructor. * @param string $key * @param string|null $nonce */ public function __construct($key, $nonce = null) { $this->key = $key; $this->counter = 1; if (is_null($nonce)) { $nonce = str_repeat("\0", 12); } $this->nonce = str_pad($nonce, 12, "\0", STR_PAD_RIGHT);; $this->_pad = str_repeat("\0", 4); } /** * @return self */ public function counterReset() { $this->counter = 1; $this->_pad = str_repeat("\0", 4); return $this; } /** * @return string */ public function getKey() { return $this->key; } /** * @return string */ public function getCounter() { return ParagonIE_Sodium_Core32_Util::store32_le($this->counter); } /** * @return string */ public function getNonce() { if (!is_string($this->nonce)) { $this->nonce = str_repeat("\0", 12); } if (ParagonIE_Sodium_Core32_Util::strlen($this->nonce) !== 12) { $this->nonce = str_pad($this->nonce, 12, "\0", STR_PAD_RIGHT); } return $this->nonce; } /** * @return string */ public function getCombinedNonce() { return $this->getCounter() . ParagonIE_Sodium_Core32_Util::substr($this->getNonce(), 0, 8); } /** * @return self */ public function incrementCounter() { ++$this->counter; return $this; } /** * @return bool */ public function needsRekey() { return ($this->counter & 0xffff) === 0; } /** * @param string $newKeyAndNonce * @return self */ public function rekey($newKeyAndNonce) { $this->key = ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 0, 32); $this->nonce = str_pad( ParagonIE_Sodium_Core32_Util::substr($newKeyAndNonce, 32), 12, "\0", STR_PAD_RIGHT ); return $this; } /** * @param string $str * @return self */ public function xorNonce($str) { $this->nonce = ParagonIE_Sodium_Core32_Util::xorStrings( $this->getNonce(), str_pad( ParagonIE_Sodium_Core32_Util::substr($str, 0, 8), 12, "\0", STR_PAD_RIGHT ) ); return $this; } /** * @param string $string * @return self */ public static function fromString($string) { $state = new ParagonIE_Sodium_Core32_SecretStream_State( ParagonIE_Sodium_Core32_Util::substr($string, 0, 32) ); $state->counter = ParagonIE_Sodium_Core32_Util::load_4( ParagonIE_Sodium_Core32_Util::substr($string, 32, 4) ); $state->nonce = ParagonIE_Sodium_Core32_Util::substr($string, 36, 12); $state->_pad = ParagonIE_Sodium_Core32_Util::substr($string, 48, 8); return $state; } /** * @return string */ public function toString() { return $this->key . $this->getCounter() . $this->nonce . $this->_pad; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Ed25519', false)) { return; } if (!class_exists('ParagonIE_Sodium_Core32_Curve25519')) { require_once dirname(__FILE__) . '/Curve25519.php'; } /** * Class ParagonIE_Sodium_Core32_Ed25519 */ abstract class ParagonIE_Sodium_Core32_Ed25519 extends ParagonIE_Sodium_Core32_Curve25519 { const KEYPAIR_BYTES = 96; const SEED_BYTES = 32; /** * @internal You should not use this directly from another application * * @return string (96 bytes) * @throws Exception * @throws SodiumException * @throws TypeError */ public static function keypair() { $seed = random_bytes(self::SEED_BYTES); $pk = ''; $sk = ''; self::seed_keypair($pk, $sk, $seed); return $sk . $pk; } /** * @internal You should not use this directly from another application * * @param string $pk * @param string $sk * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function seed_keypair(&$pk, &$sk, $seed) { if (self::strlen($seed) !== self::SEED_BYTES) { throw new RangeException('crypto_sign keypair seed must be 32 bytes long'); } /** @var string $pk */ $pk = self::publickey_from_secretkey($seed); $sk = $seed . $pk; return $sk; } /** * @internal You should not use this directly from another application * * @param string $keypair * @return string * @throws TypeError */ public static function secretkey($keypair) { if (self::strlen($keypair) !== self::KEYPAIR_BYTES) { throw new RangeException('crypto_sign keypair must be 96 bytes long'); } return self::substr($keypair, 0, 64); } /** * @internal You should not use this directly from another application * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function publickey($keypair) { if (self::strlen($keypair) !== self::KEYPAIR_BYTES) { throw new RangeException('crypto_sign keypair must be 96 bytes long'); } return self::substr($keypair, 64, 32); } /** * @internal You should not use this directly from another application * * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function publickey_from_secretkey($sk) { /** @var string $sk */ $sk = hash('sha512', self::substr($sk, 0, 32), true); $sk[0] = self::intToChr( self::chrToInt($sk[0]) & 248 ); $sk[31] = self::intToChr( (self::chrToInt($sk[31]) & 63) | 64 ); return self::sk_to_pk($sk); } /** * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function pk_to_curve25519($pk) { if (self::small_order($pk)) { throw new SodiumException('Public key is on a small order'); } $A = self::ge_frombytes_negate_vartime($pk); $p1 = self::ge_mul_l($A); if (!self::fe_isnonzero($p1->X)) { throw new SodiumException('Unexpected zero result'); } # fe_1(one_minus_y); # fe_sub(one_minus_y, one_minus_y, A.Y); # fe_invert(one_minus_y, one_minus_y); $one_minux_y = self::fe_invert( self::fe_sub( self::fe_1(), $A->Y ) ); # fe_1(x); # fe_add(x, x, A.Y); # fe_mul(x, x, one_minus_y); $x = self::fe_mul( self::fe_add(self::fe_1(), $A->Y), $one_minux_y ); # fe_tobytes(curve25519_pk, x); return self::fe_tobytes($x); } /** * @internal You should not use this directly from another application * * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sk_to_pk($sk) { return self::ge_p3_tobytes( self::ge_scalarmult_base( self::substr($sk, 0, 32) ) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { /** @var string $signature */ $signature = self::sign_detached($message, $sk); return $signature . $message; } /** * @internal You should not use this directly from another application * * @param string $message A signed message * @param string $pk Public key * @return string Message (without signature) * @throws SodiumException * @throws TypeError */ public static function sign_open($message, $pk) { /** @var string $signature */ $signature = self::substr($message, 0, 64); /** @var string $message */ $message = self::substr($message, 64); if (self::verify_detached($signature, $message, $pk)) { return $message; } throw new SodiumException('Invalid signature'); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress PossiblyInvalidArgument */ public static function sign_detached($message, $sk) { # crypto_hash_sha512(az, sk, 32); $az = hash('sha512', self::substr($sk, 0, 32), true); # az[0] &= 248; # az[31] &= 63; # az[31] |= 64; $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); # crypto_hash_sha512_init(&hs); # crypto_hash_sha512_update(&hs, az + 32, 32); # crypto_hash_sha512_update(&hs, m, mlen); # crypto_hash_sha512_final(&hs, nonce); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($az, 32, 32)); self::hash_update($hs, $message); $nonceHash = hash_final($hs, true); # memmove(sig + 32, sk + 32, 32); $pk = self::substr($sk, 32, 32); # sc_reduce(nonce); # ge_scalarmult_base(&R, nonce); # ge_p3_tobytes(sig, &R); $nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32); $sig = self::ge_p3_tobytes( self::ge_scalarmult_base($nonce) ); # crypto_hash_sha512_init(&hs); # crypto_hash_sha512_update(&hs, sig, 64); # crypto_hash_sha512_update(&hs, m, mlen); # crypto_hash_sha512_final(&hs, hram); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($sig, 0, 32)); self::hash_update($hs, self::substr($pk, 0, 32)); self::hash_update($hs, $message); $hramHash = hash_final($hs, true); # sc_reduce(hram); # sc_muladd(sig + 32, hram, az, nonce); $hram = self::sc_reduce($hramHash); $sigAfter = self::sc_muladd($hram, $az, $nonce); $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32); try { ParagonIE_Sodium_Compat::memzero($az); } catch (SodiumException $ex) { $az = null; } return $sig; } /** * @internal You should not use this directly from another application * * @param string $sig * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function verify_detached($sig, $message, $pk) { if (self::strlen($sig) < 64) { throw new SodiumException('Signature is too short'); } if ((self::chrToInt($sig[63]) & 240) && self::check_S_lt_L(self::substr($sig, 32, 32))) { throw new SodiumException('S < L - Invalid signature'); } if (self::small_order($sig)) { throw new SodiumException('Signature is on too small of an order'); } if ((self::chrToInt($sig[63]) & 224) !== 0) { throw new SodiumException('Invalid signature'); } $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= self::chrToInt($pk[$i]); } if ($d === 0) { throw new SodiumException('All zero public key'); } /** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */ $orig = ParagonIE_Sodium_Compat::$fastMult; // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification. ParagonIE_Sodium_Compat::$fastMult = true; /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */ $A = self::ge_frombytes_negate_vartime($pk); /** @var string $hDigest */ $hDigest = hash( 'sha512', self::substr($sig, 0, 32) . self::substr($pk, 0, 32) . $message, true ); /** @var string $h */ $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */ $R = self::ge_double_scalarmult_vartime( $h, $A, self::substr($sig, 32) ); /** @var string $rcheck */ $rcheck = self::ge_tobytes($R); // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before. ParagonIE_Sodium_Compat::$fastMult = $orig; return self::verify_32($rcheck, self::substr($sig, 0, 32)); } /** * @internal You should not use this directly from another application * * @param string $S * @return bool * @throws SodiumException * @throws TypeError */ public static function check_S_lt_L($S) { if (self::strlen($S) < 32) { throw new SodiumException('Signature must be 32 bytes'); } static $L = array( 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 ); /** @var array<int, int> $L */ $c = 0; $n = 1; $i = 32; do { --$i; $x = self::chrToInt($S[$i]); $c |= ( (($x - $L[$i]) >> 8) & $n ); $n &= ( (($x ^ $L[$i]) - 1) >> 8 ); } while ($i !== 0); return $c === 0; } /** * @param string $R * @return bool * @throws SodiumException * @throws TypeError */ public static function small_order($R) { static $blocklist = array( /* 0 (order 4) */ array( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), /* 1 (order 1) */ array( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */ array( 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 ), /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */ array( 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a ), /* p-1 (order 2) */ array( 0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85 ), /* p (order 4) */ array( 0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa ), /* p+1 (order 1) */ array( 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */ array( 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */ array( 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f ), /* 2p-1 (order 2) */ array( 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), /* 2p (order 4) */ array( 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), /* 2p+1 (order 1) */ array( 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ) ); /** @var array<int, array<int, int>> $blocklist */ $countBlocklist = count($blocklist); for ($i = 0; $i < $countBlocklist; ++$i) { $c = 0; for ($j = 0; $j < 32; ++$j) { $c |= self::chrToInt($R[$j]) ^ $blocklist[$i][$j]; } if ($c === 0) { return true; } } return false; } } <?php if (class_exists('ParagonIE_Sodium_Core32_XSalsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_XSalsa20 */ abstract class ParagonIE_Sodium_Core32_XSalsa20 extends ParagonIE_Sodium_Core32_HSalsa20 { /** * Expand a key and nonce into an xsalsa20 keystream. * * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function xsalsa20($len, $nonce, $key) { $ret = self::salsa20( $len, self::substr($nonce, 16, 8), self::hsalsa20($nonce, $key) ); return $ret; } /** * Encrypt a string with XSalsa20. Doesn't provide integrity. * * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function xsalsa20_xor($message, $nonce, $key) { return self::xorStrings( $message, self::xsalsa20( self::strlen($message), $nonce, $key ) ); } } <?php /** * Class ParagonIE_Sodium_Core32_Int32 * * Encapsulates a 32-bit integer. * * These are immutable. It always returns a new instance. */ class ParagonIE_Sodium_Core32_Int32 { /** * @var array<int, int> - two 16-bit integers * * 0 is the higher 16 bits * 1 is the lower 16 bits */ public $limbs = array(0, 0); /** * @var int */ public $overflow = 0; /** * @var bool */ public $unsignedInt = false; /** * ParagonIE_Sodium_Core32_Int32 constructor. * @param array $array * @param bool $unsignedInt */ public function __construct($array = array(0, 0), $unsignedInt = false) { $this->limbs = array( (int) $array[0], (int) $array[1] ); $this->overflow = 0; $this->unsignedInt = $unsignedInt; } /** * Adds two int32 objects * * @param ParagonIE_Sodium_Core32_Int32 $addend * @return ParagonIE_Sodium_Core32_Int32 */ public function addInt32(ParagonIE_Sodium_Core32_Int32 $addend) { $i0 = $this->limbs[0]; $i1 = $this->limbs[1]; $j0 = $addend->limbs[0]; $j1 = $addend->limbs[1]; $r1 = $i1 + ($j1 & 0xffff); $carry = $r1 >> 16; $r0 = $i0 + ($j0 & 0xffff) + $carry; $carry = $r0 >> 16; $r0 &= 0xffff; $r1 &= 0xffff; $return = new ParagonIE_Sodium_Core32_Int32( array($r0, $r1) ); $return->overflow = $carry; $return->unsignedInt = $this->unsignedInt; return $return; } /** * Adds a normal integer to an int32 object * * @param int $int * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError */ public function addInt($int) { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); /** @var int $int */ $int = (int) $int; $int = (int) $int; $i0 = $this->limbs[0]; $i1 = $this->limbs[1]; $r1 = $i1 + ($int & 0xffff); $carry = $r1 >> 16; $r0 = $i0 + (($int >> 16) & 0xffff) + $carry; $carry = $r0 >> 16; $r0 &= 0xffff; $r1 &= 0xffff; $return = new ParagonIE_Sodium_Core32_Int32( array($r0, $r1) ); $return->overflow = $carry; $return->unsignedInt = $this->unsignedInt; return $return; } /** * @param int $b * @return int */ public function compareInt($b = 0) { $gt = 0; $eq = 1; $i = 2; $j = 0; while ($i > 0) { --$i; /** @var int $x1 */ $x1 = $this->limbs[$i]; /** @var int $x2 */ $x2 = ($b >> ($j << 4)) & 0xffff; /** @var int $gt */ $gt |= (($x2 - $x1) >> 8) & $eq; /** @var int $eq */ $eq &= (($x2 ^ $x1) - 1) >> 8; } return ($gt + $gt - $eq) + 1; } /** * @param int $m * @return ParagonIE_Sodium_Core32_Int32 */ public function mask($m = 0) { /** @var int $hi */ $hi = ((int) $m >> 16); $hi &= 0xffff; /** @var int $lo */ $lo = ((int) $m) & 0xffff; return new ParagonIE_Sodium_Core32_Int32( array( (int) ($this->limbs[0] & $hi), (int) ($this->limbs[1] & $lo) ), $this->unsignedInt ); } /** * @param array<int, int> $a * @param array<int, int> $b * @param int $baseLog2 * @return array<int, int> */ public function multiplyLong(array $a, array $b, $baseLog2 = 16) { $a_l = count($a); $b_l = count($b); /** @var array<int, int> $r */ $r = array_fill(0, $a_l + $b_l + 1, 0); $base = 1 << $baseLog2; for ($i = 0; $i < $a_l; ++$i) { $a_i = $a[$i]; for ($j = 0; $j < $a_l; ++$j) { $b_j = $b[$j]; $product = ($a_i * $b_j) + $r[$i + $j]; $carry = ((int) $product >> $baseLog2 & 0xffff); $r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff; $r[$i + $j + 1] += $carry; } } return array_slice($r, 0, 5); } /** * @param int $int * @return ParagonIE_Sodium_Core32_Int32 */ public function mulIntFast($int) { // Handle negative numbers $aNeg = ($this->limbs[0] >> 15) & 1; $bNeg = ($int >> 31) & 1; $a = array_reverse($this->limbs); $b = array( $int & 0xffff, ($int >> 16) & 0xffff ); if ($aNeg) { for ($i = 0; $i < 2; ++$i) { $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; } ++$a[0]; } if ($bNeg) { for ($i = 0; $i < 2; ++$i) { $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; } ++$b[0]; } // Multiply $res = $this->multiplyLong($a, $b); // Re-apply negation to results if ($aNeg !== $bNeg) { for ($i = 0; $i < 2; ++$i) { $res[$i] = (0xffff ^ $res[$i]) & 0xffff; } // Handle integer overflow $c = 1; for ($i = 0; $i < 2; ++$i) { $res[$i] += $c; $c = $res[$i] >> 16; $res[$i] &= 0xffff; } } // Return our values $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs = array( $res[1] & 0xffff, $res[0] & 0xffff ); if (count($res) > 2) { $return->overflow = $res[2] & 0xffff; } $return->unsignedInt = $this->unsignedInt; return $return; } /** * @param ParagonIE_Sodium_Core32_Int32 $right * @return ParagonIE_Sodium_Core32_Int32 */ public function mulInt32Fast(ParagonIE_Sodium_Core32_Int32 $right) { $aNeg = ($this->limbs[0] >> 15) & 1; $bNeg = ($right->limbs[0] >> 15) & 1; $a = array_reverse($this->limbs); $b = array_reverse($right->limbs); if ($aNeg) { for ($i = 0; $i < 2; ++$i) { $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; } ++$a[0]; } if ($bNeg) { for ($i = 0; $i < 2; ++$i) { $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; } ++$b[0]; } $res = $this->multiplyLong($a, $b); if ($aNeg !== $bNeg) { if ($aNeg !== $bNeg) { for ($i = 0; $i < 2; ++$i) { $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; } $c = 1; for ($i = 0; $i < 2; ++$i) { $res[$i] += $c; $c = $res[$i] >> 16; $res[$i] &= 0xffff; } } } $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs = array( $res[1] & 0xffff, $res[0] & 0xffff ); if (count($res) > 2) { $return->overflow = $res[2]; } return $return; } /** * @param int $int * @param int $size * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError */ public function mulInt($int = 0, $size = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); if (ParagonIE_Sodium_Compat::$fastMult) { return $this->mulIntFast((int) $int); } /** @var int $int */ $int = (int) $int; /** @var int $size */ $size = (int) $size; if (!$size) { $size = 31; } /** @var int $size */ $a = clone $this; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; // Initialize: $ret0 = 0; $ret1 = 0; $a0 = $a->limbs[0]; $a1 = $a->limbs[1]; /** @var int $size */ /** @var int $i */ for ($i = $size; $i >= 0; --$i) { $m = (int) (-($int & 1)); $x0 = $a0 & $m; $x1 = $a1 & $m; $ret1 += $x1; $c = $ret1 >> 16; $ret0 += $x0 + $c; $ret0 &= 0xffff; $ret1 &= 0xffff; $a1 = ($a1 << 1); $x1 = $a1 >> 16; $a0 = ($a0 << 1) | $x1; $a0 &= 0xffff; $a1 &= 0xffff; $int >>= 1; } $return->limbs[0] = $ret0; $return->limbs[1] = $ret1; return $return; } /** * @param ParagonIE_Sodium_Core32_Int32 $int * @param int $size * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError */ public function mulInt32(ParagonIE_Sodium_Core32_Int32 $int, $size = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); if (ParagonIE_Sodium_Compat::$fastMult) { return $this->mulInt32Fast($int); } if (!$size) { $size = 31; } /** @var int $size */ $a = clone $this; $b = clone $int; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; // Initialize: $ret0 = 0; $ret1 = 0; $a0 = $a->limbs[0]; $a1 = $a->limbs[1]; $b0 = $b->limbs[0]; $b1 = $b->limbs[1]; /** @var int $size */ /** @var int $i */ for ($i = $size; $i >= 0; --$i) { $m = (int) (-($b1 & 1)); $x0 = $a0 & $m; $x1 = $a1 & $m; $ret1 += $x1; $c = $ret1 >> 16; $ret0 += $x0 + $c; $ret0 &= 0xffff; $ret1 &= 0xffff; $a1 = ($a1 << 1); $x1 = $a1 >> 16; $a0 = ($a0 << 1) | $x1; $a0 &= 0xffff; $a1 &= 0xffff; $x0 = ($b0 & 1) << 16; $b0 = ($b0 >> 1); $b1 = (($b1 | $x0) >> 1); $b0 &= 0xffff; $b1 &= 0xffff; } $return->limbs[0] = $ret0; $return->limbs[1] = $ret1; return $return; } /** * OR this 32-bit integer with another. * * @param ParagonIE_Sodium_Core32_Int32 $b * @return ParagonIE_Sodium_Core32_Int32 */ public function orInt32(ParagonIE_Sodium_Core32_Int32 $b) { $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $return->limbs = array( (int) ($this->limbs[0] | $b->limbs[0]), (int) ($this->limbs[1] | $b->limbs[1]) ); /** @var int overflow */ $return->overflow = $this->overflow | $b->overflow; return $return; } /** * @param int $b * @return bool */ public function isGreaterThan($b = 0) { return $this->compareInt($b) > 0; } /** * @param int $b * @return bool */ public function isLessThanInt($b = 0) { return $this->compareInt($b) < 0; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public function rotateLeft($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $c &= 31; if ($c === 0) { // NOP, but we want a copy. $return->limbs = $this->limbs; } else { /** @var int $c */ /** @var int $idx_shift */ $idx_shift = ($c >> 4) & 1; /** @var int $sub_shift */ $sub_shift = $c & 15; /** @var array<int, int> $limbs */ $limbs =& $return->limbs; /** @var array<int, int> $myLimbs */ $myLimbs =& $this->limbs; for ($i = 1; $i >= 0; --$i) { /** @var int $j */ $j = ($i + $idx_shift) & 1; /** @var int $k */ $k = ($i + $idx_shift + 1) & 1; $limbs[$i] = (int) ( ( ((int) ($myLimbs[$j]) << $sub_shift) | ((int) ($myLimbs[$k]) >> (16 - $sub_shift)) ) & 0xffff ); } } return $return; } /** * Rotate to the right * * @param int $c * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public function rotateRight($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $c &= 31; /** @var int $c */ if ($c === 0) { // NOP, but we want a copy. $return->limbs = $this->limbs; } else { /** @var int $c */ /** @var int $idx_shift */ $idx_shift = ($c >> 4) & 1; /** @var int $sub_shift */ $sub_shift = $c & 15; /** @var array<int, int> $limbs */ $limbs =& $return->limbs; /** @var array<int, int> $myLimbs */ $myLimbs =& $this->limbs; for ($i = 1; $i >= 0; --$i) { /** @var int $j */ $j = ($i - $idx_shift) & 1; /** @var int $k */ $k = ($i - $idx_shift - 1) & 1; $limbs[$i] = (int) ( ( ((int) ($myLimbs[$j]) >> (int) ($sub_shift)) | ((int) ($myLimbs[$k]) << (16 - (int) ($sub_shift))) ) & 0xffff ); } } return $return; } /** * @param bool $bool * @return self */ public function setUnsignedInt($bool = false) { $this->unsignedInt = !empty($bool); return $this; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError */ public function shiftLeft($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $c &= 63; /** @var int $c */ if ($c === 0) { $return->limbs = $this->limbs; } elseif ($c < 0) { /** @var int $c */ return $this->shiftRight(-$c); } else { /** @var int $c */ /** @var int $tmp */ $tmp = $this->limbs[1] << $c; $return->limbs[1] = (int)($tmp & 0xffff); /** @var int $carry */ $carry = $tmp >> 16; /** @var int $tmp */ $tmp = ($this->limbs[0] << $c) | ($carry & 0xffff); $return->limbs[0] = (int) ($tmp & 0xffff); } return $return; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public function shiftRight($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $c &= 63; /** @var int $c */ if ($c >= 16) { $return->limbs = array( (int) ($this->overflow & 0xffff), (int) ($this->limbs[0]) ); $return->overflow = $this->overflow >> 16; return $return->shiftRight($c & 15); } if ($c === 0) { $return->limbs = $this->limbs; } elseif ($c < 0) { /** @var int $c */ return $this->shiftLeft(-$c); } else { if (!is_int($c)) { throw new TypeError(); } /** @var int $c */ // $return->limbs[0] = (int) (($this->limbs[0] >> $c) & 0xffff); $carryLeft = (int) ($this->overflow & ((1 << ($c + 1)) - 1)); $return->limbs[0] = (int) ((($this->limbs[0] >> $c) | ($carryLeft << (16 - $c))) & 0xffff); $carryRight = (int) ($this->limbs[0] & ((1 << ($c + 1)) - 1)); $return->limbs[1] = (int) ((($this->limbs[1] >> $c) | ($carryRight << (16 - $c))) & 0xffff); $return->overflow >>= $c; } return $return; } /** * Subtract a normal integer from an int32 object. * * @param int $int * @return ParagonIE_Sodium_Core32_Int32 * @throws SodiumException * @throws TypeError */ public function subInt($int) { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); /** @var int $int */ $int = (int) $int; $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; /** @var int $tmp */ $tmp = $this->limbs[1] - ($int & 0xffff); /** @var int $carry */ $carry = $tmp >> 16; $return->limbs[1] = (int) ($tmp & 0xffff); /** @var int $tmp */ $tmp = $this->limbs[0] - (($int >> 16) & 0xffff) + $carry; $return->limbs[0] = (int) ($tmp & 0xffff); return $return; } /** * Subtract two int32 objects from each other * * @param ParagonIE_Sodium_Core32_Int32 $b * @return ParagonIE_Sodium_Core32_Int32 */ public function subInt32(ParagonIE_Sodium_Core32_Int32 $b) { $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; /** @var int $tmp */ $tmp = $this->limbs[1] - ($b->limbs[1] & 0xffff); /** @var int $carry */ $carry = $tmp >> 16; $return->limbs[1] = (int) ($tmp & 0xffff); /** @var int $tmp */ $tmp = $this->limbs[0] - ($b->limbs[0] & 0xffff) + $carry; $return->limbs[0] = (int) ($tmp & 0xffff); return $return; } /** * XOR this 32-bit integer with another. * * @param ParagonIE_Sodium_Core32_Int32 $b * @return ParagonIE_Sodium_Core32_Int32 */ public function xorInt32(ParagonIE_Sodium_Core32_Int32 $b) { $return = new ParagonIE_Sodium_Core32_Int32(); $return->unsignedInt = $this->unsignedInt; $return->limbs = array( (int) ($this->limbs[0] ^ $b->limbs[0]), (int) ($this->limbs[1] ^ $b->limbs[1]) ); return $return; } /** * @param int $signed * @return self * @throws SodiumException * @throws TypeError */ public static function fromInt($signed) { ParagonIE_Sodium_Core32_Util::declareScalarType($signed, 'int', 1);; /** @var int $signed */ $signed = (int) $signed; return new ParagonIE_Sodium_Core32_Int32( array( (int) (($signed >> 16) & 0xffff), (int) ($signed & 0xffff) ) ); } /** * @param string $string * @return self * @throws SodiumException * @throws TypeError */ public static function fromString($string) { ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); $string = (string) $string; if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 4) { throw new RangeException( 'String must be 4 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' ); } $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff) << 8); $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff); $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff) << 8); $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff); return $return; } /** * @param string $string * @return self * @throws SodiumException * @throws TypeError */ public static function fromReverseString($string) { ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); $string = (string) $string; if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 4) { throw new RangeException( 'String must be 4 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' ); } $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff) << 8); $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff); $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff) << 8); $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff); return $return; } /** * @return array<int, int> */ public function toArray() { return array((int) ($this->limbs[0] << 16 | $this->limbs[1])); } /** * @return string * @throws TypeError */ public function toString() { return ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff); } /** * @return int */ public function toInt() { return (int) ( (($this->limbs[0] & 0xffff) << 16) | ($this->limbs[1] & 0xffff) ); } /** * @return ParagonIE_Sodium_Core32_Int32 */ public function toInt32() { $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs[0] = (int) ($this->limbs[0] & 0xffff); $return->limbs[1] = (int) ($this->limbs[1] & 0xffff); $return->unsignedInt = $this->unsignedInt; $return->overflow = (int) ($this->overflow & 0x7fffffff); return $return; } /** * @return ParagonIE_Sodium_Core32_Int64 */ public function toInt64() { $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; if ($this->unsignedInt) { $return->limbs[0] += (($this->overflow >> 16) & 0xffff); $return->limbs[1] += (($this->overflow) & 0xffff); } else { $neg = -(($this->limbs[0] >> 15) & 1); $return->limbs[0] = (int)($neg & 0xffff); $return->limbs[1] = (int)($neg & 0xffff); } $return->limbs[2] = (int) ($this->limbs[0] & 0xffff); $return->limbs[3] = (int) ($this->limbs[1] & 0xffff); return $return; } /** * @return string * @throws TypeError */ public function toReverseString() { return ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff); } /** * @return string */ public function __toString() { try { return $this->toString(); } catch (TypeError $ex) { // PHP engine can't handle exceptions from __toString() return ''; } } } <?php if (class_exists('ParagonIE_Sodium_Core32_XChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_XChaCha20 */ class ParagonIE_Sodium_Core32_XChaCha20 extends ParagonIE_Sodium_Core32_HChaCha20 { /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function stream($len = 64, $nonce = '', $key = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_Ctx( self::hChaCha20( self::substr($nonce, 0, 16), $key ), self::substr($nonce, 16, 8) ), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function streamXorIc($message, $nonce = '', $key = '', $ic = '') { if (self::strlen($nonce) !== 24) { throw new SodiumException('Nonce must be 24 bytes long'); } return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_Ctx( self::hChaCha20(self::substr($nonce, 0, 16), $key), self::substr($nonce, 16, 8), $ic ), $message ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '') { return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx( self::hChaCha20(self::substr($nonce, 0, 16), $key), "\x00\x00\x00\x00" . self::substr($nonce, 16, 8), $ic ), $message ); } } <?php if (class_exists('ParagonIE_Sodium_Core32_HChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core_HChaCha20 */ class ParagonIE_Sodium_Core32_HChaCha20 extends ParagonIE_Sodium_Core32_ChaCha20 { /** * @param string $in * @param string $key * @param string|null $c * @return string * @throws SodiumException * @throws TypeError */ public static function hChaCha20($in = '', $key = '', $c = null) { $ctx = array(); if ($c === null) { $ctx[0] = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865)); $ctx[1] = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e)); $ctx[2] = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32)); $ctx[3] = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574)); } else { $ctx[0] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4)); $ctx[1] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4)); $ctx[2] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4)); $ctx[3] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4)); } $ctx[4] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4)); $ctx[5] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4)); $ctx[6] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4)); $ctx[7] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4)); $ctx[8] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4)); $ctx[9] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4)); $ctx[10] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4)); $ctx[11] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4)); $ctx[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4)); $ctx[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4)); $ctx[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4)); $ctx[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4)); return self::hChaCha20Bytes($ctx); } /** * @param array $ctx * @return string * @throws SodiumException * @throws TypeError */ protected static function hChaCha20Bytes(array $ctx) { /** @var ParagonIE_Sodium_Core32_Int32 $x0 */ $x0 = $ctx[0]; /** @var ParagonIE_Sodium_Core32_Int32 $x1 */ $x1 = $ctx[1]; /** @var ParagonIE_Sodium_Core32_Int32 $x2 */ $x2 = $ctx[2]; /** @var ParagonIE_Sodium_Core32_Int32 $x3 */ $x3 = $ctx[3]; /** @var ParagonIE_Sodium_Core32_Int32 $x4 */ $x4 = $ctx[4]; /** @var ParagonIE_Sodium_Core32_Int32 $x5 */ $x5 = $ctx[5]; /** @var ParagonIE_Sodium_Core32_Int32 $x6 */ $x6 = $ctx[6]; /** @var ParagonIE_Sodium_Core32_Int32 $x7 */ $x7 = $ctx[7]; /** @var ParagonIE_Sodium_Core32_Int32 $x8 */ $x8 = $ctx[8]; /** @var ParagonIE_Sodium_Core32_Int32 $x9 */ $x9 = $ctx[9]; /** @var ParagonIE_Sodium_Core32_Int32 $x10 */ $x10 = $ctx[10]; /** @var ParagonIE_Sodium_Core32_Int32 $x11 */ $x11 = $ctx[11]; /** @var ParagonIE_Sodium_Core32_Int32 $x12 */ $x12 = $ctx[12]; /** @var ParagonIE_Sodium_Core32_Int32 $x13 */ $x13 = $ctx[13]; /** @var ParagonIE_Sodium_Core32_Int32 $x14 */ $x14 = $ctx[14]; /** @var ParagonIE_Sodium_Core32_Int32 $x15 */ $x15 = $ctx[15]; for ($i = 0; $i < 10; ++$i) { # QUARTERROUND( x0, x4, x8, x12) list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12); # QUARTERROUND( x1, x5, x9, x13) list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13); # QUARTERROUND( x2, x6, x10, x14) list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14); # QUARTERROUND( x3, x7, x11, x15) list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15); # QUARTERROUND( x0, x5, x10, x15) list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15); # QUARTERROUND( x1, x6, x11, x12) list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12); # QUARTERROUND( x2, x7, x8, x13) list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13); # QUARTERROUND( x3, x4, x9, x14) list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14); } return $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString(); } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519 * * Implements Curve25519 core functions * * Based on the ref10 curve25519 code provided by libsodium * * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c */ abstract class ParagonIE_Sodium_Core32_Curve25519 extends ParagonIE_Sodium_Core32_Curve25519_H { /** * Get a field element of size 10 with a value of 0 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_0() { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32() ) ); } /** * Get a field element of size 10 with a value of 1 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_1() { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(1), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32(), new ParagonIE_Sodium_Core32_Int32() ) ); } /** * Add two field elements. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_add( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g ) { $arr = array(); for ($i = 0; $i < 10; ++$i) { $arr[$i] = $f[$i]->addInt32($g[$i]); } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $arr */ return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($arr); } /** * Constant-time conditional move. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @param int $b * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_cmov( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g, $b = 0 ) { /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ $h = array(); for ($i = 0; $i < 10; ++$i) { if (!($f[$i] instanceof ParagonIE_Sodium_Core32_Int32)) { throw new TypeError('Expected Int32'); } if (!($g[$i] instanceof ParagonIE_Sodium_Core32_Int32)) { throw new TypeError('Expected Int32'); } $h[$i] = $f[$i]->xorInt32( $f[$i]->xorInt32($g[$i])->mask($b) ); } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h); } /** * Create a copy of a field element. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe */ public static function fe_copy(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $h = clone $f; return $h; } /** * Give: 32-byte string. * Receive: A field element object to use for internal calculations. * * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws RangeException * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall */ public static function fe_frombytes($s) { if (self::strlen($s) !== 32) { throw new RangeException('Expected a 32-byte string.'); } /** @var ParagonIE_Sodium_Core32_Int32 $h0 */ $h0 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_4($s) ); /** @var ParagonIE_Sodium_Core32_Int32 $h1 */ $h1 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 4, 3)) << 6 ); /** @var ParagonIE_Sodium_Core32_Int32 $h2 */ $h2 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 7, 3)) << 5 ); /** @var ParagonIE_Sodium_Core32_Int32 $h3 */ $h3 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 10, 3)) << 3 ); /** @var ParagonIE_Sodium_Core32_Int32 $h4 */ $h4 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 13, 3)) << 2 ); /** @var ParagonIE_Sodium_Core32_Int32 $h5 */ $h5 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_4(self::substr($s, 16, 4)) ); /** @var ParagonIE_Sodium_Core32_Int32 $h6 */ $h6 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 20, 3)) << 7 ); /** @var ParagonIE_Sodium_Core32_Int32 $h7 */ $h7 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 23, 3)) << 5 ); /** @var ParagonIE_Sodium_Core32_Int32 $h8 */ $h8 = ParagonIE_Sodium_Core32_Int32::fromInt( self::load_3(self::substr($s, 26, 3)) << 4 ); /** @var ParagonIE_Sodium_Core32_Int32 $h9 */ $h9 = ParagonIE_Sodium_Core32_Int32::fromInt( (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2 ); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt32($carry9->mulInt(19, 5)); $h9 = $h9->subInt32($carry9->shiftLeft(25)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt32($carry1); $h1 = $h1->subInt32($carry1->shiftLeft(25)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt32($carry3); $h3 = $h3->subInt32($carry3->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt32($carry5); $h5 = $h5->subInt32($carry5->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt32($carry7); $h7 = $h7->subInt32($carry7->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt32($carry0); $h0 = $h0->subInt32($carry0->shiftLeft(26)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt32($carry2); $h2 = $h2->subInt32($carry2->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt32($carry4); $h4 = $h4->subInt32($carry4->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt32($carry6); $h6 = $h6->subInt32($carry6->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt32($carry8); $h8 = $h8->subInt32($carry8->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array($h0, $h1, $h2,$h3, $h4, $h5, $h6, $h7, $h8, $h9) ); } /** * Convert a field element to a byte string. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $h * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_tobytes(ParagonIE_Sodium_Core32_Curve25519_Fe $h) { /** * @var ParagonIE_Sodium_Core32_Int64[] $f * @var ParagonIE_Sodium_Core32_Int64 $q */ $f = array(); for ($i = 0; $i < 10; ++$i) { $f[$i] = $h[$i]->toInt64(); } $q = $f[9]->mulInt(19, 5)->addInt(1 << 14)->shiftRight(25) ->addInt64($f[0])->shiftRight(26) ->addInt64($f[1])->shiftRight(25) ->addInt64($f[2])->shiftRight(26) ->addInt64($f[3])->shiftRight(25) ->addInt64($f[4])->shiftRight(26) ->addInt64($f[5])->shiftRight(25) ->addInt64($f[6])->shiftRight(26) ->addInt64($f[7])->shiftRight(25) ->addInt64($f[8])->shiftRight(26) ->addInt64($f[9])->shiftRight(25); $f[0] = $f[0]->addInt64($q->mulInt(19, 5)); $carry0 = $f[0]->shiftRight(26); $f[1] = $f[1]->addInt64($carry0); $f[0] = $f[0]->subInt64($carry0->shiftLeft(26)); $carry1 = $f[1]->shiftRight(25); $f[2] = $f[2]->addInt64($carry1); $f[1] = $f[1]->subInt64($carry1->shiftLeft(25)); $carry2 = $f[2]->shiftRight(26); $f[3] = $f[3]->addInt64($carry2); $f[2] = $f[2]->subInt64($carry2->shiftLeft(26)); $carry3 = $f[3]->shiftRight(25); $f[4] = $f[4]->addInt64($carry3); $f[3] = $f[3]->subInt64($carry3->shiftLeft(25)); $carry4 = $f[4]->shiftRight(26); $f[5] = $f[5]->addInt64($carry4); $f[4] = $f[4]->subInt64($carry4->shiftLeft(26)); $carry5 = $f[5]->shiftRight(25); $f[6] = $f[6]->addInt64($carry5); $f[5] = $f[5]->subInt64($carry5->shiftLeft(25)); $carry6 = $f[6]->shiftRight(26); $f[7] = $f[7]->addInt64($carry6); $f[6] = $f[6]->subInt64($carry6->shiftLeft(26)); $carry7 = $f[7]->shiftRight(25); $f[8] = $f[8]->addInt64($carry7); $f[7] = $f[7]->subInt64($carry7->shiftLeft(25)); $carry8 = $f[8]->shiftRight(26); $f[9] = $f[9]->addInt64($carry8); $f[8] = $f[8]->subInt64($carry8->shiftLeft(26)); $carry9 = $f[9]->shiftRight(25); $f[9] = $f[9]->subInt64($carry9->shiftLeft(25)); $h0 = $f[0]->toInt32()->toInt(); $h1 = $f[1]->toInt32()->toInt(); $h2 = $f[2]->toInt32()->toInt(); $h3 = $f[3]->toInt32()->toInt(); $h4 = $f[4]->toInt32()->toInt(); $h5 = $f[5]->toInt32()->toInt(); $h6 = $f[6]->toInt32()->toInt(); $h7 = $f[7]->toInt32()->toInt(); $h8 = $f[8]->toInt32()->toInt(); $h9 = $f[9]->toInt32()->toInt(); /** * @var array<int, int> */ $s = array( (int) (($h0 >> 0) & 0xff), (int) (($h0 >> 8) & 0xff), (int) (($h0 >> 16) & 0xff), (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff), (int) (($h1 >> 6) & 0xff), (int) (($h1 >> 14) & 0xff), (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff), (int) (($h2 >> 5) & 0xff), (int) (($h2 >> 13) & 0xff), (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff), (int) (($h3 >> 3) & 0xff), (int) (($h3 >> 11) & 0xff), (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff), (int) (($h4 >> 2) & 0xff), (int) (($h4 >> 10) & 0xff), (int) (($h4 >> 18) & 0xff), (int) (($h5 >> 0) & 0xff), (int) (($h5 >> 8) & 0xff), (int) (($h5 >> 16) & 0xff), (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff), (int) (($h6 >> 7) & 0xff), (int) (($h6 >> 15) & 0xff), (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff), (int) (($h7 >> 5) & 0xff), (int) (($h7 >> 13) & 0xff), (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff), (int) (($h8 >> 4) & 0xff), (int) (($h8 >> 12) & 0xff), (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff), (int) (($h9 >> 2) & 0xff), (int) (($h9 >> 10) & 0xff), (int) (($h9 >> 18) & 0xff) ); return self::intArrayToString($s); } /** * Is a field element negative? (1 = yes, 0 = no. Used in calculations.) * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return int * @throws SodiumException * @throws TypeError */ public static function fe_isnegative(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $str = self::fe_tobytes($f); return (int) (self::chrToInt($str[0]) & 1); } /** * Returns 0 if this field element results in all NUL bytes. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return bool * @throws SodiumException * @throws TypeError */ public static function fe_isnonzero(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { static $zero; if ($zero === null) { $zero = str_repeat("\x00", 32); } $str = self::fe_tobytes($f); /** @var string $zero */ return !self::verify_32($str, $zero); } /** * Multiply two field elements * * h = f * g * * @internal You should not use this directly from another application * * @security Is multiplication a source of timing leaks? If so, can we do * anything to prevent that from happening? * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_mul( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g ) { /** * @var ParagonIE_Sodium_Core32_Int32[] $f * @var ParagonIE_Sodium_Core32_Int32[] $g * @var ParagonIE_Sodium_Core32_Int64 $f0 * @var ParagonIE_Sodium_Core32_Int64 $f1 * @var ParagonIE_Sodium_Core32_Int64 $f2 * @var ParagonIE_Sodium_Core32_Int64 $f3 * @var ParagonIE_Sodium_Core32_Int64 $f4 * @var ParagonIE_Sodium_Core32_Int64 $f5 * @var ParagonIE_Sodium_Core32_Int64 $f6 * @var ParagonIE_Sodium_Core32_Int64 $f7 * @var ParagonIE_Sodium_Core32_Int64 $f8 * @var ParagonIE_Sodium_Core32_Int64 $f9 * @var ParagonIE_Sodium_Core32_Int64 $g0 * @var ParagonIE_Sodium_Core32_Int64 $g1 * @var ParagonIE_Sodium_Core32_Int64 $g2 * @var ParagonIE_Sodium_Core32_Int64 $g3 * @var ParagonIE_Sodium_Core32_Int64 $g4 * @var ParagonIE_Sodium_Core32_Int64 $g5 * @var ParagonIE_Sodium_Core32_Int64 $g6 * @var ParagonIE_Sodium_Core32_Int64 $g7 * @var ParagonIE_Sodium_Core32_Int64 $g8 * @var ParagonIE_Sodium_Core32_Int64 $g9 */ $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $g0 = $g[0]->toInt64(); $g1 = $g[1]->toInt64(); $g2 = $g[2]->toInt64(); $g3 = $g[3]->toInt64(); $g4 = $g[4]->toInt64(); $g5 = $g[5]->toInt64(); $g6 = $g[6]->toInt64(); $g7 = $g[7]->toInt64(); $g8 = $g[8]->toInt64(); $g9 = $g[9]->toInt64(); $g1_19 = $g1->mulInt(19, 5); /* 2^4 <= 19 <= 2^5, but we only want 5 bits */ $g2_19 = $g2->mulInt(19, 5); $g3_19 = $g3->mulInt(19, 5); $g4_19 = $g4->mulInt(19, 5); $g5_19 = $g5->mulInt(19, 5); $g6_19 = $g6->mulInt(19, 5); $g7_19 = $g7->mulInt(19, 5); $g8_19 = $g8->mulInt(19, 5); $g9_19 = $g9->mulInt(19, 5); $f1_2 = $f1->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f9_2 = $f9->shiftLeft(1); $f0g0 = $f0->mulInt64($g0, 27); $f0g1 = $f0->mulInt64($g1, 27); $f0g2 = $f0->mulInt64($g2, 27); $f0g3 = $f0->mulInt64($g3, 27); $f0g4 = $f0->mulInt64($g4, 27); $f0g5 = $f0->mulInt64($g5, 27); $f0g6 = $f0->mulInt64($g6, 27); $f0g7 = $f0->mulInt64($g7, 27); $f0g8 = $f0->mulInt64($g8, 27); $f0g9 = $f0->mulInt64($g9, 27); $f1g0 = $f1->mulInt64($g0, 27); $f1g1_2 = $f1_2->mulInt64($g1, 27); $f1g2 = $f1->mulInt64($g2, 27); $f1g3_2 = $f1_2->mulInt64($g3, 27); $f1g4 = $f1->mulInt64($g4, 30); $f1g5_2 = $f1_2->mulInt64($g5, 30); $f1g6 = $f1->mulInt64($g6, 30); $f1g7_2 = $f1_2->mulInt64($g7, 30); $f1g8 = $f1->mulInt64($g8, 30); $f1g9_38 = $g9_19->mulInt64($f1_2, 30); $f2g0 = $f2->mulInt64($g0, 30); $f2g1 = $f2->mulInt64($g1, 29); $f2g2 = $f2->mulInt64($g2, 30); $f2g3 = $f2->mulInt64($g3, 29); $f2g4 = $f2->mulInt64($g4, 30); $f2g5 = $f2->mulInt64($g5, 29); $f2g6 = $f2->mulInt64($g6, 30); $f2g7 = $f2->mulInt64($g7, 29); $f2g8_19 = $g8_19->mulInt64($f2, 30); $f2g9_19 = $g9_19->mulInt64($f2, 30); $f3g0 = $f3->mulInt64($g0, 30); $f3g1_2 = $f3_2->mulInt64($g1, 30); $f3g2 = $f3->mulInt64($g2, 30); $f3g3_2 = $f3_2->mulInt64($g3, 30); $f3g4 = $f3->mulInt64($g4, 30); $f3g5_2 = $f3_2->mulInt64($g5, 30); $f3g6 = $f3->mulInt64($g6, 30); $f3g7_38 = $g7_19->mulInt64($f3_2, 30); $f3g8_19 = $g8_19->mulInt64($f3, 30); $f3g9_38 = $g9_19->mulInt64($f3_2, 30); $f4g0 = $f4->mulInt64($g0, 30); $f4g1 = $f4->mulInt64($g1, 30); $f4g2 = $f4->mulInt64($g2, 30); $f4g3 = $f4->mulInt64($g3, 30); $f4g4 = $f4->mulInt64($g4, 30); $f4g5 = $f4->mulInt64($g5, 30); $f4g6_19 = $g6_19->mulInt64($f4, 30); $f4g7_19 = $g7_19->mulInt64($f4, 30); $f4g8_19 = $g8_19->mulInt64($f4, 30); $f4g9_19 = $g9_19->mulInt64($f4, 30); $f5g0 = $f5->mulInt64($g0, 30); $f5g1_2 = $f5_2->mulInt64($g1, 30); $f5g2 = $f5->mulInt64($g2, 30); $f5g3_2 = $f5_2->mulInt64($g3, 30); $f5g4 = $f5->mulInt64($g4, 30); $f5g5_38 = $g5_19->mulInt64($f5_2, 30); $f5g6_19 = $g6_19->mulInt64($f5, 30); $f5g7_38 = $g7_19->mulInt64($f5_2, 30); $f5g8_19 = $g8_19->mulInt64($f5, 30); $f5g9_38 = $g9_19->mulInt64($f5_2, 30); $f6g0 = $f6->mulInt64($g0, 30); $f6g1 = $f6->mulInt64($g1, 30); $f6g2 = $f6->mulInt64($g2, 30); $f6g3 = $f6->mulInt64($g3, 30); $f6g4_19 = $g4_19->mulInt64($f6, 30); $f6g5_19 = $g5_19->mulInt64($f6, 30); $f6g6_19 = $g6_19->mulInt64($f6, 30); $f6g7_19 = $g7_19->mulInt64($f6, 30); $f6g8_19 = $g8_19->mulInt64($f6, 30); $f6g9_19 = $g9_19->mulInt64($f6, 30); $f7g0 = $f7->mulInt64($g0, 30); $f7g1_2 = $g1->mulInt64($f7_2, 30); $f7g2 = $f7->mulInt64($g2, 30); $f7g3_38 = $g3_19->mulInt64($f7_2, 30); $f7g4_19 = $g4_19->mulInt64($f7, 30); $f7g5_38 = $g5_19->mulInt64($f7_2, 30); $f7g6_19 = $g6_19->mulInt64($f7, 30); $f7g7_38 = $g7_19->mulInt64($f7_2, 30); $f7g8_19 = $g8_19->mulInt64($f7, 30); $f7g9_38 = $g9_19->mulInt64($f7_2, 30); $f8g0 = $f8->mulInt64($g0, 30); $f8g1 = $f8->mulInt64($g1, 29); $f8g2_19 = $g2_19->mulInt64($f8, 30); $f8g3_19 = $g3_19->mulInt64($f8, 30); $f8g4_19 = $g4_19->mulInt64($f8, 30); $f8g5_19 = $g5_19->mulInt64($f8, 30); $f8g6_19 = $g6_19->mulInt64($f8, 30); $f8g7_19 = $g7_19->mulInt64($f8, 30); $f8g8_19 = $g8_19->mulInt64($f8, 30); $f8g9_19 = $g9_19->mulInt64($f8, 30); $f9g0 = $f9->mulInt64($g0, 30); $f9g1_38 = $g1_19->mulInt64($f9_2, 30); $f9g2_19 = $g2_19->mulInt64($f9, 30); $f9g3_38 = $g3_19->mulInt64($f9_2, 30); $f9g4_19 = $g4_19->mulInt64($f9, 30); $f9g5_38 = $g5_19->mulInt64($f9_2, 30); $f9g6_19 = $g6_19->mulInt64($f9, 30); $f9g7_38 = $g7_19->mulInt64($f9_2, 30); $f9g8_19 = $g8_19->mulInt64($f9, 30); $f9g9_38 = $g9_19->mulInt64($f9_2, 30); // $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38; $h0 = $f0g0->addInt64($f1g9_38)->addInt64($f2g8_19)->addInt64($f3g7_38) ->addInt64($f4g6_19)->addInt64($f5g5_38)->addInt64($f6g4_19) ->addInt64($f7g3_38)->addInt64($f8g2_19)->addInt64($f9g1_38); // $h1 = $f0g1 + $f1g0 + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19; $h1 = $f0g1->addInt64($f1g0)->addInt64($f2g9_19)->addInt64($f3g8_19) ->addInt64($f4g7_19)->addInt64($f5g6_19)->addInt64($f6g5_19) ->addInt64($f7g4_19)->addInt64($f8g3_19)->addInt64($f9g2_19); // $h2 = $f0g2 + $f1g1_2 + $f2g0 + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38; $h2 = $f0g2->addInt64($f1g1_2)->addInt64($f2g0)->addInt64($f3g9_38) ->addInt64($f4g8_19)->addInt64($f5g7_38)->addInt64($f6g6_19) ->addInt64($f7g5_38)->addInt64($f8g4_19)->addInt64($f9g3_38); // $h3 = $f0g3 + $f1g2 + $f2g1 + $f3g0 + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19; $h3 = $f0g3->addInt64($f1g2)->addInt64($f2g1)->addInt64($f3g0) ->addInt64($f4g9_19)->addInt64($f5g8_19)->addInt64($f6g7_19) ->addInt64($f7g6_19)->addInt64($f8g5_19)->addInt64($f9g4_19); // $h4 = $f0g4 + $f1g3_2 + $f2g2 + $f3g1_2 + $f4g0 + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38; $h4 = $f0g4->addInt64($f1g3_2)->addInt64($f2g2)->addInt64($f3g1_2) ->addInt64($f4g0)->addInt64($f5g9_38)->addInt64($f6g8_19) ->addInt64($f7g7_38)->addInt64($f8g6_19)->addInt64($f9g5_38); // $h5 = $f0g5 + $f1g4 + $f2g3 + $f3g2 + $f4g1 + $f5g0 + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19; $h5 = $f0g5->addInt64($f1g4)->addInt64($f2g3)->addInt64($f3g2) ->addInt64($f4g1)->addInt64($f5g0)->addInt64($f6g9_19) ->addInt64($f7g8_19)->addInt64($f8g7_19)->addInt64($f9g6_19); // $h6 = $f0g6 + $f1g5_2 + $f2g4 + $f3g3_2 + $f4g2 + $f5g1_2 + $f6g0 + $f7g9_38 + $f8g8_19 + $f9g7_38; $h6 = $f0g6->addInt64($f1g5_2)->addInt64($f2g4)->addInt64($f3g3_2) ->addInt64($f4g2)->addInt64($f5g1_2)->addInt64($f6g0) ->addInt64($f7g9_38)->addInt64($f8g8_19)->addInt64($f9g7_38); // $h7 = $f0g7 + $f1g6 + $f2g5 + $f3g4 + $f4g3 + $f5g2 + $f6g1 + $f7g0 + $f8g9_19 + $f9g8_19; $h7 = $f0g7->addInt64($f1g6)->addInt64($f2g5)->addInt64($f3g4) ->addInt64($f4g3)->addInt64($f5g2)->addInt64($f6g1) ->addInt64($f7g0)->addInt64($f8g9_19)->addInt64($f9g8_19); // $h8 = $f0g8 + $f1g7_2 + $f2g6 + $f3g5_2 + $f4g4 + $f5g3_2 + $f6g2 + $f7g1_2 + $f8g0 + $f9g9_38; $h8 = $f0g8->addInt64($f1g7_2)->addInt64($f2g6)->addInt64($f3g5_2) ->addInt64($f4g4)->addInt64($f5g3_2)->addInt64($f6g2) ->addInt64($f7g1_2)->addInt64($f8g0)->addInt64($f9g9_38); // $h9 = $f0g9 + $f1g8 + $f2g7 + $f3g6 + $f4g5 + $f5g4 + $f6g3 + $f7g2 + $f8g1 + $f9g0 ; $h9 = $f0g9->addInt64($f1g8)->addInt64($f2g7)->addInt64($f3g6) ->addInt64($f4g5)->addInt64($f5g4)->addInt64($f6g3) ->addInt64($f7g2)->addInt64($f8g1)->addInt64($f9g0); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 * @var ParagonIE_Sodium_Core32_Int64 $carry0 * @var ParagonIE_Sodium_Core32_Int64 $carry1 * @var ParagonIE_Sodium_Core32_Int64 $carry2 * @var ParagonIE_Sodium_Core32_Int64 $carry3 * @var ParagonIE_Sodium_Core32_Int64 $carry4 * @var ParagonIE_Sodium_Core32_Int64 $carry5 * @var ParagonIE_Sodium_Core32_Int64 $carry6 * @var ParagonIE_Sodium_Core32_Int64 $carry7 * @var ParagonIE_Sodium_Core32_Int64 $carry8 * @var ParagonIE_Sodium_Core32_Int64 $carry9 */ $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * Get the negative values for each piece of the field element. * * h = -f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_neg(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $h = new ParagonIE_Sodium_Core32_Curve25519_Fe(); for ($i = 0; $i < 10; ++$i) { $h[$i] = $h[$i]->subInt32($f[$i]); } return $h; } /** * Square a field element * * h = f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall */ public static function fe_sq(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $f0_2 = $f0->shiftLeft(1); $f1_2 = $f1->shiftLeft(1); $f2_2 = $f2->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f4_2 = $f4->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f6_2 = $f6->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f5_38 = $f5->mulInt(38, 6); $f6_19 = $f6->mulInt(19, 5); $f7_38 = $f7->mulInt(38, 6); $f8_19 = $f8->mulInt(19, 5); $f9_38 = $f9->mulInt(38, 6); $f0f0 = $f0->mulInt64($f0, 28); $f0f1_2 = $f0_2->mulInt64($f1, 28); $f0f2_2 = $f0_2->mulInt64($f2, 28); $f0f3_2 = $f0_2->mulInt64($f3, 28); $f0f4_2 = $f0_2->mulInt64($f4, 28); $f0f5_2 = $f0_2->mulInt64($f5, 28); $f0f6_2 = $f0_2->mulInt64($f6, 28); $f0f7_2 = $f0_2->mulInt64($f7, 28); $f0f8_2 = $f0_2->mulInt64($f8, 28); $f0f9_2 = $f0_2->mulInt64($f9, 28); $f1f1_2 = $f1_2->mulInt64($f1, 28); $f1f2_2 = $f1_2->mulInt64($f2, 28); $f1f3_4 = $f1_2->mulInt64($f3_2, 28); $f1f4_2 = $f1_2->mulInt64($f4, 28); $f1f5_4 = $f1_2->mulInt64($f5_2, 30); $f1f6_2 = $f1_2->mulInt64($f6, 28); $f1f7_4 = $f1_2->mulInt64($f7_2, 28); $f1f8_2 = $f1_2->mulInt64($f8, 28); $f1f9_76 = $f9_38->mulInt64($f1_2, 30); $f2f2 = $f2->mulInt64($f2, 28); $f2f3_2 = $f2_2->mulInt64($f3, 28); $f2f4_2 = $f2_2->mulInt64($f4, 28); $f2f5_2 = $f2_2->mulInt64($f5, 28); $f2f6_2 = $f2_2->mulInt64($f6, 28); $f2f7_2 = $f2_2->mulInt64($f7, 28); $f2f8_38 = $f8_19->mulInt64($f2_2, 30); $f2f9_38 = $f9_38->mulInt64($f2, 30); $f3f3_2 = $f3_2->mulInt64($f3, 28); $f3f4_2 = $f3_2->mulInt64($f4, 28); $f3f5_4 = $f3_2->mulInt64($f5_2, 30); $f3f6_2 = $f3_2->mulInt64($f6, 28); $f3f7_76 = $f7_38->mulInt64($f3_2, 30); $f3f8_38 = $f8_19->mulInt64($f3_2, 30); $f3f9_76 = $f9_38->mulInt64($f3_2, 30); $f4f4 = $f4->mulInt64($f4, 28); $f4f5_2 = $f4_2->mulInt64($f5, 28); $f4f6_38 = $f6_19->mulInt64($f4_2, 30); $f4f7_38 = $f7_38->mulInt64($f4, 30); $f4f8_38 = $f8_19->mulInt64($f4_2, 30); $f4f9_38 = $f9_38->mulInt64($f4, 30); $f5f5_38 = $f5_38->mulInt64($f5, 30); $f5f6_38 = $f6_19->mulInt64($f5_2, 30); $f5f7_76 = $f7_38->mulInt64($f5_2, 30); $f5f8_38 = $f8_19->mulInt64($f5_2, 30); $f5f9_76 = $f9_38->mulInt64($f5_2, 30); $f6f6_19 = $f6_19->mulInt64($f6, 30); $f6f7_38 = $f7_38->mulInt64($f6, 30); $f6f8_38 = $f8_19->mulInt64($f6_2, 30); $f6f9_38 = $f9_38->mulInt64($f6, 30); $f7f7_38 = $f7_38->mulInt64($f7, 28); $f7f8_38 = $f8_19->mulInt64($f7_2, 30); $f7f9_76 = $f9_38->mulInt64($f7_2, 30); $f8f8_19 = $f8_19->mulInt64($f8, 30); $f8f9_38 = $f9_38->mulInt64($f8, 30); $f9f9_38 = $f9_38->mulInt64($f9, 28); $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38); $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38); $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19); $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38); $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38); $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38); $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19); $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38); $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38); $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 */ $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * Square and double a field element * * h = 2 * f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall */ public static function fe_sq2(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { $f0 = $f[0]->toInt64(); $f1 = $f[1]->toInt64(); $f2 = $f[2]->toInt64(); $f3 = $f[3]->toInt64(); $f4 = $f[4]->toInt64(); $f5 = $f[5]->toInt64(); $f6 = $f[6]->toInt64(); $f7 = $f[7]->toInt64(); $f8 = $f[8]->toInt64(); $f9 = $f[9]->toInt64(); $f0_2 = $f0->shiftLeft(1); $f1_2 = $f1->shiftLeft(1); $f2_2 = $f2->shiftLeft(1); $f3_2 = $f3->shiftLeft(1); $f4_2 = $f4->shiftLeft(1); $f5_2 = $f5->shiftLeft(1); $f6_2 = $f6->shiftLeft(1); $f7_2 = $f7->shiftLeft(1); $f5_38 = $f5->mulInt(38, 6); /* 1.959375*2^30 */ $f6_19 = $f6->mulInt(19, 5); /* 1.959375*2^30 */ $f7_38 = $f7->mulInt(38, 6); /* 1.959375*2^30 */ $f8_19 = $f8->mulInt(19, 5); /* 1.959375*2^30 */ $f9_38 = $f9->mulInt(38, 6); /* 1.959375*2^30 */ $f0f0 = $f0->mulInt64($f0, 28); $f0f1_2 = $f0_2->mulInt64($f1, 28); $f0f2_2 = $f0_2->mulInt64($f2, 28); $f0f3_2 = $f0_2->mulInt64($f3, 28); $f0f4_2 = $f0_2->mulInt64($f4, 28); $f0f5_2 = $f0_2->mulInt64($f5, 28); $f0f6_2 = $f0_2->mulInt64($f6, 28); $f0f7_2 = $f0_2->mulInt64($f7, 28); $f0f8_2 = $f0_2->mulInt64($f8, 28); $f0f9_2 = $f0_2->mulInt64($f9, 28); $f1f1_2 = $f1_2->mulInt64($f1, 28); $f1f2_2 = $f1_2->mulInt64($f2, 28); $f1f3_4 = $f1_2->mulInt64($f3_2, 29); $f1f4_2 = $f1_2->mulInt64($f4, 28); $f1f5_4 = $f1_2->mulInt64($f5_2, 29); $f1f6_2 = $f1_2->mulInt64($f6, 28); $f1f7_4 = $f1_2->mulInt64($f7_2, 29); $f1f8_2 = $f1_2->mulInt64($f8, 28); $f1f9_76 = $f9_38->mulInt64($f1_2, 29); $f2f2 = $f2->mulInt64($f2, 28); $f2f3_2 = $f2_2->mulInt64($f3, 28); $f2f4_2 = $f2_2->mulInt64($f4, 28); $f2f5_2 = $f2_2->mulInt64($f5, 28); $f2f6_2 = $f2_2->mulInt64($f6, 28); $f2f7_2 = $f2_2->mulInt64($f7, 28); $f2f8_38 = $f8_19->mulInt64($f2_2, 29); $f2f9_38 = $f9_38->mulInt64($f2, 29); $f3f3_2 = $f3_2->mulInt64($f3, 28); $f3f4_2 = $f3_2->mulInt64($f4, 28); $f3f5_4 = $f3_2->mulInt64($f5_2, 28); $f3f6_2 = $f3_2->mulInt64($f6, 28); $f3f7_76 = $f7_38->mulInt64($f3_2, 29); $f3f8_38 = $f8_19->mulInt64($f3_2, 29); $f3f9_76 = $f9_38->mulInt64($f3_2, 29); $f4f4 = $f4->mulInt64($f4, 28); $f4f5_2 = $f4_2->mulInt64($f5, 28); $f4f6_38 = $f6_19->mulInt64($f4_2, 29); $f4f7_38 = $f7_38->mulInt64($f4, 29); $f4f8_38 = $f8_19->mulInt64($f4_2, 29); $f4f9_38 = $f9_38->mulInt64($f4, 29); $f5f5_38 = $f5_38->mulInt64($f5, 29); $f5f6_38 = $f6_19->mulInt64($f5_2, 29); $f5f7_76 = $f7_38->mulInt64($f5_2, 29); $f5f8_38 = $f8_19->mulInt64($f5_2, 29); $f5f9_76 = $f9_38->mulInt64($f5_2, 29); $f6f6_19 = $f6_19->mulInt64($f6, 29); $f6f7_38 = $f7_38->mulInt64($f6, 29); $f6f8_38 = $f8_19->mulInt64($f6_2, 29); $f6f9_38 = $f9_38->mulInt64($f6, 29); $f7f7_38 = $f7_38->mulInt64($f7, 29); $f7f8_38 = $f8_19->mulInt64($f7_2, 29); $f7f9_76 = $f9_38->mulInt64($f7_2, 29); $f8f8_19 = $f8_19->mulInt64($f8, 29); $f8f9_38 = $f9_38->mulInt64($f8, 29); $f9f9_38 = $f9_38->mulInt64($f9, 29); $h0 = $f0f0->addInt64($f1f9_76)->addInt64($f2f8_38)->addInt64($f3f7_76)->addInt64($f4f6_38)->addInt64($f5f5_38); $h1 = $f0f1_2->addInt64($f2f9_38)->addInt64($f3f8_38)->addInt64($f4f7_38)->addInt64($f5f6_38); $h2 = $f0f2_2->addInt64($f1f1_2)->addInt64($f3f9_76)->addInt64($f4f8_38)->addInt64($f5f7_76)->addInt64($f6f6_19); $h3 = $f0f3_2->addInt64($f1f2_2)->addInt64($f4f9_38)->addInt64($f5f8_38)->addInt64($f6f7_38); $h4 = $f0f4_2->addInt64($f1f3_4)->addInt64($f2f2)->addInt64($f5f9_76)->addInt64($f6f8_38)->addInt64($f7f7_38); $h5 = $f0f5_2->addInt64($f1f4_2)->addInt64($f2f3_2)->addInt64($f6f9_38)->addInt64($f7f8_38); $h6 = $f0f6_2->addInt64($f1f5_4)->addInt64($f2f4_2)->addInt64($f3f3_2)->addInt64($f7f9_76)->addInt64($f8f8_19); $h7 = $f0f7_2->addInt64($f1f6_2)->addInt64($f2f5_2)->addInt64($f3f4_2)->addInt64($f8f9_38); $h8 = $f0f8_2->addInt64($f1f7_4)->addInt64($f2f6_2)->addInt64($f3f5_4)->addInt64($f4f4)->addInt64($f9f9_38); $h9 = $f0f9_2->addInt64($f1f8_2)->addInt64($f2f7_2)->addInt64($f3f6_2)->addInt64($f4f5_2); /** * @var ParagonIE_Sodium_Core32_Int64 $h0 * @var ParagonIE_Sodium_Core32_Int64 $h1 * @var ParagonIE_Sodium_Core32_Int64 $h2 * @var ParagonIE_Sodium_Core32_Int64 $h3 * @var ParagonIE_Sodium_Core32_Int64 $h4 * @var ParagonIE_Sodium_Core32_Int64 $h5 * @var ParagonIE_Sodium_Core32_Int64 $h6 * @var ParagonIE_Sodium_Core32_Int64 $h7 * @var ParagonIE_Sodium_Core32_Int64 $h8 * @var ParagonIE_Sodium_Core32_Int64 $h9 */ $h0 = $h0->shiftLeft(1); $h1 = $h1->shiftLeft(1); $h2 = $h2->shiftLeft(1); $h3 = $h3->shiftLeft(1); $h4 = $h4->shiftLeft(1); $h5 = $h5->shiftLeft(1); $h6 = $h6->shiftLeft(1); $h7 = $h7->shiftLeft(1); $h8 = $h8->shiftLeft(1); $h9 = $h9->shiftLeft(1); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry1 = $h1->addInt(1 << 24)->shiftRight(25); $h2 = $h2->addInt64($carry1); $h1 = $h1->subInt64($carry1->shiftLeft(25)); $carry5 = $h5->addInt(1 << 24)->shiftRight(25); $h6 = $h6->addInt64($carry5); $h5 = $h5->subInt64($carry5->shiftLeft(25)); $carry2 = $h2->addInt(1 << 25)->shiftRight(26); $h3 = $h3->addInt64($carry2); $h2 = $h2->subInt64($carry2->shiftLeft(26)); $carry6 = $h6->addInt(1 << 25)->shiftRight(26); $h7 = $h7->addInt64($carry6); $h6 = $h6->subInt64($carry6->shiftLeft(26)); $carry3 = $h3->addInt(1 << 24)->shiftRight(25); $h4 = $h4->addInt64($carry3); $h3 = $h3->subInt64($carry3->shiftLeft(25)); $carry7 = $h7->addInt(1 << 24)->shiftRight(25); $h8 = $h8->addInt64($carry7); $h7 = $h7->subInt64($carry7->shiftLeft(25)); $carry4 = $h4->addInt(1 << 25)->shiftRight(26); $h5 = $h5->addInt64($carry4); $h4 = $h4->subInt64($carry4->shiftLeft(26)); $carry8 = $h8->addInt(1 << 25)->shiftRight(26); $h9 = $h9->addInt64($carry8); $h8 = $h8->subInt64($carry8->shiftLeft(26)); $carry9 = $h9->addInt(1 << 24)->shiftRight(25); $h0 = $h0->addInt64($carry9->mulInt(19, 5)); $h9 = $h9->subInt64($carry9->shiftLeft(25)); $carry0 = $h0->addInt(1 << 25)->shiftRight(26); $h1 = $h1->addInt64($carry0); $h0 = $h0->subInt64($carry0->shiftLeft(26)); return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $h0->toInt32(), $h1->toInt32(), $h2->toInt32(), $h3->toInt32(), $h4->toInt32(), $h5->toInt32(), $h6->toInt32(), $h7->toInt32(), $h8->toInt32(), $h9->toInt32() ) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $Z * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_invert(ParagonIE_Sodium_Core32_Curve25519_Fe $Z) { $z = clone $Z; $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t2 = self::fe_sq($t0); $t1 = self::fe_mul($t1, $t2); $t2 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 20; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 100; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } return self::fe_mul($t1, $t0); } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106 * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $z * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function fe_pow22523(ParagonIE_Sodium_Core32_Curve25519_Fe $z) { # fe_sq(t0, z); # fe_sq(t1, t0); # fe_sq(t1, t1); # fe_mul(t1, z, t1); # fe_mul(t0, t0, t1); # fe_sq(t0, t0); # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t0 = self::fe_sq($t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 5; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 20; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 20; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 100; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 100; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t0, t0); # fe_sq(t0, t0); # fe_mul(out, t0, z); $t0 = self::fe_mul($t1, $t0); $t0 = self::fe_sq($t0); $t0 = self::fe_sq($t0); return self::fe_mul($t0, $z); } /** * Subtract two field elements. * * h = f - g * * Preconditions: * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * * Postconditions: * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall * @psalm-suppress MixedTypeCoercion */ public static function fe_sub(ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g) { return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( $f[0]->subInt32($g[0]), $f[1]->subInt32($g[1]), $f[2]->subInt32($g[2]), $f[3]->subInt32($g[3]), $f[4]->subInt32($g[4]), $f[5]->subInt32($g[5]), $f[6]->subInt32($g[6]), $f[7]->subInt32($g[7]), $f[8]->subInt32($g[8]), $f[9]->subInt32($g[9]) ) ); } /** * Add two group elements. * * r = p + q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_add( ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YplusX); $r->Y = self::fe_mul($r->Y, $q->YminusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215 * @param string $a * @return array<int, mixed> * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayOffset */ public static function slide($a) { if (self::strlen($a) < 256) { if (self::strlen($a) < 16) { $a = str_pad($a, 256, '0', STR_PAD_RIGHT); } } /** @var array<int, int> $r */ $r = array(); for ($i = 0; $i < 256; ++$i) { $r[$i] = (int) (1 & ( self::chrToInt($a[$i >> 3]) >> ($i & 7) ) ); } for ($i = 0;$i < 256;++$i) { if ($r[$i]) { for ($b = 1;$b <= 6 && $i + $b < 256;++$b) { if ($r[$i + $b]) { if ($r[$i] + ($r[$i + $b] << $b) <= 15) { $r[$i] += $r[$i + $b] << $b; $r[$i + $b] = 0; } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) { $r[$i] -= $r[$i + $b] << $b; for ($k = $i + $b; $k < 256; ++$k) { if (!$r[$k]) { $r[$k] = 1; break; } $r[$k] = 0; } } else { break; } } } } } return $r; } /** * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_frombytes_negate_vartime($s) { static $d = null; if (!$d) { $d = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d[9]) ) ); } /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */ # fe_frombytes(h->Y,s); # fe_1(h->Z); $h = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3( self::fe_0(), self::fe_frombytes($s), self::fe_1() ); # fe_sq(u,h->Y); # fe_mul(v,u,d); # fe_sub(u,u,h->Z); /* u = y^2-1 */ # fe_add(v,v,h->Z); /* v = dy^2+1 */ $u = self::fe_sq($h->Y); /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d */ $v = self::fe_mul($u, $d); $u = self::fe_sub($u, $h->Z); /* u = y^2 - 1 */ $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */ # fe_sq(v3,v); # fe_mul(v3,v3,v); /* v3 = v^3 */ # fe_sq(h->X,v3); # fe_mul(h->X,h->X,v); # fe_mul(h->X,h->X,u); /* x = uv^7 */ $v3 = self::fe_sq($v); $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */ $h->X = self::fe_sq($v3); $h->X = self::fe_mul($h->X, $v); $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */ # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ # fe_mul(h->X,h->X,v3); # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */ $h->X = self::fe_mul($h->X, $v3); $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */ # fe_sq(vxx,h->X); # fe_mul(vxx,vxx,v); # fe_sub(check,vxx,u); /* vx^2-u */ $vxx = self::fe_sq($h->X); $vxx = self::fe_mul($vxx, $v); $check = self::fe_sub($vxx, $u); /* vx^2 - u */ # if (fe_isnonzero(check)) { # fe_add(check,vxx,u); /* vx^2+u */ # if (fe_isnonzero(check)) { # return -1; # } # fe_mul(h->X,h->X,sqrtm1); # } if (self::fe_isnonzero($check)) { $check = self::fe_add($vxx, $u); /* vx^2 + u */ if (self::fe_isnonzero($check)) { throw new RangeException('Internal check failed.'); } $h->X = self::fe_mul( $h->X, ParagonIE_Sodium_Core32_Curve25519_Fe::fromIntArray(self::$sqrtm1) ); } # if (fe_isnegative(h->X) == (s[31] >> 7)) { # fe_neg(h->X,h->X); # } $i = self::chrToInt($s[31]); if (self::fe_isnegative($h->X) === ($i >> 7)) { $h->X = self::fe_neg($h->X); } # fe_mul(h->T,h->X,h->Y); $h->T = self::fe_mul($h->X, $h->Y); return $h; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_madd( ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yplusx); $r->Y = self::fe_mul($r->Y, $q->yminusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add(clone $p->Z, clone $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_msub( ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yminusx); $r->Y = self::fe_mul($r->Y, $q->yplusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add($p->Z, $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError */ public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P2(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P3(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); $r->T = self::fe_mul($p->X, $p->Y); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError */ public static function ge_p2_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2( self::fe_0(), self::fe_1(), self::fe_1() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_p2_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $p) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_sq($p->X); $r->Z = self::fe_sq($p->Y); $r->T = self::fe_sq2($p->Z); $r->Y = self::fe_add($p->X, $p->Y); $t0 = self::fe_sq($r->Y); $r->Y = self::fe_add($r->Z, $r->X); $r->Z = self::fe_sub($r->Z, $r->X); $r->X = self::fe_sub($t0, $r->Y); $r->T = self::fe_sub($r->T, $r->Z); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_p3_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P3( self::fe_0(), self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Cached * @throws SodiumException * @throws TypeError */ public static function ge_p3_to_cached(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { static $d2 = null; if ($d2 === null) { $d2 = ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$d2[9]) ) ); } /** @var ParagonIE_Sodium_Core32_Curve25519_Fe $d2 */ $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached(); $r->YplusX = self::fe_add($p->Y, $p->X); $r->YminusX = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_copy($p->Z); $r->T2d = self::fe_mul($p->T, $d2); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 */ public static function ge_p3_to_p2(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { return new ParagonIE_Sodium_Core32_Curve25519_Ge_P2( $p->X, $p->Y, $p->Z ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_p3_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_p3_dbl(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p) { $q = self::ge_p3_to_p2($p); return self::ge_p2_dbl($q); } /** * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError */ public static function ge_precomp_0() { return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param int $b * @param int $c * @return int * @psalm-suppress MixedReturnStatement */ public static function equal($b, $c) { $b0 = $b & 0xffff; $b1 = ($b >> 16) & 0xffff; $c0 = $c & 0xffff; $c1 = ($c >> 16) & 0xffff; $d0 = (($b0 ^ $c0) - 1) >> 31; $d1 = (($b1 ^ $c1) - 1) >> 31; return ($d0 & $d1) & 1; } /** * @internal You should not use this directly from another application * * @param string|int $char * @return int (1 = yes, 0 = no) * @throws SodiumException * @throws TypeError */ public static function negative($char) { if (is_int($char)) { return $char < 0 ? 1 : 0; } /** @var string $char */ $x = self::chrToInt(self::substr($char, 0, 1)); return (int) ($x >> 31); } /** * Conditional move * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u * @param int $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError */ public static function cmov( ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $t, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $u, $b ) { if (!is_int($b)) { throw new InvalidArgumentException('Expected an integer.'); } return new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_cmov($t->yplusx, $u->yplusx, $b), self::fe_cmov($t->yminusx, $u->yminusx, $b), self::fe_cmov($t->xy2d, $u->xy2d, $b) ); } /** * @internal You should not use this directly from another application * * @param int $pos * @param int $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedArgument */ public static function ge_select($pos = 0, $b = 0) { static $base = null; if ($base === null) { $base = array(); foreach (self::$base as $i => $bas) { for ($j = 0; $j < 8; ++$j) { $base[$i][$j] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][0][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][1][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][0]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][1]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][2]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][3]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][4]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][5]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][6]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][7]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][8]), ParagonIE_Sodium_Core32_Int32::fromInt($bas[$j][2][9]) ) ) ); } } } if (!is_int($pos)) { throw new InvalidArgumentException('Position must be an integer'); } if ($pos < 0 || $pos > 31) { throw new RangeException('Position is out of range [0, 31]'); } $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); $t = self::ge_precomp_0(); for ($i = 0; $i < 8; ++$i) { $t = self::cmov( $t, $base[$pos][$i], -self::equal($babs, $i + 1) ); } $minusT = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( self::fe_copy($t->yminusx), self::fe_copy($t->yplusx), self::fe_neg($t->xy2d) ); return self::cmov($t, $minusT, -$bnegative); } /** * Subtract two group elements. * * r = p - q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 * @throws SodiumException * @throws TypeError */ public static function ge_sub( ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YminusX); $r->Y = self::fe_mul($r->Y, $q->YplusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * Convert a group element to a byte string. * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_tobytes(ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A * @param string $b * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public static function ge_double_scalarmult_vartime( $a, ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A, $b ) { /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */ $Ai = array(); static $Bi = array(); /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */ if (!$Bi) { for ($i = 0; $i < 8; ++$i) { $Bi[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][0][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][1][9]) ) ), ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray( array( ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][0]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][1]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][2]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][3]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][4]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][5]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][6]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][7]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][8]), ParagonIE_Sodium_Core32_Int32::fromInt(self::$base2[$i][2][9]) ) ) ); } } for ($i = 0; $i < 8; ++$i) { $Ai[$i] = new ParagonIE_Sodium_Core32_Curve25519_Ge_Cached( self::fe_0(), self::fe_0(), self::fe_0(), self::fe_0() ); } /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai */ # slide(aslide,a); # slide(bslide,b); /** @var array<int, int> $aslide */ $aslide = self::slide($a); /** @var array<int, int> $bslide */ $bslide = self::slide($b); # ge_p3_to_cached(&Ai[0],A); # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); $Ai[0] = self::ge_p3_to_cached($A); $t = self::ge_p3_dbl($A); $A2 = self::ge_p1p1_to_p3($t); # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); for ($i = 0; $i < 7; ++$i) { $t = self::ge_add($A2, $Ai[$i]); $u = self::ge_p1p1_to_p3($t); $Ai[$i + 1] = self::ge_p3_to_cached($u); } # ge_p2_0(r); $r = self::ge_p2_0(); # for (i = 255;i >= 0;--i) { # if (aslide[i] || bslide[i]) break; # } $i = 255; for (; $i >= 0; --$i) { if ($aslide[$i] || $bslide[$i]) { break; } } # for (;i >= 0;--i) { for (; $i >= 0; --$i) { # ge_p2_dbl(&t,r); $t = self::ge_p2_dbl($r); # if (aslide[i] > 0) { if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_add(&t,&u,&Ai[aslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_add( $u, $Ai[(int) floor($aslide[$i] / 2)] ); # } else if (aslide[i] < 0) { } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_sub(&t,&u,&Ai[(-aslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_sub( $u, $Ai[(int) floor(-$aslide[$i] / 2)] ); } /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp> $Bi */ # if (bslide[i] > 0) { if ($bslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_madd(&t,&u,&Bi[bslide[i]/2]); $u = self::ge_p1p1_to_p3($t); /** @var int $index */ $index = (int) floor($bslide[$i] / 2); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */ $thisB = $Bi[$index]; $t = self::ge_madd($t, $u, $thisB); # } else if (bslide[i] < 0) { } elseif ($bslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_msub(&t,&u,&Bi[(-bslide[i])/2]); $u = self::ge_p1p1_to_p3($t); /** @var int $index */ $index = (int) floor(-$bslide[$i] / 2); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp $thisB */ $thisB = $Bi[$index]; $t = self::ge_msub($t, $u, $thisB); } # ge_p1p1_to_p2(r,&t); $r = self::ge_p1p1_to_p2($t); } return $r; } /** * @internal You should not use this directly from another application * * @param string $a * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand * @throws SodiumException * @throws TypeError */ public static function ge_scalarmult_base($a) { /** @var array<int, int> $e */ $e = array(); $r = new ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1(); for ($i = 0; $i < 32; ++$i) { /** @var int $dbl */ $dbl = (int) $i << 1; $e[$dbl] = (int) self::chrToInt($a[$i]) & 15; $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15; } /** @var int $carry */ $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } /** @var array<int, int> $e */ $e[63] += (int) $carry; $h = self::ge_p3_0(); for ($i = 1; $i < 64; $i += 2) { $t = self::ge_select((int) floor($i / 2), (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } $r = self::ge_p3_dbl($h); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $h = self::ge_p1p1_to_p3($r); for ($i = 0; $i < 64; $i += 2) { $t = self::ge_select($i >> 1, (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } return $h; } /** * Calculates (ab + c) mod l * where l = 2^252 + 27742317777372353535851937790883648493 * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @param string $c * @return string * @throws SodiumException * @throws TypeError */ public static function sc_muladd($a, $b, $c) { $a0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 0, 3))); $a1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5)); $a2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2)); $a3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7)); $a4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4)); $a5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1)); $a6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6)); $a7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3)); $a8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($a, 21, 3))); $a9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5)); $a10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2)); $a11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($a, 28, 4)) >> 7)); $b0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 0, 3))); $b1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5)); $b2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2)); $b3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7)); $b4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4)); $b5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1)); $b6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6)); $b7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3)); $b8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($b, 21, 3))); $b9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5)); $b10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2)); $b11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($b, 28, 4)) >> 7)); $c0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 0, 3))); $c1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5)); $c2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2)); $c3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7)); $c4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4)); $c5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1)); $c6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6)); $c7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3)); $c8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($c, 21, 3))); $c9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5)); $c10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2)); $c11 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($c, 28, 4)) >> 7)); /* Can't really avoid the pyramid here: */ /** * @var ParagonIE_Sodium_Core32_Int64 $s0 * @var ParagonIE_Sodium_Core32_Int64 $s1 * @var ParagonIE_Sodium_Core32_Int64 $s2 * @var ParagonIE_Sodium_Core32_Int64 $s3 * @var ParagonIE_Sodium_Core32_Int64 $s4 * @var ParagonIE_Sodium_Core32_Int64 $s5 * @var ParagonIE_Sodium_Core32_Int64 $s6 * @var ParagonIE_Sodium_Core32_Int64 $s7 * @var ParagonIE_Sodium_Core32_Int64 $s8 * @var ParagonIE_Sodium_Core32_Int64 $s9 * @var ParagonIE_Sodium_Core32_Int64 $s10 * @var ParagonIE_Sodium_Core32_Int64 $s11 * @var ParagonIE_Sodium_Core32_Int64 $s12 * @var ParagonIE_Sodium_Core32_Int64 $s13 * @var ParagonIE_Sodium_Core32_Int64 $s14 * @var ParagonIE_Sodium_Core32_Int64 $s15 * @var ParagonIE_Sodium_Core32_Int64 $s16 * @var ParagonIE_Sodium_Core32_Int64 $s17 * @var ParagonIE_Sodium_Core32_Int64 $s18 * @var ParagonIE_Sodium_Core32_Int64 $s19 * @var ParagonIE_Sodium_Core32_Int64 $s20 * @var ParagonIE_Sodium_Core32_Int64 $s21 * @var ParagonIE_Sodium_Core32_Int64 $s22 * @var ParagonIE_Sodium_Core32_Int64 $s23 */ $s0 = $c0->addInt64($a0->mulInt64($b0, 24)); $s1 = $c1->addInt64($a0->mulInt64($b1, 24))->addInt64($a1->mulInt64($b0, 24)); $s2 = $c2->addInt64($a0->mulInt64($b2, 24))->addInt64($a1->mulInt64($b1, 24))->addInt64($a2->mulInt64($b0, 24)); $s3 = $c3->addInt64($a0->mulInt64($b3, 24))->addInt64($a1->mulInt64($b2, 24))->addInt64($a2->mulInt64($b1, 24)) ->addInt64($a3->mulInt64($b0, 24)); $s4 = $c4->addInt64($a0->mulInt64($b4, 24))->addInt64($a1->mulInt64($b3, 24))->addInt64($a2->mulInt64($b2, 24)) ->addInt64($a3->mulInt64($b1, 24))->addInt64($a4->mulInt64($b0, 24)); $s5 = $c5->addInt64($a0->mulInt64($b5, 24))->addInt64($a1->mulInt64($b4, 24))->addInt64($a2->mulInt64($b3, 24)) ->addInt64($a3->mulInt64($b2, 24))->addInt64($a4->mulInt64($b1, 24))->addInt64($a5->mulInt64($b0, 24)); $s6 = $c6->addInt64($a0->mulInt64($b6, 24))->addInt64($a1->mulInt64($b5, 24))->addInt64($a2->mulInt64($b4, 24)) ->addInt64($a3->mulInt64($b3, 24))->addInt64($a4->mulInt64($b2, 24))->addInt64($a5->mulInt64($b1, 24)) ->addInt64($a6->mulInt64($b0, 24)); $s7 = $c7->addInt64($a0->mulInt64($b7, 24))->addInt64($a1->mulInt64($b6, 24))->addInt64($a2->mulInt64($b5, 24)) ->addInt64($a3->mulInt64($b4, 24))->addInt64($a4->mulInt64($b3, 24))->addInt64($a5->mulInt64($b2, 24)) ->addInt64($a6->mulInt64($b1, 24))->addInt64($a7->mulInt64($b0, 24)); $s8 = $c8->addInt64($a0->mulInt64($b8, 24))->addInt64($a1->mulInt64($b7, 24))->addInt64($a2->mulInt64($b6, 24)) ->addInt64($a3->mulInt64($b5, 24))->addInt64($a4->mulInt64($b4, 24))->addInt64($a5->mulInt64($b3, 24)) ->addInt64($a6->mulInt64($b2, 24))->addInt64($a7->mulInt64($b1, 24))->addInt64($a8->mulInt64($b0, 24)); $s9 = $c9->addInt64($a0->mulInt64($b9, 24))->addInt64($a1->mulInt64($b8, 24))->addInt64($a2->mulInt64($b7, 24)) ->addInt64($a3->mulInt64($b6, 24))->addInt64($a4->mulInt64($b5, 24))->addInt64($a5->mulInt64($b4, 24)) ->addInt64($a6->mulInt64($b3, 24))->addInt64($a7->mulInt64($b2, 24))->addInt64($a8->mulInt64($b1, 24)) ->addInt64($a9->mulInt64($b0, 24)); $s10 = $c10->addInt64($a0->mulInt64($b10, 24))->addInt64($a1->mulInt64($b9, 24))->addInt64($a2->mulInt64($b8, 24)) ->addInt64($a3->mulInt64($b7, 24))->addInt64($a4->mulInt64($b6, 24))->addInt64($a5->mulInt64($b5, 24)) ->addInt64($a6->mulInt64($b4, 24))->addInt64($a7->mulInt64($b3, 24))->addInt64($a8->mulInt64($b2, 24)) ->addInt64($a9->mulInt64($b1, 24))->addInt64($a10->mulInt64($b0, 24)); $s11 = $c11->addInt64($a0->mulInt64($b11, 24))->addInt64($a1->mulInt64($b10, 24))->addInt64($a2->mulInt64($b9, 24)) ->addInt64($a3->mulInt64($b8, 24))->addInt64($a4->mulInt64($b7, 24))->addInt64($a5->mulInt64($b6, 24)) ->addInt64($a6->mulInt64($b5, 24))->addInt64($a7->mulInt64($b4, 24))->addInt64($a8->mulInt64($b3, 24)) ->addInt64($a9->mulInt64($b2, 24))->addInt64($a10->mulInt64($b1, 24))->addInt64($a11->mulInt64($b0, 24)); $s12 = $a1->mulInt64($b11, 24)->addInt64($a2->mulInt64($b10, 24))->addInt64($a3->mulInt64($b9, 24)) ->addInt64($a4->mulInt64($b8, 24))->addInt64($a5->mulInt64($b7, 24))->addInt64($a6->mulInt64($b6, 24)) ->addInt64($a7->mulInt64($b5, 24))->addInt64($a8->mulInt64($b4, 24))->addInt64($a9->mulInt64($b3, 24)) ->addInt64($a10->mulInt64($b2, 24))->addInt64($a11->mulInt64($b1, 24)); $s13 = $a2->mulInt64($b11, 24)->addInt64($a3->mulInt64($b10, 24))->addInt64($a4->mulInt64($b9, 24)) ->addInt64($a5->mulInt64($b8, 24))->addInt64($a6->mulInt64($b7, 24))->addInt64($a7->mulInt64($b6, 24)) ->addInt64($a8->mulInt64($b5, 24))->addInt64($a9->mulInt64($b4, 24))->addInt64($a10->mulInt64($b3, 24)) ->addInt64($a11->mulInt64($b2, 24)); $s14 = $a3->mulInt64($b11, 24)->addInt64($a4->mulInt64($b10, 24))->addInt64($a5->mulInt64($b9, 24)) ->addInt64($a6->mulInt64($b8, 24))->addInt64($a7->mulInt64($b7, 24))->addInt64($a8->mulInt64($b6, 24)) ->addInt64($a9->mulInt64($b5, 24))->addInt64($a10->mulInt64($b4, 24))->addInt64($a11->mulInt64($b3, 24)); $s15 = $a4->mulInt64($b11, 24)->addInt64($a5->mulInt64($b10, 24))->addInt64($a6->mulInt64($b9, 24)) ->addInt64($a7->mulInt64($b8, 24))->addInt64($a8->mulInt64($b7, 24))->addInt64($a9->mulInt64($b6, 24)) ->addInt64($a10->mulInt64($b5, 24))->addInt64($a11->mulInt64($b4, 24)); $s16 = $a5->mulInt64($b11, 24)->addInt64($a6->mulInt64($b10, 24))->addInt64($a7->mulInt64($b9, 24)) ->addInt64($a8->mulInt64($b8, 24))->addInt64($a9->mulInt64($b7, 24))->addInt64($a10->mulInt64($b6, 24)) ->addInt64($a11->mulInt64($b5, 24)); $s17 = $a6->mulInt64($b11, 24)->addInt64($a7->mulInt64($b10, 24))->addInt64($a8->mulInt64($b9, 24)) ->addInt64($a9->mulInt64($b8, 24))->addInt64($a10->mulInt64($b7, 24))->addInt64($a11->mulInt64($b6, 24)); $s18 = $a7->mulInt64($b11, 24)->addInt64($a8->mulInt64($b10, 24))->addInt64($a9->mulInt64($b9, 24)) ->addInt64($a10->mulInt64($b8, 24))->addInt64($a11->mulInt64($b7, 24)); $s19 = $a8->mulInt64($b11, 24)->addInt64($a9->mulInt64($b10, 24))->addInt64($a10->mulInt64($b9, 24)) ->addInt64($a11->mulInt64($b8, 24)); $s20 = $a9->mulInt64($b11, 24)->addInt64($a10->mulInt64($b10, 24))->addInt64($a11->mulInt64($b9, 24)); $s21 = $a10->mulInt64($b11, 24)->addInt64($a11->mulInt64($b10, 24)); $s22 = $a11->mulInt64($b11, 24); $s23 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry18 = $s18->addInt(1 << 20)->shiftRight(21); $s19 = $s19->addInt64($carry18); $s18 = $s18->subInt64($carry18->shiftLeft(21)); $carry20 = $s20->addInt(1 << 20)->shiftRight(21); $s21 = $s21->addInt64($carry20); $s20 = $s20->subInt64($carry20->shiftLeft(21)); $carry22 = $s22->addInt(1 << 20)->shiftRight(21); $s23 = $s23->addInt64($carry22); $s22 = $s22->subInt64($carry22->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $carry17 = $s17->addInt(1 << 20)->shiftRight(21); $s18 = $s18->addInt64($carry17); $s17 = $s17->subInt64($carry17->shiftLeft(21)); $carry19 = $s19->addInt(1 << 20)->shiftRight(21); $s20 = $s20->addInt64($carry19); $s19 = $s19->subInt64($carry19->shiftLeft(21)); $carry21 = $s21->addInt(1 << 20)->shiftRight(21); $s22 = $s22->addInt64($carry21); $s21 = $s21->subInt64($carry21->shiftLeft(21)); $s11 = $s11->addInt64($s23->mulInt(666643, 20)); $s12 = $s12->addInt64($s23->mulInt(470296, 19)); $s13 = $s13->addInt64($s23->mulInt(654183, 20)); $s14 = $s14->subInt64($s23->mulInt(997805, 20)); $s15 = $s15->addInt64($s23->mulInt(136657, 18)); $s16 = $s16->subInt64($s23->mulInt(683901, 20)); $s10 = $s10->addInt64($s22->mulInt(666643, 20)); $s11 = $s11->addInt64($s22->mulInt(470296, 19)); $s12 = $s12->addInt64($s22->mulInt(654183, 20)); $s13 = $s13->subInt64($s22->mulInt(997805, 20)); $s14 = $s14->addInt64($s22->mulInt(136657, 18)); $s15 = $s15->subInt64($s22->mulInt(683901, 20)); $s9 = $s9->addInt64($s21->mulInt(666643, 20)); $s10 = $s10->addInt64($s21->mulInt(470296, 19)); $s11 = $s11->addInt64($s21->mulInt(654183, 20)); $s12 = $s12->subInt64($s21->mulInt(997805, 20)); $s13 = $s13->addInt64($s21->mulInt(136657, 18)); $s14 = $s14->subInt64($s21->mulInt(683901, 20)); $s8 = $s8->addInt64($s20->mulInt(666643, 20)); $s9 = $s9->addInt64($s20->mulInt(470296, 19)); $s10 = $s10->addInt64($s20->mulInt(654183, 20)); $s11 = $s11->subInt64($s20->mulInt(997805, 20)); $s12 = $s12->addInt64($s20->mulInt(136657, 18)); $s13 = $s13->subInt64($s20->mulInt(683901, 20)); $s7 = $s7->addInt64($s19->mulInt(666643, 20)); $s8 = $s8->addInt64($s19->mulInt(470296, 19)); $s9 = $s9->addInt64($s19->mulInt(654183, 20)); $s10 = $s10->subInt64($s19->mulInt(997805, 20)); $s11 = $s11->addInt64($s19->mulInt(136657, 18)); $s12 = $s12->subInt64($s19->mulInt(683901, 20)); $s6 = $s6->addInt64($s18->mulInt(666643, 20)); $s7 = $s7->addInt64($s18->mulInt(470296, 19)); $s8 = $s8->addInt64($s18->mulInt(654183, 20)); $s9 = $s9->subInt64($s18->mulInt(997805, 20)); $s10 = $s10->addInt64($s18->mulInt(136657, 18)); $s11 = $s11->subInt64($s18->mulInt(683901, 20)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $s5 = $s5->addInt64($s17->mulInt(666643, 20)); $s6 = $s6->addInt64($s17->mulInt(470296, 19)); $s7 = $s7->addInt64($s17->mulInt(654183, 20)); $s8 = $s8->subInt64($s17->mulInt(997805, 20)); $s9 = $s9->addInt64($s17->mulInt(136657, 18)); $s10 = $s10->subInt64($s17->mulInt(683901, 20)); $s4 = $s4->addInt64($s16->mulInt(666643, 20)); $s5 = $s5->addInt64($s16->mulInt(470296, 19)); $s6 = $s6->addInt64($s16->mulInt(654183, 20)); $s7 = $s7->subInt64($s16->mulInt(997805, 20)); $s8 = $s8->addInt64($s16->mulInt(136657, 18)); $s9 = $s9->subInt64($s16->mulInt(683901, 20)); $s3 = $s3->addInt64($s15->mulInt(666643, 20)); $s4 = $s4->addInt64($s15->mulInt(470296, 19)); $s5 = $s5->addInt64($s15->mulInt(654183, 20)); $s6 = $s6->subInt64($s15->mulInt(997805, 20)); $s7 = $s7->addInt64($s15->mulInt(136657, 18)); $s8 = $s8->subInt64($s15->mulInt(683901, 20)); $s2 = $s2->addInt64($s14->mulInt(666643, 20)); $s3 = $s3->addInt64($s14->mulInt(470296, 19)); $s4 = $s4->addInt64($s14->mulInt(654183, 20)); $s5 = $s5->subInt64($s14->mulInt(997805, 20)); $s6 = $s6->addInt64($s14->mulInt(136657, 18)); $s7 = $s7->subInt64($s14->mulInt(683901, 20)); $s1 = $s1->addInt64($s13->mulInt(666643, 20)); $s2 = $s2->addInt64($s13->mulInt(470296, 19)); $s3 = $s3->addInt64($s13->mulInt(654183, 20)); $s4 = $s4->subInt64($s13->mulInt(997805, 20)); $s5 = $s5->addInt64($s13->mulInt(136657, 18)); $s6 = $s6->subInt64($s13->mulInt(683901, 20)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry11 = $s11->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s10->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $S0 = $s0->toInt(); $S1 = $s1->toInt(); $S2 = $s2->toInt(); $S3 = $s3->toInt(); $S4 = $s4->toInt(); $S5 = $s5->toInt(); $S6 = $s6->toInt(); $S7 = $s7->toInt(); $S8 = $s8->toInt(); $S9 = $s9->toInt(); $S10 = $s10->toInt(); $S11 = $s11->toInt(); /** * @var array<int, int> */ $arr = array( (int) (0xff & ($S0 >> 0)), (int) (0xff & ($S0 >> 8)), (int) (0xff & (($S0 >> 16) | ($S1 << 5))), (int) (0xff & ($S1 >> 3)), (int) (0xff & ($S1 >> 11)), (int) (0xff & (($S1 >> 19) | ($S2 << 2))), (int) (0xff & ($S2 >> 6)), (int) (0xff & (($S2 >> 14) | ($S3 << 7))), (int) (0xff & ($S3 >> 1)), (int) (0xff & ($S3 >> 9)), (int) (0xff & (($S3 >> 17) | ($S4 << 4))), (int) (0xff & ($S4 >> 4)), (int) (0xff & ($S4 >> 12)), (int) (0xff & (($S4 >> 20) | ($S5 << 1))), (int) (0xff & ($S5 >> 7)), (int) (0xff & (($S5 >> 15) | ($S6 << 6))), (int) (0xff & ($S6 >> 2)), (int) (0xff & ($S6 >> 10)), (int) (0xff & (($S6 >> 18) | ($S7 << 3))), (int) (0xff & ($S7 >> 5)), (int) (0xff & ($S7 >> 13)), (int) (0xff & ($S8 >> 0)), (int) (0xff & ($S8 >> 8)), (int) (0xff & (($S8 >> 16) | ($S9 << 5))), (int) (0xff & ($S9 >> 3)), (int) (0xff & ($S9 >> 11)), (int) (0xff & (($S9 >> 19) | ($S10 << 2))), (int) (0xff & ($S10 >> 6)), (int) (0xff & (($S10 >> 14) | ($S11 << 7))), (int) (0xff & ($S11 >> 1)), (int) (0xff & ($S11 >> 9)), (int) (0xff & ($S11 >> 17)) ); return self::intArrayToString($arr); } /** * @internal You should not use this directly from another application * * @param string $s * @return string * @throws SodiumException * @throws TypeError */ public static function sc_reduce($s) { /** * @var ParagonIE_Sodium_Core32_Int64 $s0 * @var ParagonIE_Sodium_Core32_Int64 $s1 * @var ParagonIE_Sodium_Core32_Int64 $s2 * @var ParagonIE_Sodium_Core32_Int64 $s3 * @var ParagonIE_Sodium_Core32_Int64 $s4 * @var ParagonIE_Sodium_Core32_Int64 $s5 * @var ParagonIE_Sodium_Core32_Int64 $s6 * @var ParagonIE_Sodium_Core32_Int64 $s7 * @var ParagonIE_Sodium_Core32_Int64 $s8 * @var ParagonIE_Sodium_Core32_Int64 $s9 * @var ParagonIE_Sodium_Core32_Int64 $s10 * @var ParagonIE_Sodium_Core32_Int64 $s11 * @var ParagonIE_Sodium_Core32_Int64 $s12 * @var ParagonIE_Sodium_Core32_Int64 $s13 * @var ParagonIE_Sodium_Core32_Int64 $s14 * @var ParagonIE_Sodium_Core32_Int64 $s15 * @var ParagonIE_Sodium_Core32_Int64 $s16 * @var ParagonIE_Sodium_Core32_Int64 $s17 * @var ParagonIE_Sodium_Core32_Int64 $s18 * @var ParagonIE_Sodium_Core32_Int64 $s19 * @var ParagonIE_Sodium_Core32_Int64 $s20 * @var ParagonIE_Sodium_Core32_Int64 $s21 * @var ParagonIE_Sodium_Core32_Int64 $s22 * @var ParagonIE_Sodium_Core32_Int64 $s23 */ $s0 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 0, 3))); $s1 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5)); $s2 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2)); $s3 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7)); $s4 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4)); $s5 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1)); $s6 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6)); $s7 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3)); $s8 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 21, 3))); $s9 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5)); $s10 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2)); $s11 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7)); $s12 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4)); $s13 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1)); $s14 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6)); $s15 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3)); $s16 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & self::load_3(self::substr($s, 42, 3))); $s17 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5)); $s18 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2)); $s19 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7)); $s20 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4)); $s21 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1)); $s22 = ParagonIE_Sodium_Core32_Int64::fromInt(2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6)); $s23 = ParagonIE_Sodium_Core32_Int64::fromInt(0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3)); $s11 = $s11->addInt64($s23->mulInt(666643, 20)); $s12 = $s12->addInt64($s23->mulInt(470296, 19)); $s13 = $s13->addInt64($s23->mulInt(654183, 20)); $s14 = $s14->subInt64($s23->mulInt(997805, 20)); $s15 = $s15->addInt64($s23->mulInt(136657, 18)); $s16 = $s16->subInt64($s23->mulInt(683901, 20)); $s10 = $s10->addInt64($s22->mulInt(666643, 20)); $s11 = $s11->addInt64($s22->mulInt(470296, 19)); $s12 = $s12->addInt64($s22->mulInt(654183, 20)); $s13 = $s13->subInt64($s22->mulInt(997805, 20)); $s14 = $s14->addInt64($s22->mulInt(136657, 18)); $s15 = $s15->subInt64($s22->mulInt(683901, 20)); $s9 = $s9->addInt64($s21->mulInt(666643, 20)); $s10 = $s10->addInt64($s21->mulInt(470296, 19)); $s11 = $s11->addInt64($s21->mulInt(654183, 20)); $s12 = $s12->subInt64($s21->mulInt(997805, 20)); $s13 = $s13->addInt64($s21->mulInt(136657, 18)); $s14 = $s14->subInt64($s21->mulInt(683901, 20)); $s8 = $s8->addInt64($s20->mulInt(666643, 20)); $s9 = $s9->addInt64($s20->mulInt(470296, 19)); $s10 = $s10->addInt64($s20->mulInt(654183, 20)); $s11 = $s11->subInt64($s20->mulInt(997805, 20)); $s12 = $s12->addInt64($s20->mulInt(136657, 18)); $s13 = $s13->subInt64($s20->mulInt(683901, 20)); $s7 = $s7->addInt64($s19->mulInt(666643, 20)); $s8 = $s8->addInt64($s19->mulInt(470296, 19)); $s9 = $s9->addInt64($s19->mulInt(654183, 20)); $s10 = $s10->subInt64($s19->mulInt(997805, 20)); $s11 = $s11->addInt64($s19->mulInt(136657, 18)); $s12 = $s12->subInt64($s19->mulInt(683901, 20)); $s6 = $s6->addInt64($s18->mulInt(666643, 20)); $s7 = $s7->addInt64($s18->mulInt(470296, 19)); $s8 = $s8->addInt64($s18->mulInt(654183, 20)); $s9 = $s9->subInt64($s18->mulInt(997805, 20)); $s10 = $s10->addInt64($s18->mulInt(136657, 18)); $s11 = $s11->subInt64($s18->mulInt(683901, 20)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry12 = $s12->addInt(1 << 20)->shiftRight(21); $s13 = $s13->addInt64($carry12); $s12 = $s12->subInt64($carry12->shiftLeft(21)); $carry14 = $s14->addInt(1 << 20)->shiftRight(21); $s15 = $s15->addInt64($carry14); $s14 = $s14->subInt64($carry14->shiftLeft(21)); $carry16 = $s16->addInt(1 << 20)->shiftRight(21); $s17 = $s17->addInt64($carry16); $s16 = $s16->subInt64($carry16->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $carry13 = $s13->addInt(1 << 20)->shiftRight(21); $s14 = $s14->addInt64($carry13); $s13 = $s13->subInt64($carry13->shiftLeft(21)); $carry15 = $s15->addInt(1 << 20)->shiftRight(21); $s16 = $s16->addInt64($carry15); $s15 = $s15->subInt64($carry15->shiftLeft(21)); $s5 = $s5->addInt64($s17->mulInt(666643, 20)); $s6 = $s6->addInt64($s17->mulInt(470296, 19)); $s7 = $s7->addInt64($s17->mulInt(654183, 20)); $s8 = $s8->subInt64($s17->mulInt(997805, 20)); $s9 = $s9->addInt64($s17->mulInt(136657, 18)); $s10 = $s10->subInt64($s17->mulInt(683901, 20)); $s4 = $s4->addInt64($s16->mulInt(666643, 20)); $s5 = $s5->addInt64($s16->mulInt(470296, 19)); $s6 = $s6->addInt64($s16->mulInt(654183, 20)); $s7 = $s7->subInt64($s16->mulInt(997805, 20)); $s8 = $s8->addInt64($s16->mulInt(136657, 18)); $s9 = $s9->subInt64($s16->mulInt(683901, 20)); $s3 = $s3->addInt64($s15->mulInt(666643, 20)); $s4 = $s4->addInt64($s15->mulInt(470296, 19)); $s5 = $s5->addInt64($s15->mulInt(654183, 20)); $s6 = $s6->subInt64($s15->mulInt(997805, 20)); $s7 = $s7->addInt64($s15->mulInt(136657, 18)); $s8 = $s8->subInt64($s15->mulInt(683901, 20)); $s2 = $s2->addInt64($s14->mulInt(666643, 20)); $s3 = $s3->addInt64($s14->mulInt(470296, 19)); $s4 = $s4->addInt64($s14->mulInt(654183, 20)); $s5 = $s5->subInt64($s14->mulInt(997805, 20)); $s6 = $s6->addInt64($s14->mulInt(136657, 18)); $s7 = $s7->subInt64($s14->mulInt(683901, 20)); $s1 = $s1->addInt64($s13->mulInt(666643, 20)); $s2 = $s2->addInt64($s13->mulInt(470296, 19)); $s3 = $s3->addInt64($s13->mulInt(654183, 20)); $s4 = $s4->subInt64($s13->mulInt(997805, 20)); $s5 = $s5->addInt64($s13->mulInt(136657, 18)); $s6 = $s6->subInt64($s13->mulInt(683901, 20)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->addInt(1 << 20)->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry2 = $s2->addInt(1 << 20)->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry4 = $s4->addInt(1 << 20)->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry6 = $s6->addInt(1 << 20)->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry8 = $s8->addInt(1 << 20)->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry10 = $s10->addInt(1 << 20)->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry1 = $s1->addInt(1 << 20)->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry3 = $s3->addInt(1 << 20)->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry5 = $s5->addInt(1 << 20)->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry7 = $s7->addInt(1 << 20)->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry9 = $s9->addInt(1 << 20)->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry11 = $s11->addInt(1 << 20)->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $s12 = new ParagonIE_Sodium_Core32_Int64(); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $carry11 = $s11->shiftRight(21); $s12 = $s12->addInt64($carry11); $s11 = $s11->subInt64($carry11->shiftLeft(21)); $s0 = $s0->addInt64($s12->mulInt(666643, 20)); $s1 = $s1->addInt64($s12->mulInt(470296, 19)); $s2 = $s2->addInt64($s12->mulInt(654183, 20)); $s3 = $s3->subInt64($s12->mulInt(997805, 20)); $s4 = $s4->addInt64($s12->mulInt(136657, 18)); $s5 = $s5->subInt64($s12->mulInt(683901, 20)); $carry0 = $s0->shiftRight(21); $s1 = $s1->addInt64($carry0); $s0 = $s0->subInt64($carry0->shiftLeft(21)); $carry1 = $s1->shiftRight(21); $s2 = $s2->addInt64($carry1); $s1 = $s1->subInt64($carry1->shiftLeft(21)); $carry2 = $s2->shiftRight(21); $s3 = $s3->addInt64($carry2); $s2 = $s2->subInt64($carry2->shiftLeft(21)); $carry3 = $s3->shiftRight(21); $s4 = $s4->addInt64($carry3); $s3 = $s3->subInt64($carry3->shiftLeft(21)); $carry4 = $s4->shiftRight(21); $s5 = $s5->addInt64($carry4); $s4 = $s4->subInt64($carry4->shiftLeft(21)); $carry5 = $s5->shiftRight(21); $s6 = $s6->addInt64($carry5); $s5 = $s5->subInt64($carry5->shiftLeft(21)); $carry6 = $s6->shiftRight(21); $s7 = $s7->addInt64($carry6); $s6 = $s6->subInt64($carry6->shiftLeft(21)); $carry7 = $s7->shiftRight(21); $s8 = $s8->addInt64($carry7); $s7 = $s7->subInt64($carry7->shiftLeft(21)); $carry8 = $s8->shiftRight(21); $s9 = $s9->addInt64($carry8); $s8 = $s8->subInt64($carry8->shiftLeft(21)); $carry9 = $s9->shiftRight(21); $s10 = $s10->addInt64($carry9); $s9 = $s9->subInt64($carry9->shiftLeft(21)); $carry10 = $s10->shiftRight(21); $s11 = $s11->addInt64($carry10); $s10 = $s10->subInt64($carry10->shiftLeft(21)); $S0 = $s0->toInt32()->toInt(); $S1 = $s1->toInt32()->toInt(); $S2 = $s2->toInt32()->toInt(); $S3 = $s3->toInt32()->toInt(); $S4 = $s4->toInt32()->toInt(); $S5 = $s5->toInt32()->toInt(); $S6 = $s6->toInt32()->toInt(); $S7 = $s7->toInt32()->toInt(); $S8 = $s8->toInt32()->toInt(); $S9 = $s9->toInt32()->toInt(); $S10 = $s10->toInt32()->toInt(); $S11 = $s11->toInt32()->toInt(); /** * @var array<int, int> */ $arr = array( (int) ($S0 >> 0), (int) ($S0 >> 8), (int) (($S0 >> 16) | ($S1 << 5)), (int) ($S1 >> 3), (int) ($S1 >> 11), (int) (($S1 >> 19) | ($S2 << 2)), (int) ($S2 >> 6), (int) (($S2 >> 14) | ($S3 << 7)), (int) ($S3 >> 1), (int) ($S3 >> 9), (int) (($S3 >> 17) | ($S4 << 4)), (int) ($S4 >> 4), (int) ($S4 >> 12), (int) (($S4 >> 20) | ($S5 << 1)), (int) ($S5 >> 7), (int) (($S5 >> 15) | ($S6 << 6)), (int) ($S6 >> 2), (int) ($S6 >> 10), (int) (($S6 >> 18) | ($S7 << 3)), (int) ($S7 >> 5), (int) ($S7 >> 13), (int) ($S8 >> 0), (int) ($S8 >> 8), (int) (($S8 >> 16) | ($S9 << 5)), (int) ($S9 >> 3), (int) ($S9 >> 11), (int) (($S9 >> 19) | ($S10 << 2)), (int) ($S10 >> 6), (int) (($S10 >> 14) | ($S11 << 7)), (int) ($S11 >> 1), (int) ($S11 >> 9), (int) $S11 >> 17 ); return self::intArrayToString($arr); } /** * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 * * @param ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A * @return ParagonIE_Sodium_Core32_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_mul_l(ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A) { $aslide = array( 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 ); /** @var array<int, ParagonIE_Sodium_Core32_Curve25519_Ge_Cached> $Ai size 8 */ $Ai = array(); # ge_p3_to_cached(&Ai[0], A); $Ai[0] = self::ge_p3_to_cached($A); # ge_p3_dbl(&t, A); $t = self::ge_p3_dbl($A); # ge_p1p1_to_p3(&A2, &t); $A2 = self::ge_p1p1_to_p3($t); for ($i = 1; $i < 8; ++$i) { # ge_add(&t, &A2, &Ai[0]); $t = self::ge_add($A2, $Ai[$i - 1]); # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_p3_to_cached(&Ai[i], &u); $Ai[$i] = self::ge_p3_to_cached($u); } $r = self::ge_p3_0(); for ($i = 252; $i >= 0; --$i) { $t = self::ge_p3_dbl($r); if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_add(&t, &u, &Ai[aslide[i] / 2]); $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]); } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]); } } # ge_p1p1_to_p3(r, &t); return self::ge_p1p1_to_p3($t); } } <?php if (class_exists('ParagonIE_Sodium_Core32_SipHash', false)) { return; } /** * Class ParagonIE_SodiumCompat_Core32_SipHash * * Only uses 32-bit arithmetic, while the original SipHash used 64-bit integers */ class ParagonIE_Sodium_Core32_SipHash extends ParagonIE_Sodium_Core32_Util { /** * @internal You should not use this directly from another application * * @param array<int, ParagonIE_Sodium_Core32_Int64> $v * @return array<int, ParagonIE_Sodium_Core32_Int64> */ public static function sipRound(array $v) { # v0 += v1; $v[0] = $v[0]->addInt64($v[1]); # v1 = ROTL(v1, 13); $v[1] = $v[1]->rotateLeft(13); # v1 ^= v0; $v[1] = $v[1]->xorInt64($v[0]); # v0=ROTL(v0,32); $v[0] = $v[0]->rotateLeft(32); # v2 += v3; $v[2] = $v[2]->addInt64($v[3]); # v3=ROTL(v3,16); $v[3] = $v[3]->rotateLeft(16); # v3 ^= v2; $v[3] = $v[3]->xorInt64($v[2]); # v0 += v3; $v[0] = $v[0]->addInt64($v[3]); # v3=ROTL(v3,21); $v[3] = $v[3]->rotateLeft(21); # v3 ^= v0; $v[3] = $v[3]->xorInt64($v[0]); # v2 += v1; $v[2] = $v[2]->addInt64($v[1]); # v1=ROTL(v1,17); $v[1] = $v[1]->rotateLeft(17); # v1 ^= v2; $v[1] = $v[1]->xorInt64($v[2]); # v2=ROTL(v2,32) $v[2] = $v[2]->rotateLeft(32); return $v; } /** * @internal You should not use this directly from another application * * @param string $in * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function sipHash24($in, $key) { $inlen = self::strlen($in); # /* "somepseudorandomlygeneratedbytes" */ # u64 v0 = 0x736f6d6570736575ULL; # u64 v1 = 0x646f72616e646f6dULL; # u64 v2 = 0x6c7967656e657261ULL; # u64 v3 = 0x7465646279746573ULL; $v = array( new ParagonIE_Sodium_Core32_Int64( array(0x736f, 0x6d65, 0x7073, 0x6575) ), new ParagonIE_Sodium_Core32_Int64( array(0x646f, 0x7261, 0x6e64, 0x6f6d) ), new ParagonIE_Sodium_Core32_Int64( array(0x6c79, 0x6765, 0x6e65, 0x7261) ), new ParagonIE_Sodium_Core32_Int64( array(0x7465, 0x6462, 0x7974, 0x6573) ) ); # u64 k0 = LOAD64_LE( k ); # u64 k1 = LOAD64_LE( k + 8 ); $k = array( ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($key, 0, 8) ), ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($key, 8, 8) ) ); # b = ( ( u64 )inlen ) << 56; $b = new ParagonIE_Sodium_Core32_Int64( array(($inlen << 8) & 0xffff, 0, 0, 0) ); # v3 ^= k1; $v[3] = $v[3]->xorInt64($k[1]); # v2 ^= k0; $v[2] = $v[2]->xorInt64($k[0]); # v1 ^= k1; $v[1] = $v[1]->xorInt64($k[1]); # v0 ^= k0; $v[0] = $v[0]->xorInt64($k[0]); $left = $inlen; # for ( ; in != end; in += 8 ) while ($left >= 8) { # m = LOAD64_LE( in ); $m = ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($in, 0, 8) ); # v3 ^= m; $v[3] = $v[3]->xorInt64($m); # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); # v0 ^= m; $v[0] = $v[0]->xorInt64($m); $in = self::substr($in, 8); $left -= 8; } # switch( left ) # { # case 7: b |= ( ( u64 )in[ 6] ) << 48; # case 6: b |= ( ( u64 )in[ 5] ) << 40; # case 5: b |= ( ( u64 )in[ 4] ) << 32; # case 4: b |= ( ( u64 )in[ 3] ) << 24; # case 3: b |= ( ( u64 )in[ 2] ) << 16; # case 2: b |= ( ( u64 )in[ 1] ) << 8; # case 1: b |= ( ( u64 )in[ 0] ); break; # case 0: break; # } switch ($left) { case 7: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( 0, self::chrToInt($in[6]) << 16 ) ); case 6: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( 0, self::chrToInt($in[5]) << 8 ) ); case 5: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( 0, self::chrToInt($in[4]) ) ); case 4: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( self::chrToInt($in[3]) << 24, 0 ) ); case 3: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( self::chrToInt($in[2]) << 16, 0 ) ); case 2: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( self::chrToInt($in[1]) << 8, 0 ) ); case 1: $b = $b->orInt64( ParagonIE_Sodium_Core32_Int64::fromInts( self::chrToInt($in[0]), 0 ) ); case 0: break; } # v3 ^= b; $v[3] = $v[3]->xorInt64($b); # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); # v0 ^= b; $v[0] = $v[0]->xorInt64($b); // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation # v2 ^= 0xff; $v[2]->limbs[3] ^= 0xff; # SIPROUND; # SIPROUND; # SIPROUND; # SIPROUND; $v = self::sipRound($v); $v = self::sipRound($v); $v = self::sipRound($v); $v = self::sipRound($v); # b = v0 ^ v1 ^ v2 ^ v3; # STORE64_LE( out, b ); return $v[0] ->xorInt64($v[1]) ->xorInt64($v[2]) ->xorInt64($v[3]) ->toReverseString(); } } <?php if (class_exists('ParagonIE_Sodium_Core32_HSalsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_HSalsa20 */ abstract class ParagonIE_Sodium_Core32_HSalsa20 extends ParagonIE_Sodium_Core32_Salsa20 { /** * Calculate an hsalsa20 hash of a single block * * HSalsa20 doesn't have a counter and will never be used for more than * one block (used to derive a subkey for xsalsa20). * * @internal You should not use this directly from another application * * @param string $in * @param string $k * @param string|null $c * @return string * @throws SodiumException * @throws TypeError */ public static function hsalsa20($in, $k, $c = null) { /** * @var ParagonIE_Sodium_Core32_Int32 $x0 * @var ParagonIE_Sodium_Core32_Int32 $x1 * @var ParagonIE_Sodium_Core32_Int32 $x2 * @var ParagonIE_Sodium_Core32_Int32 $x3 * @var ParagonIE_Sodium_Core32_Int32 $x4 * @var ParagonIE_Sodium_Core32_Int32 $x5 * @var ParagonIE_Sodium_Core32_Int32 $x6 * @var ParagonIE_Sodium_Core32_Int32 $x7 * @var ParagonIE_Sodium_Core32_Int32 $x8 * @var ParagonIE_Sodium_Core32_Int32 $x9 * @var ParagonIE_Sodium_Core32_Int32 $x10 * @var ParagonIE_Sodium_Core32_Int32 $x11 * @var ParagonIE_Sodium_Core32_Int32 $x12 * @var ParagonIE_Sodium_Core32_Int32 $x13 * @var ParagonIE_Sodium_Core32_Int32 $x14 * @var ParagonIE_Sodium_Core32_Int32 $x15 * @var ParagonIE_Sodium_Core32_Int32 $j0 * @var ParagonIE_Sodium_Core32_Int32 $j1 * @var ParagonIE_Sodium_Core32_Int32 $j2 * @var ParagonIE_Sodium_Core32_Int32 $j3 * @var ParagonIE_Sodium_Core32_Int32 $j4 * @var ParagonIE_Sodium_Core32_Int32 $j5 * @var ParagonIE_Sodium_Core32_Int32 $j6 * @var ParagonIE_Sodium_Core32_Int32 $j7 * @var ParagonIE_Sodium_Core32_Int32 $j8 * @var ParagonIE_Sodium_Core32_Int32 $j9 * @var ParagonIE_Sodium_Core32_Int32 $j10 * @var ParagonIE_Sodium_Core32_Int32 $j11 * @var ParagonIE_Sodium_Core32_Int32 $j12 * @var ParagonIE_Sodium_Core32_Int32 $j13 * @var ParagonIE_Sodium_Core32_Int32 $j14 * @var ParagonIE_Sodium_Core32_Int32 $j15 */ if (self::strlen($k) < 32) { throw new RangeException('Key must be 32 bytes long'); } if ($c === null) { $x0 = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865)); $x5 = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e)); $x10 = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32)); $x15 = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574)); } else { $x0 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4)); $x5 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4)); $x10 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4)); $x15 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4)); } $x1 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4)); $x2 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4)); $x3 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4)); $x4 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4)); $x6 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4)); $x7 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4)); $x8 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4)); $x9 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4)); $x11 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4)); $x12 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4)); $x13 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4)); $x14 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4)); for ($i = self::ROUNDS; $i > 0; $i -= 2) { $x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7)); $x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9)); $x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13)); $x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18)); $x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7)); $x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9)); $x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13)); $x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18)); $x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7)); $x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9)); $x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13)); $x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18)); $x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7)); $x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9)); $x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13)); $x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18)); $x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7)); $x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9)); $x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13)); $x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18)); $x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7)); $x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9)); $x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13)); $x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18)); $x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7)); $x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9)); $x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13)); $x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18)); $x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7)); $x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9)); $x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13)); $x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18)); } return $x0->toReverseString() . $x5->toReverseString() . $x10->toReverseString() . $x15->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString(); } } <?php if (class_exists('ParagonIE_Sodium_Core32_Poly1305_State', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Poly1305_State */ class ParagonIE_Sodium_Core32_Poly1305_State extends ParagonIE_Sodium_Core32_Util { /** * @var array<int, int> */ protected $buffer = array(); /** * @var bool */ protected $final = false; /** * @var array<int, ParagonIE_Sodium_Core32_Int32> */ public $h; /** * @var int */ protected $leftover = 0; /** * @var array<int, ParagonIE_Sodium_Core32_Int32> */ public $r; /** * @var array<int, ParagonIE_Sodium_Core32_Int64> */ public $pad; /** * ParagonIE_Sodium_Core32_Poly1305_State constructor. * * @internal You should not use this directly from another application * * @param string $key * @throws InvalidArgumentException * @throws SodiumException * @throws TypeError */ public function __construct($key = '') { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Poly1305 requires a 32-byte key' ); } /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ $this->r = array( // st->r[0] = ... ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4)) ->setUnsignedInt(true) ->mask(0x3ffffff), // st->r[1] = ... ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 3, 4)) ->setUnsignedInt(true) ->shiftRight(2) ->mask(0x3ffff03), // st->r[2] = ... ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 6, 4)) ->setUnsignedInt(true) ->shiftRight(4) ->mask(0x3ffc0ff), // st->r[3] = ... ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 9, 4)) ->setUnsignedInt(true) ->shiftRight(6) ->mask(0x3f03fff), // st->r[4] = ... ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4)) ->setUnsignedInt(true) ->shiftRight(8) ->mask(0x00fffff) ); /* h = 0 */ $this->h = array( new ParagonIE_Sodium_Core32_Int32(array(0, 0), true), new ParagonIE_Sodium_Core32_Int32(array(0, 0), true), new ParagonIE_Sodium_Core32_Int32(array(0, 0), true), new ParagonIE_Sodium_Core32_Int32(array(0, 0), true), new ParagonIE_Sodium_Core32_Int32(array(0, 0), true) ); /* save pad for later */ $this->pad = array( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4)) ->setUnsignedInt(true)->toInt64(), ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4)) ->setUnsignedInt(true)->toInt64(), ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4)) ->setUnsignedInt(true)->toInt64(), ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4)) ->setUnsignedInt(true)->toInt64(), ); $this->leftover = 0; $this->final = false; } /** * @internal You should not use this directly from another application * * @param string $message * @return self * @throws SodiumException * @throws TypeError */ public function update($message = '') { $bytes = self::strlen($message); /* handle leftover */ if ($this->leftover) { /** @var int $want */ $want = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - $this->leftover; if ($want > $bytes) { $want = $bytes; } for ($i = 0; $i < $want; ++$i) { $mi = self::chrToInt($message[$i]); $this->buffer[$this->leftover + $i] = $mi; } // We snip off the leftmost bytes. $message = self::substr($message, $want); $bytes = self::strlen($message); $this->leftover += $want; if ($this->leftover < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) { // We still don't have enough to run $this->blocks() return $this; } $this->blocks( self::intArrayToString($this->buffer), ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE ); $this->leftover = 0; } /* process full blocks */ if ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) { /** @var int $want */ $want = $bytes & ~(ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE - 1); if ($want >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) { /** @var string $block */ $block = self::substr($message, 0, $want); if (self::strlen($block) >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) { $this->blocks($block, $want); $message = self::substr($message, $want); $bytes = self::strlen($message); } } } /* store leftover */ if ($bytes) { for ($i = 0; $i < $bytes; ++$i) { $mi = self::chrToInt($message[$i]); $this->buffer[$this->leftover + $i] = $mi; } $this->leftover = (int) $this->leftover + $bytes; } return $this; } /** * @internal You should not use this directly from another application * * @param string $message * @param int $bytes * @return self * @throws SodiumException * @throws TypeError */ public function blocks($message, $bytes) { if (self::strlen($message) < 16) { $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT); } $hibit = ParagonIE_Sodium_Core32_Int32::fromInt((int) ($this->final ? 0 : 1 << 24)); /* 1 << 128 */ $hibit->setUnsignedInt(true); $zero = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 0), true); /** * @var ParagonIE_Sodium_Core32_Int64 $d0 * @var ParagonIE_Sodium_Core32_Int64 $d1 * @var ParagonIE_Sodium_Core32_Int64 $d2 * @var ParagonIE_Sodium_Core32_Int64 $d3 * @var ParagonIE_Sodium_Core32_Int64 $d4 * @var ParagonIE_Sodium_Core32_Int64 $r0 * @var ParagonIE_Sodium_Core32_Int64 $r1 * @var ParagonIE_Sodium_Core32_Int64 $r2 * @var ParagonIE_Sodium_Core32_Int64 $r3 * @var ParagonIE_Sodium_Core32_Int64 $r4 * * @var ParagonIE_Sodium_Core32_Int32 $h0 * @var ParagonIE_Sodium_Core32_Int32 $h1 * @var ParagonIE_Sodium_Core32_Int32 $h2 * @var ParagonIE_Sodium_Core32_Int32 $h3 * @var ParagonIE_Sodium_Core32_Int32 $h4 */ $r0 = $this->r[0]->toInt64(); $r1 = $this->r[1]->toInt64(); $r2 = $this->r[2]->toInt64(); $r3 = $this->r[3]->toInt64(); $r4 = $this->r[4]->toInt64(); $s1 = $r1->toInt64()->mulInt(5, 3); $s2 = $r2->toInt64()->mulInt(5, 3); $s3 = $r3->toInt64()->mulInt(5, 3); $s4 = $r4->toInt64()->mulInt(5, 3); $h0 = $this->h[0]; $h1 = $this->h[1]; $h2 = $this->h[2]; $h3 = $this->h[3]; $h4 = $this->h[4]; while ($bytes >= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE) { /* h += m[i] */ $h0 = $h0->addInt32( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4)) ->mask(0x3ffffff) )->toInt64(); $h1 = $h1->addInt32( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 3, 4)) ->shiftRight(2) ->mask(0x3ffffff) )->toInt64(); $h2 = $h2->addInt32( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 6, 4)) ->shiftRight(4) ->mask(0x3ffffff) )->toInt64(); $h3 = $h3->addInt32( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 9, 4)) ->shiftRight(6) ->mask(0x3ffffff) )->toInt64(); $h4 = $h4->addInt32( ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4)) ->shiftRight(8) ->orInt32($hibit) )->toInt64(); /* h *= r */ $d0 = $zero ->addInt64($h0->mulInt64($r0, 27)) ->addInt64($s4->mulInt64($h1, 27)) ->addInt64($s3->mulInt64($h2, 27)) ->addInt64($s2->mulInt64($h3, 27)) ->addInt64($s1->mulInt64($h4, 27)); $d1 = $zero ->addInt64($h0->mulInt64($r1, 27)) ->addInt64($h1->mulInt64($r0, 27)) ->addInt64($s4->mulInt64($h2, 27)) ->addInt64($s3->mulInt64($h3, 27)) ->addInt64($s2->mulInt64($h4, 27)); $d2 = $zero ->addInt64($h0->mulInt64($r2, 27)) ->addInt64($h1->mulInt64($r1, 27)) ->addInt64($h2->mulInt64($r0, 27)) ->addInt64($s4->mulInt64($h3, 27)) ->addInt64($s3->mulInt64($h4, 27)); $d3 = $zero ->addInt64($h0->mulInt64($r3, 27)) ->addInt64($h1->mulInt64($r2, 27)) ->addInt64($h2->mulInt64($r1, 27)) ->addInt64($h3->mulInt64($r0, 27)) ->addInt64($s4->mulInt64($h4, 27)); $d4 = $zero ->addInt64($h0->mulInt64($r4, 27)) ->addInt64($h1->mulInt64($r3, 27)) ->addInt64($h2->mulInt64($r2, 27)) ->addInt64($h3->mulInt64($r1, 27)) ->addInt64($h4->mulInt64($r0, 27)); /* (partial) h %= p */ $c = $d0->shiftRight(26); $h0 = $d0->toInt32()->mask(0x3ffffff); $d1 = $d1->addInt64($c); $c = $d1->shiftRight(26); $h1 = $d1->toInt32()->mask(0x3ffffff); $d2 = $d2->addInt64($c); $c = $d2->shiftRight(26); $h2 = $d2->toInt32()->mask(0x3ffffff); $d3 = $d3->addInt64($c); $c = $d3->shiftRight(26); $h3 = $d3->toInt32()->mask(0x3ffffff); $d4 = $d4->addInt64($c); $c = $d4->shiftRight(26); $h4 = $d4->toInt32()->mask(0x3ffffff); $h0 = $h0->addInt32($c->toInt32()->mulInt(5, 3)); $c = $h0->shiftRight(26); $h0 = $h0->mask(0x3ffffff); $h1 = $h1->addInt32($c); // Chop off the left 32 bytes. $message = self::substr( $message, ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE ); $bytes -= ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h */ $this->h = array($h0, $h1, $h2, $h3, $h4); return $this; } /** * @internal You should not use this directly from another application * * @return string * @throws SodiumException * @throws TypeError */ public function finish() { /* process the remaining block */ if ($this->leftover) { $i = $this->leftover; $this->buffer[$i++] = 1; for (; $i < ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE; ++$i) { $this->buffer[$i] = 0; } $this->final = true; $this->blocks( self::substr( self::intArrayToString($this->buffer), 0, ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE ), $b = ParagonIE_Sodium_Core32_Poly1305::BLOCK_SIZE ); } /** * @var ParagonIE_Sodium_Core32_Int32 $f * @var ParagonIE_Sodium_Core32_Int32 $g0 * @var ParagonIE_Sodium_Core32_Int32 $g1 * @var ParagonIE_Sodium_Core32_Int32 $g2 * @var ParagonIE_Sodium_Core32_Int32 $g3 * @var ParagonIE_Sodium_Core32_Int32 $g4 * @var ParagonIE_Sodium_Core32_Int32 $h0 * @var ParagonIE_Sodium_Core32_Int32 $h1 * @var ParagonIE_Sodium_Core32_Int32 $h2 * @var ParagonIE_Sodium_Core32_Int32 $h3 * @var ParagonIE_Sodium_Core32_Int32 $h4 */ $h0 = $this->h[0]; $h1 = $this->h[1]; $h2 = $this->h[2]; $h3 = $this->h[3]; $h4 = $this->h[4]; $c = $h1->shiftRight(26); # $c = $h1 >> 26; $h1 = $h1->mask(0x3ffffff); # $h1 &= 0x3ffffff; $h2 = $h2->addInt32($c); # $h2 += $c; $c = $h2->shiftRight(26); # $c = $h2 >> 26; $h2 = $h2->mask(0x3ffffff); # $h2 &= 0x3ffffff; $h3 = $h3->addInt32($c); # $h3 += $c; $c = $h3->shiftRight(26); # $c = $h3 >> 26; $h3 = $h3->mask(0x3ffffff); # $h3 &= 0x3ffffff; $h4 = $h4->addInt32($c); # $h4 += $c; $c = $h4->shiftRight(26); # $c = $h4 >> 26; $h4 = $h4->mask(0x3ffffff); # $h4 &= 0x3ffffff; $h0 = $h0->addInt32($c->mulInt(5, 3)); # $h0 += self::mul($c, 5); $c = $h0->shiftRight(26); # $c = $h0 >> 26; $h0 = $h0->mask(0x3ffffff); # $h0 &= 0x3ffffff; $h1 = $h1->addInt32($c); # $h1 += $c; /* compute h + -p */ $g0 = $h0->addInt(5); $c = $g0->shiftRight(26); $g0 = $g0->mask(0x3ffffff); $g1 = $h1->addInt32($c); $c = $g1->shiftRight(26); $g1 = $g1->mask(0x3ffffff); $g2 = $h2->addInt32($c); $c = $g2->shiftRight(26); $g2 = $g2->mask(0x3ffffff); $g3 = $h3->addInt32($c); $c = $g3->shiftRight(26); $g3 = $g3->mask(0x3ffffff); $g4 = $h4->addInt32($c)->subInt(1 << 26); # $mask = ($g4 >> 31) - 1; /* select h if h < p, or h + -p if h >= p */ $mask = (int) (($g4->toInt() >> 31) + 1); $g0 = $g0->mask($mask); $g1 = $g1->mask($mask); $g2 = $g2->mask($mask); $g3 = $g3->mask($mask); $g4 = $g4->mask($mask); /** @var int $mask */ $mask = ~$mask; $h0 = $h0->mask($mask)->orInt32($g0); $h1 = $h1->mask($mask)->orInt32($g1); $h2 = $h2->mask($mask)->orInt32($g2); $h3 = $h3->mask($mask)->orInt32($g3); $h4 = $h4->mask($mask)->orInt32($g4); /* h = h % (2^128) */ $h0 = $h0->orInt32($h1->shiftLeft(26)); $h1 = $h1->shiftRight(6)->orInt32($h2->shiftLeft(20)); $h2 = $h2->shiftRight(12)->orInt32($h3->shiftLeft(14)); $h3 = $h3->shiftRight(18)->orInt32($h4->shiftLeft(8)); /* mac = (h + pad) % (2^128) */ $f = $h0->toInt64()->addInt64($this->pad[0]); $h0 = $f->toInt32(); $f = $h1->toInt64()->addInt64($this->pad[1])->addInt($h0->overflow); $h1 = $f->toInt32(); $f = $h2->toInt64()->addInt64($this->pad[2])->addInt($h1->overflow); $h2 = $f->toInt32(); $f = $h3->toInt64()->addInt64($this->pad[3])->addInt($h2->overflow); $h3 = $f->toInt32(); return $h0->toReverseString() . $h1->toReverseString() . $h2->toReverseString() . $h3->toReverseString(); } } <?php if (class_exists('ParagonIE_Sodium_Core32_ChaCha20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_ChaCha20 */ class ParagonIE_Sodium_Core32_ChaCha20 extends ParagonIE_Sodium_Core32_Util { /** * The ChaCha20 quarter round function. Works on four 32-bit integers. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Int32 $a * @param ParagonIE_Sodium_Core32_Int32 $b * @param ParagonIE_Sodium_Core32_Int32 $c * @param ParagonIE_Sodium_Core32_Int32 $d * @return array<int, ParagonIE_Sodium_Core32_Int32> * @throws SodiumException * @throws TypeError */ protected static function quarterRound( ParagonIE_Sodium_Core32_Int32 $a, ParagonIE_Sodium_Core32_Int32 $b, ParagonIE_Sodium_Core32_Int32 $c, ParagonIE_Sodium_Core32_Int32 $d ) { /** @var ParagonIE_Sodium_Core32_Int32 $a */ /** @var ParagonIE_Sodium_Core32_Int32 $b */ /** @var ParagonIE_Sodium_Core32_Int32 $c */ /** @var ParagonIE_Sodium_Core32_Int32 $d */ # a = PLUS(a,b); d = ROTATE(XOR(d,a),16); $a = $a->addInt32($b); $d = $d->xorInt32($a)->rotateLeft(16); # c = PLUS(c,d); b = ROTATE(XOR(b,c),12); $c = $c->addInt32($d); $b = $b->xorInt32($c)->rotateLeft(12); # a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); $a = $a->addInt32($b); $d = $d->xorInt32($a)->rotateLeft(8); # c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); $c = $c->addInt32($d); $b = $b->xorInt32($c)->rotateLeft(7); return array($a, $b, $c, $d); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx * @param string $message * * @return string * @throws SodiumException * @throws TypeError */ public static function encryptBytes( ParagonIE_Sodium_Core32_ChaCha20_Ctx $ctx, $message = '' ) { $bytes = self::strlen($message); /** @var ParagonIE_Sodium_Core32_Int32 $x0 */ /** @var ParagonIE_Sodium_Core32_Int32 $x1 */ /** @var ParagonIE_Sodium_Core32_Int32 $x2 */ /** @var ParagonIE_Sodium_Core32_Int32 $x3 */ /** @var ParagonIE_Sodium_Core32_Int32 $x4 */ /** @var ParagonIE_Sodium_Core32_Int32 $x5 */ /** @var ParagonIE_Sodium_Core32_Int32 $x6 */ /** @var ParagonIE_Sodium_Core32_Int32 $x7 */ /** @var ParagonIE_Sodium_Core32_Int32 $x8 */ /** @var ParagonIE_Sodium_Core32_Int32 $x9 */ /** @var ParagonIE_Sodium_Core32_Int32 $x10 */ /** @var ParagonIE_Sodium_Core32_Int32 $x11 */ /** @var ParagonIE_Sodium_Core32_Int32 $x12 */ /** @var ParagonIE_Sodium_Core32_Int32 $x13 */ /** @var ParagonIE_Sodium_Core32_Int32 $x14 */ /** @var ParagonIE_Sodium_Core32_Int32 $x15 */ /* j0 = ctx->input[0]; j1 = ctx->input[1]; j2 = ctx->input[2]; j3 = ctx->input[3]; j4 = ctx->input[4]; j5 = ctx->input[5]; j6 = ctx->input[6]; j7 = ctx->input[7]; j8 = ctx->input[8]; j9 = ctx->input[9]; j10 = ctx->input[10]; j11 = ctx->input[11]; j12 = ctx->input[12]; j13 = ctx->input[13]; j14 = ctx->input[14]; j15 = ctx->input[15]; */ /** @var ParagonIE_Sodium_Core32_Int32 $j0 */ $j0 = $ctx[0]; /** @var ParagonIE_Sodium_Core32_Int32 $j1 */ $j1 = $ctx[1]; /** @var ParagonIE_Sodium_Core32_Int32 $j2 */ $j2 = $ctx[2]; /** @var ParagonIE_Sodium_Core32_Int32 $j3 */ $j3 = $ctx[3]; /** @var ParagonIE_Sodium_Core32_Int32 $j4 */ $j4 = $ctx[4]; /** @var ParagonIE_Sodium_Core32_Int32 $j5 */ $j5 = $ctx[5]; /** @var ParagonIE_Sodium_Core32_Int32 $j6 */ $j6 = $ctx[6]; /** @var ParagonIE_Sodium_Core32_Int32 $j7 */ $j7 = $ctx[7]; /** @var ParagonIE_Sodium_Core32_Int32 $j8 */ $j8 = $ctx[8]; /** @var ParagonIE_Sodium_Core32_Int32 $j9 */ $j9 = $ctx[9]; /** @var ParagonIE_Sodium_Core32_Int32 $j10 */ $j10 = $ctx[10]; /** @var ParagonIE_Sodium_Core32_Int32 $j11 */ $j11 = $ctx[11]; /** @var ParagonIE_Sodium_Core32_Int32 $j12 */ $j12 = $ctx[12]; /** @var ParagonIE_Sodium_Core32_Int32 $j13 */ $j13 = $ctx[13]; /** @var ParagonIE_Sodium_Core32_Int32 $j14 */ $j14 = $ctx[14]; /** @var ParagonIE_Sodium_Core32_Int32 $j15 */ $j15 = $ctx[15]; $c = ''; for (;;) { if ($bytes < 64) { $message .= str_repeat("\x00", 64 - $bytes); } $x0 = clone $j0; $x1 = clone $j1; $x2 = clone $j2; $x3 = clone $j3; $x4 = clone $j4; $x5 = clone $j5; $x6 = clone $j6; $x7 = clone $j7; $x8 = clone $j8; $x9 = clone $j9; $x10 = clone $j10; $x11 = clone $j11; $x12 = clone $j12; $x13 = clone $j13; $x14 = clone $j14; $x15 = clone $j15; # for (i = 20; i > 0; i -= 2) { for ($i = 20; $i > 0; $i -= 2) { # QUARTERROUND( x0, x4, x8, x12) list($x0, $x4, $x8, $x12) = self::quarterRound($x0, $x4, $x8, $x12); # QUARTERROUND( x1, x5, x9, x13) list($x1, $x5, $x9, $x13) = self::quarterRound($x1, $x5, $x9, $x13); # QUARTERROUND( x2, x6, x10, x14) list($x2, $x6, $x10, $x14) = self::quarterRound($x2, $x6, $x10, $x14); # QUARTERROUND( x3, x7, x11, x15) list($x3, $x7, $x11, $x15) = self::quarterRound($x3, $x7, $x11, $x15); # QUARTERROUND( x0, x5, x10, x15) list($x0, $x5, $x10, $x15) = self::quarterRound($x0, $x5, $x10, $x15); # QUARTERROUND( x1, x6, x11, x12) list($x1, $x6, $x11, $x12) = self::quarterRound($x1, $x6, $x11, $x12); # QUARTERROUND( x2, x7, x8, x13) list($x2, $x7, $x8, $x13) = self::quarterRound($x2, $x7, $x8, $x13); # QUARTERROUND( x3, x4, x9, x14) list($x3, $x4, $x9, $x14) = self::quarterRound($x3, $x4, $x9, $x14); } /* x0 = PLUS(x0, j0); x1 = PLUS(x1, j1); x2 = PLUS(x2, j2); x3 = PLUS(x3, j3); x4 = PLUS(x4, j4); x5 = PLUS(x5, j5); x6 = PLUS(x6, j6); x7 = PLUS(x7, j7); x8 = PLUS(x8, j8); x9 = PLUS(x9, j9); x10 = PLUS(x10, j10); x11 = PLUS(x11, j11); x12 = PLUS(x12, j12); x13 = PLUS(x13, j13); x14 = PLUS(x14, j14); x15 = PLUS(x15, j15); */ $x0 = $x0->addInt32($j0); $x1 = $x1->addInt32($j1); $x2 = $x2->addInt32($j2); $x3 = $x3->addInt32($j3); $x4 = $x4->addInt32($j4); $x5 = $x5->addInt32($j5); $x6 = $x6->addInt32($j6); $x7 = $x7->addInt32($j7); $x8 = $x8->addInt32($j8); $x9 = $x9->addInt32($j9); $x10 = $x10->addInt32($j10); $x11 = $x11->addInt32($j11); $x12 = $x12->addInt32($j12); $x13 = $x13->addInt32($j13); $x14 = $x14->addInt32($j14); $x15 = $x15->addInt32($j15); /* x0 = XOR(x0, LOAD32_LE(m + 0)); x1 = XOR(x1, LOAD32_LE(m + 4)); x2 = XOR(x2, LOAD32_LE(m + 8)); x3 = XOR(x3, LOAD32_LE(m + 12)); x4 = XOR(x4, LOAD32_LE(m + 16)); x5 = XOR(x5, LOAD32_LE(m + 20)); x6 = XOR(x6, LOAD32_LE(m + 24)); x7 = XOR(x7, LOAD32_LE(m + 28)); x8 = XOR(x8, LOAD32_LE(m + 32)); x9 = XOR(x9, LOAD32_LE(m + 36)); x10 = XOR(x10, LOAD32_LE(m + 40)); x11 = XOR(x11, LOAD32_LE(m + 44)); x12 = XOR(x12, LOAD32_LE(m + 48)); x13 = XOR(x13, LOAD32_LE(m + 52)); x14 = XOR(x14, LOAD32_LE(m + 56)); x15 = XOR(x15, LOAD32_LE(m + 60)); */ $x0 = $x0->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 0, 4))); $x1 = $x1->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 4, 4))); $x2 = $x2->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 8, 4))); $x3 = $x3->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 12, 4))); $x4 = $x4->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 16, 4))); $x5 = $x5->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 20, 4))); $x6 = $x6->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 24, 4))); $x7 = $x7->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 28, 4))); $x8 = $x8->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 32, 4))); $x9 = $x9->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 36, 4))); $x10 = $x10->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 40, 4))); $x11 = $x11->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 44, 4))); $x12 = $x12->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 48, 4))); $x13 = $x13->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 52, 4))); $x14 = $x14->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 56, 4))); $x15 = $x15->xorInt32(ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($message, 60, 4))); /* j12 = PLUSONE(j12); if (!j12) { j13 = PLUSONE(j13); } */ /** @var ParagonIE_Sodium_Core32_Int32 $j12 */ $j12 = $j12->addInt(1); if ($j12->limbs[0] === 0 && $j12->limbs[1] === 0) { $j13 = $j13->addInt(1); } /* STORE32_LE(c + 0, x0); STORE32_LE(c + 4, x1); STORE32_LE(c + 8, x2); STORE32_LE(c + 12, x3); STORE32_LE(c + 16, x4); STORE32_LE(c + 20, x5); STORE32_LE(c + 24, x6); STORE32_LE(c + 28, x7); STORE32_LE(c + 32, x8); STORE32_LE(c + 36, x9); STORE32_LE(c + 40, x10); STORE32_LE(c + 44, x11); STORE32_LE(c + 48, x12); STORE32_LE(c + 52, x13); STORE32_LE(c + 56, x14); STORE32_LE(c + 60, x15); */ $block = $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x4->toReverseString() . $x5->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString() . $x10->toReverseString() . $x11->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString(); /* Partial block */ if ($bytes < 64) { $c .= self::substr($block, 0, $bytes); break; } /* Full block */ $c .= $block; $bytes -= 64; if ($bytes <= 0) { break; } $message = self::substr($message, 64); } /* end for(;;) loop */ $ctx[12] = $j12; $ctx[13] = $j13; return $c; } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function stream($len = 64, $nonce = '', $key = '') { return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStream($len, $nonce = '', $key = '') { return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce), str_repeat("\x00", $len) ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function ietfStreamXorIc($message, $nonce = '', $key = '', $ic = '') { return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_IetfCtx($key, $nonce, $ic), $message ); } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @param string $ic * @return string * @throws SodiumException * @throws TypeError */ public static function streamXorIc($message, $nonce = '', $key = '', $ic = '') { return self::encryptBytes( new ParagonIE_Sodium_Core32_ChaCha20_Ctx($key, $nonce, $ic), $message ); } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Fe', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Fe * * This represents a Field Element */ class ParagonIE_Sodium_Core32_Curve25519_Fe implements ArrayAccess { /** * @var array<int, ParagonIE_Sodium_Core32_Int32> */ protected $container = array(); /** * @var int */ protected $size = 10; /** * @internal You should not use this directly from another application * * @param array<int, ParagonIE_Sodium_Core32_Int32> $array * @param bool $save_indexes * @return self * @throws SodiumException * @throws TypeError */ public static function fromArray($array, $save_indexes = null) { $count = count($array); if ($save_indexes) { $keys = array_keys($array); } else { $keys = range(0, $count - 1); } $array = array_values($array); $obj = new ParagonIE_Sodium_Core32_Curve25519_Fe(); if ($save_indexes) { for ($i = 0; $i < $count; ++$i) { $array[$i]->overflow = 0; $obj->offsetSet($keys[$i], $array[$i]); } } else { for ($i = 0; $i < $count; ++$i) { if (!($array[$i] instanceof ParagonIE_Sodium_Core32_Int32)) { throw new TypeError('Expected ParagonIE_Sodium_Core32_Int32'); } $array[$i]->overflow = 0; $obj->offsetSet($i, $array[$i]); } } return $obj; } /** * @internal You should not use this directly from another application * * @param array<int, int> $array * @param bool $save_indexes * @return self * @throws SodiumException * @throws TypeError */ public static function fromIntArray($array, $save_indexes = null) { $count = count($array); if ($save_indexes) { $keys = array_keys($array); } else { $keys = range(0, $count - 1); } $array = array_values($array); $set = array(); /** @var int $i */ /** @var int $v */ foreach ($array as $i => $v) { $set[$i] = ParagonIE_Sodium_Core32_Int32::fromInt($v); } $obj = new ParagonIE_Sodium_Core32_Curve25519_Fe(); if ($save_indexes) { for ($i = 0; $i < $count; ++$i) { $set[$i]->overflow = 0; $obj->offsetSet($keys[$i], $set[$i]); } } else { for ($i = 0; $i < $count; ++$i) { $set[$i]->overflow = 0; $obj->offsetSet($i, $set[$i]); } } return $obj; } /** * @internal You should not use this directly from another application * * @param mixed $offset * @param mixed $value * @return void * @throws SodiumException * @throws TypeError */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!($value instanceof ParagonIE_Sodium_Core32_Int32)) { throw new InvalidArgumentException('Expected an instance of ParagonIE_Sodium_Core32_Int32'); } if (is_null($offset)) { $this->container[] = $value; } else { ParagonIE_Sodium_Core32_Util::declareScalarType($offset, 'int', 1); $this->container[(int) $offset] = $value; } } /** * @internal You should not use this directly from another application * * @param mixed $offset * @return bool * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param mixed $offset * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param mixed $offset * @return ParagonIE_Sodium_Core32_Int32 * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetGet($offset) { if (!isset($this->container[$offset])) { $this->container[(int) $offset] = new ParagonIE_Sodium_Core32_Int32(); } /** @var ParagonIE_Sodium_Core32_Int32 $get */ $get = $this->container[$offset]; return $get; } /** * @internal You should not use this directly from another application * * @return array */ public function __debugInfo() { if (empty($this->container)) { return array(); } $c = array( (int) ($this->container[0]->toInt()), (int) ($this->container[1]->toInt()), (int) ($this->container[2]->toInt()), (int) ($this->container[3]->toInt()), (int) ($this->container[4]->toInt()), (int) ($this->container[5]->toInt()), (int) ($this->container[6]->toInt()), (int) ($this->container[7]->toInt()), (int) ($this->container[8]->toInt()), (int) ($this->container[9]->toInt()) ); return array(implode(', ', $c)); } } # Curve25519 Data Structures These are PHP implementation of the [structs used in the ref10 curve25519 code](https://github.com/jedisct1/libsodium/blob/master/src/libsodium/include/sodium/private/curve25519_ref10.h). <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_H', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_H * * This just contains the constants in the ref10/base.h file */ class ParagonIE_Sodium_Core32_Curve25519_H extends ParagonIE_Sodium_Core32_Util { /** * See: libsodium's crypto_core/curve25519/ref10/base.h * * @var array<int, array<int, array<int, array<int, int>>>> Basically, int[32][8][3][10] */ protected static $base = array( array( array( array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605), array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378), array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546), ), array( array(-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303), array(-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081), array(26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697), ), array( array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024), array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574), array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357), ), array( array(-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540), array(23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397), array(7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325), ), array( array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380), array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306), array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942), ), array( array(-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777), array(-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737), array(-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652), ), array( array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766), array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701), array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300), ), array( array(14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726), array(-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955), array(27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425), ), ), array( array( array(-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171), array(27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510), array(17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660), ), array( array(-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639), array(29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963), array(5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950), ), array( array(-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568), array(12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335), array(25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628), ), array( array(-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007), array(-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772), array(-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653), ), array( array(2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567), array(13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686), array(21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372), ), array( array(-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887), array(-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954), array(-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953), ), array( array(24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833), array(-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532), array(-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876), ), array( array(2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268), array(33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214), array(1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038), ), ), array( array( array(6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800), array(4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645), array(-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664), ), array( array(1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933), array(-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182), array(-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222), ), array( array(-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991), array(20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880), array(9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092), ), array( array(-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295), array(19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788), array(8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553), ), array( array(-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026), array(11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347), array(-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033), ), array( array(-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395), array(-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278), array(1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890), ), array( array(32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995), array(-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596), array(-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891), ), array( array(31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060), array(11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608), array(-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606), ), ), array( array( array(7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389), array(-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016), array(-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341), ), array( array(-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505), array(14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553), array(-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655), ), array( array(15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220), array(12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631), array(-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099), ), array( array(26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556), array(14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749), array(236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930), ), array( array(1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391), array(5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253), array(20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066), ), array( array(24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958), array(-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082), array(-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383), ), array( array(-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521), array(-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807), array(23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948), ), array( array(9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134), array(-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455), array(27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629), ), ), array( array( array(-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069), array(-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746), array(24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919), ), array( array(11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837), array(8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906), array(-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771), ), array( array(-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817), array(10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098), array(10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409), ), array( array(-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504), array(-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727), array(28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420), ), array( array(-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003), array(-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605), array(-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384), ), array( array(-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701), array(-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683), array(29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708), ), array( array(-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563), array(-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260), array(-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387), ), array( array(-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672), array(23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686), array(-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665), ), ), array( array( array(11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182), array(-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277), array(14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628), ), array( array(-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474), array(-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539), array(-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822), ), array( array(-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970), array(19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756), array(-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508), ), array( array(-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683), array(-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655), array(-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158), ), array( array(-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125), array(-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839), array(-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664), ), array( array(27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294), array(-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899), array(-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070), ), array( array(3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294), array(-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949), array(-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083), ), array( array(31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420), array(-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940), array(29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396), ), ), array( array( array(-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567), array(20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127), array(-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294), ), array( array(-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887), array(22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964), array(16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195), ), array( array(9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244), array(24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999), array(-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762), ), array( array(-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274), array(-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236), array(-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605), ), array( array(-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761), array(-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884), array(-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482), ), array( array(-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638), array(-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490), array(-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170), ), array( array(5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736), array(10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124), array(-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392), ), array( array(8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029), array(6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048), array(28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958), ), ), array( array( array(24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593), array(26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071), array(-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692), ), array( array(11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687), array(-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441), array(-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001), ), array( array(-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460), array(-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007), array(-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762), ), array( array(15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005), array(-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674), array(4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035), ), array( array(7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590), array(-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957), array(-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812), ), array( array(33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740), array(-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122), array(-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158), ), array( array(8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885), array(26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140), array(19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857), ), array( array(801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155), array(19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260), array(19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483), ), ), array( array( array(-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677), array(32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815), array(22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751), ), array( array(-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203), array(-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208), array(1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230), ), array( array(16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850), array(-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389), array(-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968), ), array( array(-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689), array(14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880), array(5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304), ), array( array(30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632), array(-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412), array(20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566), ), array( array(-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038), array(-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232), array(-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943), ), array( array(17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856), array(23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738), array(15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971), ), array( array(-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718), array(-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697), array(-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883), ), ), array( array( array(5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912), array(-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358), array(3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849), ), array( array(29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307), array(-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977), array(-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335), ), array( array(-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644), array(-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616), array(-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735), ), array( array(-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099), array(29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341), array(-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336), ), array( array(-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646), array(31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425), array(-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388), ), array( array(-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743), array(-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822), array(-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462), ), array( array(18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985), array(9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702), array(-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797), ), array( array(21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293), array(27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100), array(19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688), ), ), array( array( array(12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186), array(2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610), array(-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707), ), array( array(7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220), array(915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025), array(32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044), ), array( array(32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992), array(-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027), array(21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197), ), array( array(8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901), array(31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952), array(19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878), ), array( array(-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390), array(32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730), array(2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730), ), array( array(-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180), array(-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272), array(-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715), ), array( array(-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970), array(-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772), array(-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865), ), array( array(15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750), array(20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373), array(32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348), ), ), array( array( array(9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144), array(-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195), array(5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086), ), array( array(-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684), array(-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518), array(-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233), ), array( array(-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793), array(-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794), array(580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435), ), array( array(23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921), array(13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518), array(2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563), ), array( array(14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278), array(-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024), array(4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030), ), array( array(10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783), array(27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717), array(6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844), ), array( array(14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333), array(16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048), array(22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760), ), array( array(-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760), array(-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757), array(-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112), ), ), array( array( array(-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468), array(3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184), array(10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289), ), array( array(15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066), array(24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882), array(13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226), ), array( array(16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101), array(29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279), array(-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811), ), array( array(27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709), array(20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714), array(-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121), ), array( array(9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464), array(12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847), array(13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400), ), array( array(4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414), array(-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158), array(17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045), ), array( array(-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415), array(-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459), array(-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079), ), array( array(21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412), array(-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743), array(-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836), ), ), array( array( array(12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022), array(18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429), array(-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065), ), array( array(30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861), array(10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000), array(-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101), ), array( array(32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815), array(29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642), array(10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966), ), array( array(25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574), array(-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742), array(-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689), ), array( array(12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020), array(-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772), array(3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982), ), array( array(-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953), array(-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218), array(-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265), ), array( array(29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073), array(-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325), array(-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798), ), array( array(-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870), array(-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863), array(-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927), ), ), array( array( array(-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267), array(-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663), array(22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862), ), array( array(-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673), array(15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943), array(15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020), ), array( array(-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238), array(11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064), array(14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795), ), array( array(15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052), array(-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904), array(29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531), ), array( array(-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979), array(-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841), array(10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431), ), array( array(10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324), array(-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940), array(10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320), ), array( array(-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184), array(14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114), array(30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878), ), array( array(12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784), array(-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091), array(-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585), ), ), array( array( array(-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208), array(10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864), array(17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661), ), array( array(7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233), array(26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212), array(-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525), ), array( array(-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068), array(9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397), array(-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988), ), array( array(5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889), array(32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038), array(14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697), ), array( array(20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875), array(-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905), array(-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656), ), array( array(11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818), array(27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714), array(10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203), ), array( array(20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931), array(-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024), array(-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084), ), array( array(-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204), array(20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817), array(27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667), ), ), array( array( array(11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504), array(-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768), array(-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255), ), array( array(6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790), array(1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438), array(-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333), ), array( array(17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971), array(31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905), array(29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409), ), array( array(12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409), array(6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499), array(-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363), ), array( array(28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664), array(-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324), array(-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940), ), array( array(13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990), array(-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914), array(-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290), ), array( array(24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257), array(-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433), array(-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236), ), array( array(-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045), array(11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093), array(-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347), ), ), array( array( array(-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191), array(-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507), array(-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906), ), array( array(3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018), array(-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109), array(-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926), ), array( array(-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528), array(8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625), array(-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286), ), array( array(2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033), array(27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866), array(21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896), ), array( array(30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075), array(26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347), array(-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437), ), array( array(-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165), array(-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588), array(-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193), ), array( array(-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017), array(-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883), array(21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961), ), array( array(8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043), array(29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663), array(-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362), ), ), array( array( array(-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860), array(2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466), array(-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063), ), array( array(-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997), array(-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295), array(-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369), ), array( array(9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385), array(18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109), array(2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906), ), array( array(4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424), array(-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185), array(7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962), ), array( array(-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325), array(10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593), array(696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404), ), array( array(-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644), array(17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801), array(26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804), ), array( array(-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884), array(-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577), array(-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849), ), array( array(32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473), array(-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644), array(-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319), ), ), array( array( array(-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599), array(-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768), array(-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084), ), array( array(-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328), array(-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369), array(20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920), ), array( array(12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815), array(-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025), array(-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397), ), array( array(-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448), array(6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981), array(30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165), ), array( array(32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501), array(17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073), array(-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861), ), array( array(14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845), array(-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211), array(18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870), ), array( array(10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096), array(33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803), array(-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168), ), array( array(30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965), array(-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505), array(18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598), ), ), array( array( array(5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782), array(5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900), array(-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479), ), array( array(-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208), array(8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232), array(17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719), ), array( array(16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271), array(-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326), array(-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132), ), array( array(14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300), array(8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570), array(15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670), ), array( array(-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994), array(-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913), array(31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317), ), array( array(-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730), array(842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096), array(-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078), ), array( array(-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411), array(-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905), array(-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654), ), array( array(-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870), array(-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498), array(12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579), ), ), array( array( array(14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677), array(10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647), array(-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743), ), array( array(-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468), array(21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375), array(-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155), ), array( array(6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725), array(-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612), array(-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943), ), array( array(-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944), array(30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928), array(9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406), ), array( array(22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139), array(-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963), array(-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693), ), array( array(1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734), array(-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680), array(-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410), ), array( array(-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931), array(-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654), array(22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710), ), array( array(29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180), array(-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684), array(-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895), ), ), array( array( array(22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501), array(-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413), array(6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880), ), array( array(-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874), array(22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962), array(-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899), ), array( array(21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152), array(9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063), array(7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080), ), array( array(-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146), array(-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183), array(-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133), ), array( array(-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421), array(-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622), array(-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197), ), array( array(2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663), array(31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753), array(4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755), ), array( array(-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862), array(-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118), array(26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171), ), array( array(15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380), array(16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824), array(28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270), ), ), array( array( array(-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438), array(-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584), array(-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562), ), array( array(30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471), array(18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610), array(19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269), ), array( array(-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650), array(14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369), array(19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461), ), array( array(30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462), array(-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793), array(-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218), ), array( array(-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226), array(18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019), array(-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037), ), array( array(31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171), array(-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132), array(-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841), ), array( array(21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181), array(-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210), array(-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040), ), array( array(3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935), array(24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105), array(-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814), ), ), array( array( array(793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852), array(5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581), array(-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646), ), array( array(10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844), array(10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025), array(27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453), ), array( array(-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068), array(4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192), array(-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921), ), array( array(-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259), array(-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426), array(-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072), ), array( array(-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305), array(13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832), array(28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943), ), array( array(-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011), array(24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447), array(17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494), ), array( array(-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245), array(-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859), array(28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915), ), array( array(16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707), array(10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848), array(-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224), ), ), array( array( array(-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391), array(15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215), array(-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101), ), array( array(23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713), array(21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849), array(-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930), ), array( array(-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940), array(-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031), array(-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404), ), array( array(-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243), array(-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116), array(-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525), ), array( array(-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509), array(-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883), array(15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865), ), array( array(-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660), array(4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273), array(-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138), ), array( array(-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560), array(-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135), array(2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941), ), array( array(-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739), array(18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756), array(-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819), ), ), array( array( array(-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347), array(-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028), array(21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075), ), array( array(16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799), array(-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609), array(-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817), ), array( array(-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989), array(-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523), array(4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278), ), array( array(31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045), array(19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377), array(24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480), ), array( array(17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016), array(510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426), array(18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525), ), array( array(13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396), array(9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080), array(12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892), ), array( array(15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275), array(11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074), array(20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140), ), array( array(-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717), array(-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101), array(24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127), ), ), array( array( array(-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632), array(-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415), array(-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160), ), array( array(31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876), array(22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625), array(-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478), ), array( array(27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164), array(26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595), array(-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248), ), array( array(-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858), array(15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193), array(8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184), ), array( array(-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942), array(-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635), array(21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948), ), array( array(11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935), array(-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415), array(-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416), ), array( array(-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018), array(4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778), array(366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659), ), array( array(-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385), array(18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503), array(476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329), ), ), array( array( array(20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056), array(-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838), array(24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948), ), array( array(-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691), array(-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118), array(-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517), ), array( array(-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269), array(-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904), array(-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589), ), array( array(-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193), array(-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910), array(-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930), ), array( array(-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667), array(25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481), array(-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876), ), array( array(22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640), array(-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278), array(-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112), ), array( array(26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272), array(17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012), array(-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221), ), array( array(30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046), array(13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345), array(-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310), ), ), array( array( array(19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937), array(31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636), array(-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008), ), array( array(-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429), array(-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576), array(31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066), ), array( array(-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490), array(-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104), array(33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053), ), array( array(31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275), array(-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511), array(22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095), ), array( array(-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439), array(23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939), array(-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424), ), array( array(2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310), array(3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608), array(-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079), ), array( array(-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101), array(21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418), array(18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576), ), array( array(30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356), array(9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996), array(-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099), ), ), array( array( array(-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728), array(-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658), array(-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242), ), array( array(-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001), array(-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766), array(18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373), ), array( array(26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458), array(-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628), array(-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657), ), array( array(-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062), array(25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616), array(31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014), ), array( array(24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383), array(-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814), array(-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718), ), array( array(30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417), array(2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222), array(33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444), ), array( array(-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597), array(23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970), array(1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799), ), array( array(-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647), array(13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511), array(-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032), ), ), array( array( array(9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834), array(-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461), array(29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062), ), array( array(-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516), array(-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547), array(-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240), ), array( array(-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038), array(-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741), array(16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103), ), array( array(-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747), array(-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323), array(31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016), ), array( array(-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373), array(15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228), array(-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141), ), array( array(16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399), array(11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831), array(-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376), ), array( array(-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313), array(-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958), array(-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577), ), array( array(-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743), array(29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684), array(-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476), ), ) ); /** * See: libsodium's crypto_core/curve25519/ref10/base2.h * * @var array<int, array<int, array<int, int>>> basically int[8][3] */ protected static $base2 = array( array( array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605), array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378), array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546), ), array( array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024), array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574), array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357), ), array( array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380), array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306), array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942), ), array( array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766), array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701), array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300), ), array( array(-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877), array(-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951), array(4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784), ), array( array(-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436), array(25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918), array(23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877), ), array( array(-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800), array(-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305), array(-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300), ), array( array(-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876), array(-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619), array(-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683), ) ); /** * 37095705934669439343138083508754565189542113879843219016388785533085940283555 * * @var array<int, int> */ protected static $d = array( -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 ); /** * 2 * d = 16295367250680780974490674513165176452449235426866156013048779062215315747161 * * @var array<int, int> */ protected static $d2 = array( -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 ); /** * sqrt(-1) * * @var array<int, int> */ protected static $sqrtm1 = array( -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 ); } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Cached', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached */ class ParagonIE_Sodium_Core32_Curve25519_Ge_Cached { /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $YplusX; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $YminusX; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $T2d; /** * ParagonIE_Sodium_Core32_Curve25519_Ge_Cached constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YplusX * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $YminusX * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $Z * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $T2d */ public function __construct( ParagonIE_Sodium_Core32_Curve25519_Fe $YplusX = null, ParagonIE_Sodium_Core32_Curve25519_Fe $YminusX = null, ParagonIE_Sodium_Core32_Curve25519_Fe $Z = null, ParagonIE_Sodium_Core32_Curve25519_Fe $T2d = null ) { if ($YplusX === null) { $YplusX = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->YplusX = $YplusX; if ($YminusX === null) { $YminusX = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->YminusX = $YminusX; if ($Z === null) { $Z = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->Z = $Z; if ($T2d === null) { $T2d = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->T2d = $T2d; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P3', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Ge_P3 */ class ParagonIE_Sodium_Core32_Curve25519_Ge_P3 { /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $T; /** * ParagonIE_Sodium_Core32_Curve25519_Ge_P3 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t */ public function __construct( ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, ParagonIE_Sodium_Core32_Curve25519_Fe $z = null, ParagonIE_Sodium_Core32_Curve25519_Fe $t = null ) { if ($x === null) { $x = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->X = $x; if ($y === null) { $y = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->Y = $y; if ($z === null) { $z = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->Z = $z; if ($t === null) { $t = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->T = $t; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 */ class ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 { /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Z; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $T; /** * ParagonIE_Sodium_Core32_Curve25519_Ge_P1p1 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $t * * @throws SodiumException * @throws TypeError */ public function __construct( ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, ParagonIE_Sodium_Core32_Curve25519_Fe $z = null, ParagonIE_Sodium_Core32_Curve25519_Fe $t = null ) { if ($x === null) { $x = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->X = $x; if ($y === null) { $y = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->Y = $y; if ($z === null) { $z = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->Z = $z; if ($t === null) { $t = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->T = $t; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp */ class ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp { /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $yplusx; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $yminusx; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $xy2d; /** * ParagonIE_Sodium_Core32_Curve25519_Ge_Precomp constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx * @param ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx * @param ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d * @throws SodiumException * @throws TypeError */ public function __construct( ParagonIE_Sodium_Core32_Curve25519_Fe $yplusx = null, ParagonIE_Sodium_Core32_Curve25519_Fe $yminusx = null, ParagonIE_Sodium_Core32_Curve25519_Fe $xy2d = null ) { if ($yplusx === null) { $yplusx = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->yplusx = $yplusx; if ($yminusx === null) { $yminusx = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->yminusx = $yminusx; if ($xy2d === null) { $xy2d = ParagonIE_Sodium_Core32_Curve25519::fe_0(); } $this->xy2d = $xy2d; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Curve25519_Ge_P2', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Curve25519_Ge_P2 */ class ParagonIE_Sodium_Core32_Curve25519_Ge_P2 { /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $X; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Y; /** * @var ParagonIE_Sodium_Core32_Curve25519_Fe */ public $Z; /** * ParagonIE_Sodium_Core32_Curve25519_Ge_P2 constructor. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $x * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $y * @param ParagonIE_Sodium_Core32_Curve25519_Fe|null $z */ public function __construct( ParagonIE_Sodium_Core32_Curve25519_Fe $x = null, ParagonIE_Sodium_Core32_Curve25519_Fe $y = null, ParagonIE_Sodium_Core32_Curve25519_Fe $z = null ) { if ($x === null) { $x = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->X = $x; if ($y === null) { $y = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->Y = $y; if ($z === null) { $z = new ParagonIE_Sodium_Core32_Curve25519_Fe(); } $this->Z = $z; } } <?php if (class_exists('ParagonIE_Sodium_Core32_Poly1305', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Poly1305 */ abstract class ParagonIE_Sodium_Core32_Poly1305 extends ParagonIE_Sodium_Core32_Util { const BLOCK_SIZE = 16; /** * @internal You should not use this directly from another application * * @param string $m * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function onetimeauth($m, $key) { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Key must be 32 bytes long.' ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( self::substr($key, 0, 32) ); return $state ->update($m) ->finish(); } /** * @internal You should not use this directly from another application * * @param string $mac * @param string $m * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function onetimeauth_verify($mac, $m, $key) { if (self::strlen($key) < 32) { throw new InvalidArgumentException( 'Key must be 32 bytes long.' ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( self::substr($key, 0, 32) ); $calc = $state ->update($m) ->finish(); return self::verify_16($calc, $mac); } } <?php if (class_exists('ParagonIE_Sodium_Core_ChaCha20_IetfCtx', false)) { return; } /** * Class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx */ class ParagonIE_Sodium_Core32_ChaCha20_IetfCtx extends ParagonIE_Sodium_Core32_ChaCha20_Ctx { /** * ParagonIE_Sodium_Core_ChaCha20_IetfCtx constructor. * * @internal You should not use this directly from another application * * @param string $key ChaCha20 key. * @param string $iv Initialization Vector (a.k.a. nonce). * @param string $counter The initial counter value. * Defaults to 4 0x00 bytes. * @throws InvalidArgumentException * @throws SodiumException * @throws TypeError */ public function __construct($key = '', $iv = '', $counter = '') { if (self::strlen($iv) !== 12) { throw new InvalidArgumentException('ChaCha20 expects a 96-bit nonce in IETF mode.'); } parent::__construct($key, self::substr($iv, 0, 8), $counter); if (!empty($counter)) { $this->container[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4)); } $this->container[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4)); $this->container[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4)); $this->container[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 8, 4)); } } <?php if (class_exists('ParagonIE_Sodium_Core_ChaCha20_Ctx', false)) { return; } /** * Class ParagonIE_Sodium_Core32_ChaCha20_Ctx */ class ParagonIE_Sodium_Core32_ChaCha20_Ctx extends ParagonIE_Sodium_Core32_Util implements ArrayAccess { /** * @var SplFixedArray internally, <int, ParagonIE_Sodium_Core32_Int32> */ protected $container; /** * ParagonIE_Sodium_Core_ChaCha20_Ctx constructor. * * @internal You should not use this directly from another application * * @param string $key ChaCha20 key. * @param string $iv Initialization Vector (a.k.a. nonce). * @param string $counter The initial counter value. * Defaults to 8 0x00 bytes. * @throws InvalidArgumentException * @throws SodiumException * @throws TypeError */ public function __construct($key = '', $iv = '', $counter = '') { if (self::strlen($key) !== 32) { throw new InvalidArgumentException('ChaCha20 expects a 256-bit key.'); } if (self::strlen($iv) !== 8) { throw new InvalidArgumentException('ChaCha20 expects a 64-bit nonce.'); } $this->container = new SplFixedArray(16); /* "expand 32-byte k" as per ChaCha20 spec */ $this->container[0] = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865)); $this->container[1] = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e)); $this->container[2] = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32)); $this->container[3] = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574)); $this->container[4] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 0, 4)); $this->container[5] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 4, 4)); $this->container[6] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 8, 4)); $this->container[7] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 12, 4)); $this->container[8] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 16, 4)); $this->container[9] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 20, 4)); $this->container[10] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 24, 4)); $this->container[11] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($key, 28, 4)); if (empty($counter)) { $this->container[12] = new ParagonIE_Sodium_Core32_Int32(); $this->container[13] = new ParagonIE_Sodium_Core32_Int32(); } else { $this->container[12] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 0, 4)); $this->container[13] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($counter, 4, 4)); } $this->container[14] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 0, 4)); $this->container[15] = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($iv, 4, 4)); } /** * @internal You should not use this directly from another application * * @param int $offset * @param int|ParagonIE_Sodium_Core32_Int32 $value * @return void */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!is_int($offset)) { throw new InvalidArgumentException('Expected an integer'); } if ($value instanceof ParagonIE_Sodium_Core32_Int32) { /* } elseif (is_int($value)) { $value = ParagonIE_Sodium_Core32_Int32::fromInt($value); */ } else { throw new InvalidArgumentException('Expected an integer'); } $this->container[$offset] = $value; } /** * @internal You should not use this directly from another application * * @param int $offset * @return bool * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return void * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->container[$offset]); } /** * @internal You should not use this directly from another application * * @param int $offset * @return mixed|null * @psalm-suppress MixedArrayOffset */ #[ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->container[$offset]) ? $this->container[$offset] : null; } } <?php if (class_exists('ParagonIE_Sodium_Core_BLAKE2b', false)) { return; } /** * Class ParagonIE_Sodium_Core_BLAKE2b * * Based on the work of Devi Mandiri in devi/salt. */ abstract class ParagonIE_Sodium_Core32_BLAKE2b extends ParagonIE_Sodium_Core_Util { /** * @var SplFixedArray */ public static $iv; /** * @var array<int, array<int, int>> */ public static $sigma = array( array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), array( 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), array( 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), array( 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), array( 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), array( 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), array( 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), array( 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), array( 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0), array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), array( 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3) ); const BLOCKBYTES = 128; const OUTBYTES = 64; const KEYBYTES = 64; /** * Turn two 32-bit integers into a fixed array representing a 64-bit integer. * * @internal You should not use this directly from another application * * @param int $high * @param int $low * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public static function new64($high, $low) { return ParagonIE_Sodium_Core32_Int64::fromInts($low, $high); } /** * Convert an arbitrary number into an SplFixedArray of two 32-bit integers * that represents a 64-bit integer. * * @internal You should not use this directly from another application * * @param int $num * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ protected static function to64($num) { list($hi, $lo) = self::numericTo64BitInteger($num); return self::new64($hi, $lo); } /** * Adds two 64-bit integers together, returning their sum as a SplFixedArray * containing two 32-bit integers (representing a 64-bit integer). * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Int64 $x * @param ParagonIE_Sodium_Core32_Int64 $y * @return ParagonIE_Sodium_Core32_Int64 */ protected static function add64($x, $y) { return $x->addInt64($y); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Int64 $x * @param ParagonIE_Sodium_Core32_Int64 $y * @param ParagonIE_Sodium_Core32_Int64 $z * @return ParagonIE_Sodium_Core32_Int64 */ public static function add364($x, $y, $z) { return $x->addInt64($y)->addInt64($z); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Int64 $x * @param ParagonIE_Sodium_Core32_Int64 $y * @return ParagonIE_Sodium_Core32_Int64 * @throws TypeError */ public static function xor64(ParagonIE_Sodium_Core32_Int64 $x, ParagonIE_Sodium_Core32_Int64 $y) { return $x->xorInt64($y); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Int64 $x * @param int $c * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public static function rotr64(ParagonIE_Sodium_Core32_Int64 $x, $c) { return $x->rotateRight($c); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param int $i * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public static function load64($x, $i) { /** @var int $l */ $l = (int) ($x[$i]) | ((int) ($x[$i+1]) << 8) | ((int) ($x[$i+2]) << 16) | ((int) ($x[$i+3]) << 24); /** @var int $h */ $h = (int) ($x[$i+4]) | ((int) ($x[$i+5]) << 8) | ((int) ($x[$i+6]) << 16) | ((int) ($x[$i+7]) << 24); return self::new64($h, $l); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $x * @param int $i * @param ParagonIE_Sodium_Core32_Int64 $u * @return void * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset */ public static function store64(SplFixedArray $x, $i, ParagonIE_Sodium_Core32_Int64 $u) { $v = clone $u; $maxLength = $x->getSize() - 1; for ($j = 0; $j < 8; ++$j) { $k = 3 - ($j >> 1); $x[$i] = $v->limbs[$k] & 0xff; if (++$i > $maxLength) { return; } $v->limbs[$k] >>= 8; } } /** * This just sets the $iv static variable. * * @internal You should not use this directly from another application * * @return void * @throws SodiumException * @throws TypeError */ public static function pseudoConstructor() { static $called = false; if ($called) { return; } self::$iv = new SplFixedArray(8); self::$iv[0] = self::new64(0x6a09e667, 0xf3bcc908); self::$iv[1] = self::new64(0xbb67ae85, 0x84caa73b); self::$iv[2] = self::new64(0x3c6ef372, 0xfe94f82b); self::$iv[3] = self::new64(0xa54ff53a, 0x5f1d36f1); self::$iv[4] = self::new64(0x510e527f, 0xade682d1); self::$iv[5] = self::new64(0x9b05688c, 0x2b3e6c1f); self::$iv[6] = self::new64(0x1f83d9ab, 0xfb41bd6b); self::$iv[7] = self::new64(0x5be0cd19, 0x137e2179); $called = true; } /** * Returns a fresh BLAKE2 context. * * @internal You should not use this directly from another application * * @return SplFixedArray * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @throws SodiumException * @throws TypeError */ protected static function context() { $ctx = new SplFixedArray(6); $ctx[0] = new SplFixedArray(8); // h $ctx[1] = new SplFixedArray(2); // t $ctx[2] = new SplFixedArray(2); // f $ctx[3] = new SplFixedArray(256); // buf $ctx[4] = 0; // buflen $ctx[5] = 0; // last_node (uint8_t) for ($i = 8; $i--;) { $ctx[0][$i] = self::$iv[$i]; } for ($i = 256; $i--;) { $ctx[3][$i] = 0; } $zero = self::new64(0, 0); $ctx[1][0] = $zero; $ctx[1][1] = $zero; $ctx[2][0] = $zero; $ctx[2][1] = $zero; return $ctx; } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $buf * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedAssignment */ protected static function compress(SplFixedArray $ctx, SplFixedArray $buf) { $m = new SplFixedArray(16); $v = new SplFixedArray(16); for ($i = 16; $i--;) { $m[$i] = self::load64($buf, $i << 3); } for ($i = 8; $i--;) { $v[$i] = $ctx[0][$i]; } $v[ 8] = self::$iv[0]; $v[ 9] = self::$iv[1]; $v[10] = self::$iv[2]; $v[11] = self::$iv[3]; $v[12] = self::xor64($ctx[1][0], self::$iv[4]); $v[13] = self::xor64($ctx[1][1], self::$iv[5]); $v[14] = self::xor64($ctx[2][0], self::$iv[6]); $v[15] = self::xor64($ctx[2][1], self::$iv[7]); for ($r = 0; $r < 12; ++$r) { $v = self::G($r, 0, 0, 4, 8, 12, $v, $m); $v = self::G($r, 1, 1, 5, 9, 13, $v, $m); $v = self::G($r, 2, 2, 6, 10, 14, $v, $m); $v = self::G($r, 3, 3, 7, 11, 15, $v, $m); $v = self::G($r, 4, 0, 5, 10, 15, $v, $m); $v = self::G($r, 5, 1, 6, 11, 12, $v, $m); $v = self::G($r, 6, 2, 7, 8, 13, $v, $m); $v = self::G($r, 7, 3, 4, 9, 14, $v, $m); } for ($i = 8; $i--;) { $ctx[0][$i] = self::xor64( $ctx[0][$i], self::xor64($v[$i], $v[$i+8]) ); } } /** * @internal You should not use this directly from another application * * @param int $r * @param int $i * @param int $a * @param int $b * @param int $c * @param int $d * @param SplFixedArray $v * @param SplFixedArray $m * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayOffset */ public static function G($r, $i, $a, $b, $c, $d, SplFixedArray $v, SplFixedArray $m) { $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][$i << 1]]); $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 32); $v[$c] = self::add64($v[$c], $v[$d]); $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 24); $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][($i << 1) + 1]]); $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 16); $v[$c] = self::add64($v[$c], $v[$d]); $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 63); return $v; } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param int $inc * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment */ public static function increment_counter($ctx, $inc) { if ($inc < 0) { throw new SodiumException('Increasing by a negative number makes no sense.'); } $t = self::to64($inc); # S->t is $ctx[1] in our implementation # S->t[0] = ( uint64_t )( t >> 0 ); $ctx[1][0] = self::add64($ctx[1][0], $t); # S->t[1] += ( S->t[0] < inc ); if (!($ctx[1][0] instanceof ParagonIE_Sodium_Core32_Int64)) { throw new TypeError('Not an int64'); } /** @var ParagonIE_Sodium_Core32_Int64 $c*/ $c = $ctx[1][0]; if ($c->isLessThanInt($inc)) { $ctx[1][1] = self::add64($ctx[1][1], self::to64(1)); } } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $p * @param int $plen * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedMethodCall * @psalm-suppress MixedOperand */ public static function update(SplFixedArray $ctx, SplFixedArray $p, $plen) { self::pseudoConstructor(); $offset = 0; while ($plen > 0) { $left = $ctx[4]; $fill = 256 - $left; if ($plen > $fill) { # memcpy( S->buf + left, in, fill ); /* Fill buffer */ for ($i = $fill; $i--;) { $ctx[3][$i + $left] = $p[$i + $offset]; } # S->buflen += fill; $ctx[4] += $fill; # blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); self::increment_counter($ctx, 128); # blake2b_compress( S, S->buf ); /* Compress */ self::compress($ctx, $ctx[3]); # memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ for ($i = 128; $i--;) { $ctx[3][$i] = $ctx[3][$i + 128]; } # S->buflen -= BLAKE2B_BLOCKBYTES; $ctx[4] -= 128; # in += fill; $offset += $fill; # inlen -= fill; $plen -= $fill; } else { for ($i = $plen; $i--;) { $ctx[3][$i + $left] = $p[$i + $offset]; } $ctx[4] += $plen; $offset += $plen; $plen -= $plen; } } } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @param SplFixedArray $out * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedArrayOffset * @psalm-suppress MixedMethodCall * @psalm-suppress MixedOperand */ public static function finish(SplFixedArray $ctx, SplFixedArray $out) { self::pseudoConstructor(); if ($ctx[4] > 128) { self::increment_counter($ctx, 128); self::compress($ctx, $ctx[3]); $ctx[4] -= 128; if ($ctx[4] > 128) { throw new SodiumException('Failed to assert that buflen <= 128 bytes'); } for ($i = $ctx[4]; $i--;) { $ctx[3][$i] = $ctx[3][$i + 128]; } } self::increment_counter($ctx, $ctx[4]); $ctx[2][0] = self::new64(0xffffffff, 0xffffffff); for ($i = 256 - $ctx[4]; $i--;) { /** @var int $i */ $ctx[3][$i + $ctx[4]] = 0; } self::compress($ctx, $ctx[3]); $i = (int) (($out->getSize() - 1) / 8); for (; $i >= 0; --$i) { self::store64($out, $i << 3, $ctx[0][$i]); } return $out; } /** * @internal You should not use this directly from another application * * @param SplFixedArray|null $key * @param int $outlen * @param SplFixedArray|null $salt * @param SplFixedArray|null $personal * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedAssignment * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedMethodCall */ public static function init( $key = null, $outlen = 64, $salt = null, $personal = null ) { self::pseudoConstructor(); $klen = 0; if ($key !== null) { if (count($key) > 64) { throw new SodiumException('Invalid key size'); } $klen = count($key); } if ($outlen > 64) { throw new SodiumException('Invalid output size'); } $ctx = self::context(); $p = new SplFixedArray(64); // Zero our param buffer... for ($i = 64; --$i;) { $p[$i] = 0; } $p[0] = $outlen; // digest_length $p[1] = $klen; // key_length $p[2] = 1; // fanout $p[3] = 1; // depth if ($salt instanceof SplFixedArray) { // salt: [32] through [47] for ($i = 0; $i < 16; ++$i) { $p[32 + $i] = (int) $salt[$i]; } } if ($personal instanceof SplFixedArray) { // personal: [48] through [63] for ($i = 0; $i < 16; ++$i) { $p[48 + $i] = (int) $personal[$i]; } } $ctx[0][0] = self::xor64( $ctx[0][0], self::load64($p, 0) ); if ($salt instanceof SplFixedArray || $personal instanceof SplFixedArray) { // We need to do what blake2b_init_param() does: for ($i = 1; $i < 8; ++$i) { $ctx[0][$i] = self::xor64( $ctx[0][$i], self::load64($p, $i << 3) ); } } if ($klen > 0 && $key instanceof SplFixedArray) { $block = new SplFixedArray(128); for ($i = 128; $i--;) { $block[$i] = 0; } for ($i = $klen; $i--;) { $block[$i] = $key[$i]; } self::update($ctx, $block, 128); $ctx[4] = 128; } return $ctx; } /** * Convert a string into an SplFixedArray of integers * * @internal You should not use this directly from another application * * @param string $str * @return SplFixedArray * @psalm-suppress MixedArgumentTypeCoercion */ public static function stringToSplFixedArray($str = '') { $values = unpack('C*', $str); return SplFixedArray::fromArray(array_values($values)); } /** * Convert an SplFixedArray of integers into a string * * @internal You should not use this directly from another application * * @param SplFixedArray $a * @return string */ public static function SplFixedArrayToString(SplFixedArray $a) { /** * @var array<int, string|int> */ $arr = $a->toArray(); $c = $a->count(); array_unshift($arr, str_repeat('C', $c)); return (string) (call_user_func_array('pack', $arr)); } /** * @internal You should not use this directly from another application * * @param SplFixedArray $ctx * @return string * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment * @psalm-suppress MixedMethodCall */ public static function contextToString(SplFixedArray $ctx) { $str = ''; /** @var array<int, ParagonIE_Sodium_Core32_Int64> $ctxA */ $ctxA = $ctx[0]->toArray(); # uint64_t h[8]; for ($i = 0; $i < 8; ++$i) { if (!($ctxA[$i] instanceof ParagonIE_Sodium_Core32_Int64)) { throw new TypeError('Not an instance of Int64'); } /** @var ParagonIE_Sodium_Core32_Int64 $ctxAi */ $ctxAi = $ctxA[$i]; $str .= $ctxAi->toReverseString(); } # uint64_t t[2]; # uint64_t f[2]; for ($i = 1; $i < 3; ++$i) { /** @var array<int, ParagonIE_Sodium_Core32_Int64> $ctxA */ $ctxA = $ctx[$i]->toArray(); /** @var ParagonIE_Sodium_Core32_Int64 $ctxA1 */ $ctxA1 = $ctxA[0]; /** @var ParagonIE_Sodium_Core32_Int64 $ctxA2 */ $ctxA2 = $ctxA[1]; $str .= $ctxA1->toReverseString(); $str .= $ctxA2->toReverseString(); } # uint8_t buf[2 * 128]; $str .= self::SplFixedArrayToString($ctx[3]); /** @var int $ctx4 */ $ctx4 = $ctx[4]; # size_t buflen; $str .= implode('', array( self::intToChr($ctx4 & 0xff), self::intToChr(($ctx4 >> 8) & 0xff), self::intToChr(($ctx4 >> 16) & 0xff), self::intToChr(($ctx4 >> 24) & 0xff), "\x00\x00\x00\x00" /* self::intToChr(($ctx4 >> 32) & 0xff), self::intToChr(($ctx4 >> 40) & 0xff), self::intToChr(($ctx4 >> 48) & 0xff), self::intToChr(($ctx4 >> 56) & 0xff) */ )); # uint8_t last_node; return $str . self::intToChr($ctx[5]) . str_repeat("\x00", 23); } /** * Creates an SplFixedArray containing other SplFixedArray elements, from * a string (compatible with \Sodium\crypto_generichash_{init, update, final}) * * @internal You should not use this directly from another application * * @param string $string * @return SplFixedArray * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayAssignment */ public static function stringToContext($string) { $ctx = self::context(); # uint64_t h[8]; for ($i = 0; $i < 8; ++$i) { $ctx[0][$i] = ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($string, (($i << 3) + 0), 8) ); } # uint64_t t[2]; # uint64_t f[2]; for ($i = 1; $i < 3; ++$i) { $ctx[$i][1] = ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($string, 72 + (($i - 1) << 4), 8) ); $ctx[$i][0] = ParagonIE_Sodium_Core32_Int64::fromReverseString( self::substr($string, 64 + (($i - 1) << 4), 8) ); } # uint8_t buf[2 * 128]; $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256)); # uint8_t buf[2 * 128]; $int = 0; for ($i = 0; $i < 8; ++$i) { $int |= self::chrToInt($string[352 + $i]) << ($i << 3); } $ctx[4] = $int; return $ctx; } } <?php /** * Class ParagonIE_Sodium_Core32_Int64 * * Encapsulates a 64-bit integer. * * These are immutable. It always returns a new instance. */ class ParagonIE_Sodium_Core32_Int64 { /** * @var array<int, int> - four 16-bit integers */ public $limbs = array(0, 0, 0, 0); /** * @var int */ public $overflow = 0; /** * @var bool */ public $unsignedInt = false; /** * ParagonIE_Sodium_Core32_Int64 constructor. * @param array $array * @param bool $unsignedInt */ public function __construct($array = array(0, 0, 0, 0), $unsignedInt = false) { $this->limbs = array( (int) $array[0], (int) $array[1], (int) $array[2], (int) $array[3] ); $this->overflow = 0; $this->unsignedInt = $unsignedInt; } /** * Adds two int64 objects * * @param ParagonIE_Sodium_Core32_Int64 $addend * @return ParagonIE_Sodium_Core32_Int64 */ public function addInt64(ParagonIE_Sodium_Core32_Int64 $addend) { $i0 = $this->limbs[0]; $i1 = $this->limbs[1]; $i2 = $this->limbs[2]; $i3 = $this->limbs[3]; $j0 = $addend->limbs[0]; $j1 = $addend->limbs[1]; $j2 = $addend->limbs[2]; $j3 = $addend->limbs[3]; $r3 = $i3 + ($j3 & 0xffff); $carry = $r3 >> 16; $r2 = $i2 + ($j2 & 0xffff) + $carry; $carry = $r2 >> 16; $r1 = $i1 + ($j1 & 0xffff) + $carry; $carry = $r1 >> 16; $r0 = $i0 + ($j0 & 0xffff) + $carry; $carry = $r0 >> 16; $r0 &= 0xffff; $r1 &= 0xffff; $r2 &= 0xffff; $r3 &= 0xffff; $return = new ParagonIE_Sodium_Core32_Int64( array($r0, $r1, $r2, $r3) ); $return->overflow = $carry; $return->unsignedInt = $this->unsignedInt; return $return; } /** * Adds a normal integer to an int64 object * * @param int $int * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public function addInt($int) { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); /** @var int $int */ $int = (int) $int; $i0 = $this->limbs[0]; $i1 = $this->limbs[1]; $i2 = $this->limbs[2]; $i3 = $this->limbs[3]; $r3 = $i3 + ($int & 0xffff); $carry = $r3 >> 16; $r2 = $i2 + (($int >> 16) & 0xffff) + $carry; $carry = $r2 >> 16; $r1 = $i1 + $carry; $carry = $r1 >> 16; $r0 = $i0 + $carry; $carry = $r0 >> 16; $r0 &= 0xffff; $r1 &= 0xffff; $r2 &= 0xffff; $r3 &= 0xffff; $return = new ParagonIE_Sodium_Core32_Int64( array($r0, $r1, $r2, $r3) ); $return->overflow = $carry; $return->unsignedInt = $this->unsignedInt; return $return; } /** * @param int $b * @return int */ public function compareInt($b = 0) { $gt = 0; $eq = 1; $i = 4; $j = 0; while ($i > 0) { --$i; /** @var int $x1 */ $x1 = $this->limbs[$i]; /** @var int $x2 */ $x2 = ($b >> ($j << 4)) & 0xffff; /** int */ $gt |= (($x2 - $x1) >> 8) & $eq; /** int */ $eq &= (($x2 ^ $x1) - 1) >> 8; } return ($gt + $gt - $eq) + 1; } /** * @param int $b * @return bool */ public function isGreaterThan($b = 0) { return $this->compareInt($b) > 0; } /** * @param int $b * @return bool */ public function isLessThanInt($b = 0) { return $this->compareInt($b) < 0; } /** * @param int $hi * @param int $lo * @return ParagonIE_Sodium_Core32_Int64 */ public function mask64($hi = 0, $lo = 0) { /** @var int $a */ $a = ($hi >> 16) & 0xffff; /** @var int $b */ $b = ($hi) & 0xffff; /** @var int $c */ $c = ($lo >> 16) & 0xffff; /** @var int $d */ $d = ($lo & 0xffff); return new ParagonIE_Sodium_Core32_Int64( array( $this->limbs[0] & $a, $this->limbs[1] & $b, $this->limbs[2] & $c, $this->limbs[3] & $d ), $this->unsignedInt ); } /** * @param int $int * @param int $size * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment */ public function mulInt($int = 0, $size = 0) { if (ParagonIE_Sodium_Compat::$fastMult) { return $this->mulIntFast($int); } ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); /** @var int $int */ $int = (int) $int; /** @var int $size */ $size = (int) $size; if (!$size) { $size = 63; } $a = clone $this; $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; // Initialize: $ret0 = 0; $ret1 = 0; $ret2 = 0; $ret3 = 0; $a0 = $a->limbs[0]; $a1 = $a->limbs[1]; $a2 = $a->limbs[2]; $a3 = $a->limbs[3]; /** @var int $size */ /** @var int $i */ for ($i = $size; $i >= 0; --$i) { $mask = -($int & 1); $x0 = $a0 & $mask; $x1 = $a1 & $mask; $x2 = $a2 & $mask; $x3 = $a3 & $mask; $ret3 += $x3; $c = $ret3 >> 16; $ret2 += $x2 + $c; $c = $ret2 >> 16; $ret1 += $x1 + $c; $c = $ret1 >> 16; $ret0 += $x0 + $c; $ret0 &= 0xffff; $ret1 &= 0xffff; $ret2 &= 0xffff; $ret3 &= 0xffff; $a3 = $a3 << 1; $x3 = $a3 >> 16; $a2 = ($a2 << 1) | $x3; $x2 = $a2 >> 16; $a1 = ($a1 << 1) | $x2; $x1 = $a1 >> 16; $a0 = ($a0 << 1) | $x1; $a0 &= 0xffff; $a1 &= 0xffff; $a2 &= 0xffff; $a3 &= 0xffff; $int >>= 1; } $return->limbs[0] = $ret0; $return->limbs[1] = $ret1; $return->limbs[2] = $ret2; $return->limbs[3] = $ret3; return $return; } /** * @param ParagonIE_Sodium_Core32_Int64 $A * @param ParagonIE_Sodium_Core32_Int64 $B * @return array<int, ParagonIE_Sodium_Core32_Int64> * @throws SodiumException * @throws TypeError * @psalm-suppress MixedInferredReturnType */ public static function ctSelect( ParagonIE_Sodium_Core32_Int64 $A, ParagonIE_Sodium_Core32_Int64 $B ) { $a = clone $A; $b = clone $B; /** @var int $aNeg */ $aNeg = ($a->limbs[0] >> 15) & 1; /** @var int $bNeg */ $bNeg = ($b->limbs[0] >> 15) & 1; /** @var int $m */ $m = (-($aNeg & $bNeg)) | 1; /** @var int $swap */ $swap = $bNeg & ~$aNeg; /** @var int $d */ $d = -$swap; /* if ($bNeg && !$aNeg) { $a = clone $int; $b = clone $this; } elseif($bNeg && $aNeg) { $a = $this->mulInt(-1); $b = $int->mulInt(-1); } */ $x = $a->xorInt64($b)->mask64($d, $d); return array( $a->xorInt64($x)->mulInt($m), $b->xorInt64($x)->mulInt($m) ); } /** * @param array<int, int> $a * @param array<int, int> $b * @param int $baseLog2 * @return array<int, int> */ public function multiplyLong(array $a, array $b, $baseLog2 = 16) { $a_l = count($a); $b_l = count($b); /** @var array<int, int> $r */ $r = array_fill(0, $a_l + $b_l + 1, 0); $base = 1 << $baseLog2; for ($i = 0; $i < $a_l; ++$i) { $a_i = $a[$i]; for ($j = 0; $j < $a_l; ++$j) { $b_j = $b[$j]; $product = (($a_i * $b_j) + $r[$i + $j]); $carry = (((int) $product >> $baseLog2) & 0xffff); $r[$i + $j] = ((int) $product - (int) ($carry * $base)) & 0xffff; $r[$i + $j + 1] += $carry; } } return array_slice($r, 0, 5); } /** * @param int $int * @return ParagonIE_Sodium_Core32_Int64 */ public function mulIntFast($int) { // Handle negative numbers $aNeg = ($this->limbs[0] >> 15) & 1; $bNeg = ($int >> 31) & 1; $a = array_reverse($this->limbs); $b = array( $int & 0xffff, ($int >> 16) & 0xffff, -$bNeg & 0xffff, -$bNeg & 0xffff ); if ($aNeg) { for ($i = 0; $i < 4; ++$i) { $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; } ++$a[0]; } if ($bNeg) { for ($i = 0; $i < 4; ++$i) { $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; } ++$b[0]; } // Multiply $res = $this->multiplyLong($a, $b); // Re-apply negation to results if ($aNeg !== $bNeg) { for ($i = 0; $i < 4; ++$i) { $res[$i] = (0xffff ^ $res[$i]) & 0xffff; } // Handle integer overflow $c = 1; for ($i = 0; $i < 4; ++$i) { $res[$i] += $c; $c = $res[$i] >> 16; $res[$i] &= 0xffff; } } // Return our values $return = new ParagonIE_Sodium_Core32_Int64(); $return->limbs = array( $res[3] & 0xffff, $res[2] & 0xffff, $res[1] & 0xffff, $res[0] & 0xffff ); if (count($res) > 4) { $return->overflow = $res[4] & 0xffff; } $return->unsignedInt = $this->unsignedInt; return $return; } /** * @param ParagonIE_Sodium_Core32_Int64 $right * @return ParagonIE_Sodium_Core32_Int64 */ public function mulInt64Fast(ParagonIE_Sodium_Core32_Int64 $right) { $aNeg = ($this->limbs[0] >> 15) & 1; $bNeg = ($right->limbs[0] >> 15) & 1; $a = array_reverse($this->limbs); $b = array_reverse($right->limbs); if ($aNeg) { for ($i = 0; $i < 4; ++$i) { $a[$i] = ($a[$i] ^ 0xffff) & 0xffff; } ++$a[0]; } if ($bNeg) { for ($i = 0; $i < 4; ++$i) { $b[$i] = ($b[$i] ^ 0xffff) & 0xffff; } ++$b[0]; } $res = $this->multiplyLong($a, $b); if ($aNeg !== $bNeg) { if ($aNeg !== $bNeg) { for ($i = 0; $i < 4; ++$i) { $res[$i] = ($res[$i] ^ 0xffff) & 0xffff; } $c = 1; for ($i = 0; $i < 4; ++$i) { $res[$i] += $c; $c = $res[$i] >> 16; $res[$i] &= 0xffff; } } } $return = new ParagonIE_Sodium_Core32_Int64(); $return->limbs = array( $res[3] & 0xffff, $res[2] & 0xffff, $res[1] & 0xffff, $res[0] & 0xffff ); if (count($res) > 4) { $return->overflow = $res[4]; } return $return; } /** * @param ParagonIE_Sodium_Core32_Int64 $int * @param int $size * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment */ public function mulInt64(ParagonIE_Sodium_Core32_Int64 $int, $size = 0) { if (ParagonIE_Sodium_Compat::$fastMult) { return $this->mulInt64Fast($int); } ParagonIE_Sodium_Core32_Util::declareScalarType($size, 'int', 2); if (!$size) { $size = 63; } list($a, $b) = self::ctSelect($this, $int); $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; // Initialize: $ret0 = 0; $ret1 = 0; $ret2 = 0; $ret3 = 0; $a0 = $a->limbs[0]; $a1 = $a->limbs[1]; $a2 = $a->limbs[2]; $a3 = $a->limbs[3]; $b0 = $b->limbs[0]; $b1 = $b->limbs[1]; $b2 = $b->limbs[2]; $b3 = $b->limbs[3]; /** @var int $size */ /** @var int $i */ for ($i = (int) $size; $i >= 0; --$i) { $mask = -($b3 & 1); $x0 = $a0 & $mask; $x1 = $a1 & $mask; $x2 = $a2 & $mask; $x3 = $a3 & $mask; $ret3 += $x3; $c = $ret3 >> 16; $ret2 += $x2 + $c; $c = $ret2 >> 16; $ret1 += $x1 + $c; $c = $ret1 >> 16; $ret0 += $x0 + $c; $ret0 &= 0xffff; $ret1 &= 0xffff; $ret2 &= 0xffff; $ret3 &= 0xffff; $a3 = $a3 << 1; $x3 = $a3 >> 16; $a2 = ($a2 << 1) | $x3; $x2 = $a2 >> 16; $a1 = ($a1 << 1) | $x2; $x1 = $a1 >> 16; $a0 = ($a0 << 1) | $x1; $a0 &= 0xffff; $a1 &= 0xffff; $a2 &= 0xffff; $a3 &= 0xffff; $x0 = ($b0 & 1) << 16; $x1 = ($b1 & 1) << 16; $x2 = ($b2 & 1) << 16; $b0 = ($b0 >> 1); $b1 = (($b1 | $x0) >> 1); $b2 = (($b2 | $x1) >> 1); $b3 = (($b3 | $x2) >> 1); $b0 &= 0xffff; $b1 &= 0xffff; $b2 &= 0xffff; $b3 &= 0xffff; } $return->limbs[0] = $ret0; $return->limbs[1] = $ret1; $return->limbs[2] = $ret2; $return->limbs[3] = $ret3; return $return; } /** * OR this 64-bit integer with another. * * @param ParagonIE_Sodium_Core32_Int64 $b * @return ParagonIE_Sodium_Core32_Int64 */ public function orInt64(ParagonIE_Sodium_Core32_Int64 $b) { $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $return->limbs = array( (int) ($this->limbs[0] | $b->limbs[0]), (int) ($this->limbs[1] | $b->limbs[1]), (int) ($this->limbs[2] | $b->limbs[2]), (int) ($this->limbs[3] | $b->limbs[3]) ); return $return; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public function rotateLeft($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $c &= 63; if ($c === 0) { // NOP, but we want a copy. $return->limbs = $this->limbs; } else { /** @var array<int, int> $limbs */ $limbs =& $return->limbs; /** @var array<int, int> $myLimbs */ $myLimbs =& $this->limbs; /** @var int $idx_shift */ $idx_shift = ($c >> 4) & 3; /** @var int $sub_shift */ $sub_shift = $c & 15; for ($i = 3; $i >= 0; --$i) { /** @var int $j */ $j = ($i + $idx_shift) & 3; /** @var int $k */ $k = ($i + $idx_shift + 1) & 3; $limbs[$i] = (int) ( ( ((int) ($myLimbs[$j]) << $sub_shift) | ((int) ($myLimbs[$k]) >> (16 - $sub_shift)) ) & 0xffff ); } } return $return; } /** * Rotate to the right * * @param int $c * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArrayAccess */ public function rotateRight($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; /** @var ParagonIE_Sodium_Core32_Int64 $return */ $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $c &= 63; /** @var int $c */ if ($c === 0) { // NOP, but we want a copy. $return->limbs = $this->limbs; } else { /** @var array<int, int> $limbs */ $limbs =& $return->limbs; /** @var array<int, int> $myLimbs */ $myLimbs =& $this->limbs; /** @var int $idx_shift */ $idx_shift = ($c >> 4) & 3; /** @var int $sub_shift */ $sub_shift = $c & 15; for ($i = 3; $i >= 0; --$i) { /** @var int $j */ $j = ($i - $idx_shift) & 3; /** @var int $k */ $k = ($i - $idx_shift - 1) & 3; $limbs[$i] = (int) ( ( ((int) ($myLimbs[$j]) >> (int) ($sub_shift)) | ((int) ($myLimbs[$k]) << (16 - (int) ($sub_shift))) ) & 0xffff ); } } return $return; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public function shiftLeft($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); /** @var int $c */ $c = (int) $c; $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $c &= 63; if ($c >= 16) { if ($c >= 48) { $return->limbs = array( $this->limbs[3], 0, 0, 0 ); } elseif ($c >= 32) { $return->limbs = array( $this->limbs[2], $this->limbs[3], 0, 0 ); } else { $return->limbs = array( $this->limbs[1], $this->limbs[2], $this->limbs[3], 0 ); } return $return->shiftLeft($c & 15); } if ($c === 0) { $return->limbs = $this->limbs; } elseif ($c < 0) { /** @var int $c */ return $this->shiftRight(-$c); } else { if (!is_int($c)) { throw new TypeError(); } /** @var int $carry */ $carry = 0; for ($i = 3; $i >= 0; --$i) { /** @var int $tmp */ $tmp = ($this->limbs[$i] << $c) | ($carry & 0xffff); $return->limbs[$i] = (int) ($tmp & 0xffff); /** @var int $carry */ $carry = $tmp >> 16; } } return $return; } /** * @param int $c * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public function shiftRight($c = 0) { ParagonIE_Sodium_Core32_Util::declareScalarType($c, 'int', 1); $c = (int) $c; /** @var int $c */ $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $c &= 63; $negative = -(($this->limbs[0] >> 15) & 1); if ($c >= 16) { if ($c >= 48) { $return->limbs = array( (int) ($negative & 0xffff), (int) ($negative & 0xffff), (int) ($negative & 0xffff), (int) $this->limbs[0] ); } elseif ($c >= 32) { $return->limbs = array( (int) ($negative & 0xffff), (int) ($negative & 0xffff), (int) $this->limbs[0], (int) $this->limbs[1] ); } else { $return->limbs = array( (int) ($negative & 0xffff), (int) $this->limbs[0], (int) $this->limbs[1], (int) $this->limbs[2] ); } return $return->shiftRight($c & 15); } if ($c === 0) { $return->limbs = $this->limbs; } elseif ($c < 0) { return $this->shiftLeft(-$c); } else { if (!is_int($c)) { throw new TypeError(); } /** @var int $carryRight */ $carryRight = ($negative & 0xffff); $mask = (int) (((1 << ($c + 1)) - 1) & 0xffff); for ($i = 0; $i < 4; ++$i) { $return->limbs[$i] = (int) ( (($this->limbs[$i] >> $c) | ($carryRight << (16 - $c))) & 0xffff ); $carryRight = (int) ($this->limbs[$i] & $mask); } } return $return; } /** * Subtract a normal integer from an int64 object. * * @param int $int * @return ParagonIE_Sodium_Core32_Int64 * @throws SodiumException * @throws TypeError */ public function subInt($int) { ParagonIE_Sodium_Core32_Util::declareScalarType($int, 'int', 1); $int = (int) $int; $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; /** @var int $carry */ $carry = 0; for ($i = 3; $i >= 0; --$i) { /** @var int $tmp */ $tmp = $this->limbs[$i] - (($int >> 16) & 0xffff) + $carry; /** @var int $carry */ $carry = $tmp >> 16; $return->limbs[$i] = (int) ($tmp & 0xffff); } return $return; } /** * The difference between two Int64 objects. * * @param ParagonIE_Sodium_Core32_Int64 $b * @return ParagonIE_Sodium_Core32_Int64 */ public function subInt64(ParagonIE_Sodium_Core32_Int64 $b) { $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; /** @var int $carry */ $carry = 0; for ($i = 3; $i >= 0; --$i) { /** @var int $tmp */ $tmp = $this->limbs[$i] - $b->limbs[$i] + $carry; /** @var int $carry */ $carry = ($tmp >> 16); $return->limbs[$i] = (int) ($tmp & 0xffff); } return $return; } /** * XOR this 64-bit integer with another. * * @param ParagonIE_Sodium_Core32_Int64 $b * @return ParagonIE_Sodium_Core32_Int64 */ public function xorInt64(ParagonIE_Sodium_Core32_Int64 $b) { $return = new ParagonIE_Sodium_Core32_Int64(); $return->unsignedInt = $this->unsignedInt; $return->limbs = array( (int) ($this->limbs[0] ^ $b->limbs[0]), (int) ($this->limbs[1] ^ $b->limbs[1]), (int) ($this->limbs[2] ^ $b->limbs[2]), (int) ($this->limbs[3] ^ $b->limbs[3]) ); return $return; } /** * @param int $low * @param int $high * @return self * @throws SodiumException * @throws TypeError */ public static function fromInts($low, $high) { ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1); ParagonIE_Sodium_Core32_Util::declareScalarType($high, 'int', 2); $high = (int) $high; $low = (int) $low; return new ParagonIE_Sodium_Core32_Int64( array( (int) (($high >> 16) & 0xffff), (int) ($high & 0xffff), (int) (($low >> 16) & 0xffff), (int) ($low & 0xffff) ) ); } /** * @param int $low * @return self * @throws SodiumException * @throws TypeError */ public static function fromInt($low) { ParagonIE_Sodium_Core32_Util::declareScalarType($low, 'int', 1); $low = (int) $low; return new ParagonIE_Sodium_Core32_Int64( array( 0, 0, (int) (($low >> 16) & 0xffff), (int) ($low & 0xffff) ) ); } /** * @return int */ public function toInt() { return (int) ( (($this->limbs[2] & 0xffff) << 16) | ($this->limbs[3] & 0xffff) ); } /** * @param string $string * @return self * @throws SodiumException * @throws TypeError */ public static function fromString($string) { ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); $string = (string) $string; if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) { throw new RangeException( 'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' ); } $return = new ParagonIE_Sodium_Core32_Int64(); $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff) << 8); $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff); $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff) << 8); $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff); $return->limbs[2] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff) << 8); $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff); $return->limbs[3] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff) << 8); $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff); return $return; } /** * @param string $string * @return self * @throws SodiumException * @throws TypeError */ public static function fromReverseString($string) { ParagonIE_Sodium_Core32_Util::declareScalarType($string, 'string', 1); $string = (string) $string; if (ParagonIE_Sodium_Core32_Util::strlen($string) !== 8) { throw new RangeException( 'String must be 8 bytes; ' . ParagonIE_Sodium_Core32_Util::strlen($string) . ' given.' ); } $return = new ParagonIE_Sodium_Core32_Int64(); $return->limbs[0] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[7]) & 0xff) << 8); $return->limbs[0] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[6]) & 0xff); $return->limbs[1] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[5]) & 0xff) << 8); $return->limbs[1] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[4]) & 0xff); $return->limbs[2] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[3]) & 0xff) << 8); $return->limbs[2] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[2]) & 0xff); $return->limbs[3] = (int) ((ParagonIE_Sodium_Core32_Util::chrToInt($string[1]) & 0xff) << 8); $return->limbs[3] |= (ParagonIE_Sodium_Core32_Util::chrToInt($string[0]) & 0xff); return $return; } /** * @return array<int, int> */ public function toArray() { return array( (int) ((($this->limbs[0] & 0xffff) << 16) | ($this->limbs[1] & 0xffff)), (int) ((($this->limbs[2] & 0xffff) << 16) | ($this->limbs[3] & 0xffff)) ); } /** * @return ParagonIE_Sodium_Core32_Int32 */ public function toInt32() { $return = new ParagonIE_Sodium_Core32_Int32(); $return->limbs[0] = (int) ($this->limbs[2]); $return->limbs[1] = (int) ($this->limbs[3]); $return->unsignedInt = $this->unsignedInt; $return->overflow = (int) (ParagonIE_Sodium_Core32_Util::abs($this->limbs[1], 16) & 0xffff); return $return; } /** * @return ParagonIE_Sodium_Core32_Int64 */ public function toInt64() { $return = new ParagonIE_Sodium_Core32_Int64(); $return->limbs[0] = (int) ($this->limbs[0]); $return->limbs[1] = (int) ($this->limbs[1]); $return->limbs[2] = (int) ($this->limbs[2]); $return->limbs[3] = (int) ($this->limbs[3]); $return->unsignedInt = $this->unsignedInt; $return->overflow = ParagonIE_Sodium_Core32_Util::abs($this->overflow); return $return; } /** * @param bool $bool * @return self */ public function setUnsignedInt($bool = false) { $this->unsignedInt = !empty($bool); return $this; } /** * @return string * @throws TypeError */ public function toString() { return ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff); } /** * @return string * @throws TypeError */ public function toReverseString() { return ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[3] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[3] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[2] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[2] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[1] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[1] >> 8) & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr($this->limbs[0] & 0xff) . ParagonIE_Sodium_Core32_Util::intToChr(($this->limbs[0] >> 8) & 0xff); } /** * @return string */ public function __toString() { try { return $this->toString(); } catch (TypeError $ex) { // PHP engine can't handle exceptions from __toString() return ''; } } } <?php if (class_exists('ParagonIE_Sodium_Core32_Util', false)) { return; } /** * Class ParagonIE_Sodium_Core_Util */ abstract class ParagonIE_Sodium_Core32_Util extends ParagonIE_Sodium_Core_Util { } <?php if (class_exists('ParagonIE_Sodium_Core32_Salsa20', false)) { return; } /** * Class ParagonIE_Sodium_Core32_Salsa20 */ abstract class ParagonIE_Sodium_Core32_Salsa20 extends ParagonIE_Sodium_Core32_Util { const ROUNDS = 20; /** * Calculate an salsa20 hash of a single block * * @internal You should not use this directly from another application * * @param string $in * @param string $k * @param string|null $c * @return string * @throws SodiumException * @throws TypeError */ public static function core_salsa20($in, $k, $c = null) { /** * @var ParagonIE_Sodium_Core32_Int32 $x0 * @var ParagonIE_Sodium_Core32_Int32 $x1 * @var ParagonIE_Sodium_Core32_Int32 $x2 * @var ParagonIE_Sodium_Core32_Int32 $x3 * @var ParagonIE_Sodium_Core32_Int32 $x4 * @var ParagonIE_Sodium_Core32_Int32 $x5 * @var ParagonIE_Sodium_Core32_Int32 $x6 * @var ParagonIE_Sodium_Core32_Int32 $x7 * @var ParagonIE_Sodium_Core32_Int32 $x8 * @var ParagonIE_Sodium_Core32_Int32 $x9 * @var ParagonIE_Sodium_Core32_Int32 $x10 * @var ParagonIE_Sodium_Core32_Int32 $x11 * @var ParagonIE_Sodium_Core32_Int32 $x12 * @var ParagonIE_Sodium_Core32_Int32 $x13 * @var ParagonIE_Sodium_Core32_Int32 $x14 * @var ParagonIE_Sodium_Core32_Int32 $x15 * @var ParagonIE_Sodium_Core32_Int32 $j0 * @var ParagonIE_Sodium_Core32_Int32 $j1 * @var ParagonIE_Sodium_Core32_Int32 $j2 * @var ParagonIE_Sodium_Core32_Int32 $j3 * @var ParagonIE_Sodium_Core32_Int32 $j4 * @var ParagonIE_Sodium_Core32_Int32 $j5 * @var ParagonIE_Sodium_Core32_Int32 $j6 * @var ParagonIE_Sodium_Core32_Int32 $j7 * @var ParagonIE_Sodium_Core32_Int32 $j8 * @var ParagonIE_Sodium_Core32_Int32 $j9 * @var ParagonIE_Sodium_Core32_Int32 $j10 * @var ParagonIE_Sodium_Core32_Int32 $j11 * @var ParagonIE_Sodium_Core32_Int32 $j12 * @var ParagonIE_Sodium_Core32_Int32 $j13 * @var ParagonIE_Sodium_Core32_Int32 $j14 * @var ParagonIE_Sodium_Core32_Int32 $j15 */ if (self::strlen($k) < 32) { throw new RangeException('Key must be 32 bytes long'); } if ($c === null) { $x0 = new ParagonIE_Sodium_Core32_Int32(array(0x6170, 0x7865)); $x5 = new ParagonIE_Sodium_Core32_Int32(array(0x3320, 0x646e)); $x10 = new ParagonIE_Sodium_Core32_Int32(array(0x7962, 0x2d32)); $x15 = new ParagonIE_Sodium_Core32_Int32(array(0x6b20, 0x6574)); } else { $x0 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 0, 4)); $x5 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 4, 4)); $x10 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 8, 4)); $x15 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($c, 12, 4)); } $x1 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 0, 4)); $x2 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 4, 4)); $x3 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 8, 4)); $x4 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 12, 4)); $x6 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 0, 4)); $x7 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 4, 4)); $x8 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 8, 4)); $x9 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($in, 12, 4)); $x11 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 16, 4)); $x12 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 20, 4)); $x13 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 24, 4)); $x14 = ParagonIE_Sodium_Core32_Int32::fromReverseString(self::substr($k, 28, 4)); $j0 = clone $x0; $j1 = clone $x1; $j2 = clone $x2; $j3 = clone $x3; $j4 = clone $x4; $j5 = clone $x5; $j6 = clone $x6; $j7 = clone $x7; $j8 = clone $x8; $j9 = clone $x9; $j10 = clone $x10; $j11 = clone $x11; $j12 = clone $x12; $j13 = clone $x13; $j14 = clone $x14; $j15 = clone $x15; for ($i = self::ROUNDS; $i > 0; $i -= 2) { $x4 = $x4->xorInt32($x0->addInt32($x12)->rotateLeft(7)); $x8 = $x8->xorInt32($x4->addInt32($x0)->rotateLeft(9)); $x12 = $x12->xorInt32($x8->addInt32($x4)->rotateLeft(13)); $x0 = $x0->xorInt32($x12->addInt32($x8)->rotateLeft(18)); $x9 = $x9->xorInt32($x5->addInt32($x1)->rotateLeft(7)); $x13 = $x13->xorInt32($x9->addInt32($x5)->rotateLeft(9)); $x1 = $x1->xorInt32($x13->addInt32($x9)->rotateLeft(13)); $x5 = $x5->xorInt32($x1->addInt32($x13)->rotateLeft(18)); $x14 = $x14->xorInt32($x10->addInt32($x6)->rotateLeft(7)); $x2 = $x2->xorInt32($x14->addInt32($x10)->rotateLeft(9)); $x6 = $x6->xorInt32($x2->addInt32($x14)->rotateLeft(13)); $x10 = $x10->xorInt32($x6->addInt32($x2)->rotateLeft(18)); $x3 = $x3->xorInt32($x15->addInt32($x11)->rotateLeft(7)); $x7 = $x7->xorInt32($x3->addInt32($x15)->rotateLeft(9)); $x11 = $x11->xorInt32($x7->addInt32($x3)->rotateLeft(13)); $x15 = $x15->xorInt32($x11->addInt32($x7)->rotateLeft(18)); $x1 = $x1->xorInt32($x0->addInt32($x3)->rotateLeft(7)); $x2 = $x2->xorInt32($x1->addInt32($x0)->rotateLeft(9)); $x3 = $x3->xorInt32($x2->addInt32($x1)->rotateLeft(13)); $x0 = $x0->xorInt32($x3->addInt32($x2)->rotateLeft(18)); $x6 = $x6->xorInt32($x5->addInt32($x4)->rotateLeft(7)); $x7 = $x7->xorInt32($x6->addInt32($x5)->rotateLeft(9)); $x4 = $x4->xorInt32($x7->addInt32($x6)->rotateLeft(13)); $x5 = $x5->xorInt32($x4->addInt32($x7)->rotateLeft(18)); $x11 = $x11->xorInt32($x10->addInt32($x9)->rotateLeft(7)); $x8 = $x8->xorInt32($x11->addInt32($x10)->rotateLeft(9)); $x9 = $x9->xorInt32($x8->addInt32($x11)->rotateLeft(13)); $x10 = $x10->xorInt32($x9->addInt32($x8)->rotateLeft(18)); $x12 = $x12->xorInt32($x15->addInt32($x14)->rotateLeft(7)); $x13 = $x13->xorInt32($x12->addInt32($x15)->rotateLeft(9)); $x14 = $x14->xorInt32($x13->addInt32($x12)->rotateLeft(13)); $x15 = $x15->xorInt32($x14->addInt32($x13)->rotateLeft(18)); } $x0 = $x0->addInt32($j0); $x1 = $x1->addInt32($j1); $x2 = $x2->addInt32($j2); $x3 = $x3->addInt32($j3); $x4 = $x4->addInt32($j4); $x5 = $x5->addInt32($j5); $x6 = $x6->addInt32($j6); $x7 = $x7->addInt32($j7); $x8 = $x8->addInt32($j8); $x9 = $x9->addInt32($j9); $x10 = $x10->addInt32($j10); $x11 = $x11->addInt32($j11); $x12 = $x12->addInt32($j12); $x13 = $x13->addInt32($j13); $x14 = $x14->addInt32($j14); $x15 = $x15->addInt32($j15); return $x0->toReverseString() . $x1->toReverseString() . $x2->toReverseString() . $x3->toReverseString() . $x4->toReverseString() . $x5->toReverseString() . $x6->toReverseString() . $x7->toReverseString() . $x8->toReverseString() . $x9->toReverseString() . $x10->toReverseString() . $x11->toReverseString() . $x12->toReverseString() . $x13->toReverseString() . $x14->toReverseString() . $x15->toReverseString(); } /** * @internal You should not use this directly from another application * * @param int $len * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20($len, $nonce, $key) { if (self::strlen($key) !== 32) { throw new RangeException('Key must be 32 bytes long'); } $kcopy = '' . $key; $in = self::substr($nonce, 0, 8) . str_repeat("\0", 8); $c = ''; while ($len >= 64) { $c .= self::core_salsa20($in, $kcopy, null); $u = 1; // Internal counter. for ($i = 8; $i < 16; ++$i) { $u += self::chrToInt($in[$i]); $in[$i] = self::intToChr($u & 0xff); $u >>= 8; } $len -= 64; } if ($len > 0) { $c .= self::substr( self::core_salsa20($in, $kcopy, null), 0, $len ); } try { ParagonIE_Sodium_Compat::memzero($kcopy); } catch (SodiumException $ex) { $kcopy = null; } return $c; } /** * @internal You should not use this directly from another application * * @param string $m * @param string $n * @param int $ic * @param string $k * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20_xor_ic($m, $n, $ic, $k) { $mlen = self::strlen($m); if ($mlen < 1) { return ''; } $kcopy = self::substr($k, 0, 32); $in = self::substr($n, 0, 8); // Initialize the counter $in .= ParagonIE_Sodium_Core32_Util::store64_le($ic); $c = ''; while ($mlen >= 64) { $block = self::core_salsa20($in, $kcopy, null); $c .= self::xorStrings( self::substr($m, 0, 64), self::substr($block, 0, 64) ); $u = 1; for ($i = 8; $i < 16; ++$i) { $u += self::chrToInt($in[$i]); $in[$i] = self::intToChr($u & 0xff); $u >>= 8; } $mlen -= 64; $m = self::substr($m, 64); } if ($mlen) { $block = self::core_salsa20($in, $kcopy, null); $c .= self::xorStrings( self::substr($m, 0, $mlen), self::substr($block, 0, $mlen) ); } try { ParagonIE_Sodium_Compat::memzero($block); ParagonIE_Sodium_Compat::memzero($kcopy); } catch (SodiumException $ex) { $block = null; $kcopy = null; } return $c; } /** * @internal You should not use this directly from another application * * @param string $message * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function salsa20_xor($message, $nonce, $key) { return self::xorStrings( $message, self::salsa20( self::strlen($message), $nonce, $key ) ); } } <?php if (class_exists('ParagonIE_Sodium_Core32_X25519', false)) { return; } /** * Class ParagonIE_Sodium_Core32_X25519 */ abstract class ParagonIE_Sodium_Core32_X25519 extends ParagonIE_Sodium_Core32_Curve25519 { /** * Alters the objects passed to this method in place. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @param ParagonIE_Sodium_Core32_Curve25519_Fe $g * @param int $b * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedMethodCall */ public static function fe_cswap( ParagonIE_Sodium_Core32_Curve25519_Fe $f, ParagonIE_Sodium_Core32_Curve25519_Fe $g, $b = 0 ) { $f0 = (int) $f[0]->toInt(); $f1 = (int) $f[1]->toInt(); $f2 = (int) $f[2]->toInt(); $f3 = (int) $f[3]->toInt(); $f4 = (int) $f[4]->toInt(); $f5 = (int) $f[5]->toInt(); $f6 = (int) $f[6]->toInt(); $f7 = (int) $f[7]->toInt(); $f8 = (int) $f[8]->toInt(); $f9 = (int) $f[9]->toInt(); $g0 = (int) $g[0]->toInt(); $g1 = (int) $g[1]->toInt(); $g2 = (int) $g[2]->toInt(); $g3 = (int) $g[3]->toInt(); $g4 = (int) $g[4]->toInt(); $g5 = (int) $g[5]->toInt(); $g6 = (int) $g[6]->toInt(); $g7 = (int) $g[7]->toInt(); $g8 = (int) $g[8]->toInt(); $g9 = (int) $g[9]->toInt(); $b = -$b; /** @var int $x0 */ $x0 = ($f0 ^ $g0) & $b; /** @var int $x1 */ $x1 = ($f1 ^ $g1) & $b; /** @var int $x2 */ $x2 = ($f2 ^ $g2) & $b; /** @var int $x3 */ $x3 = ($f3 ^ $g3) & $b; /** @var int $x4 */ $x4 = ($f4 ^ $g4) & $b; /** @var int $x5 */ $x5 = ($f5 ^ $g5) & $b; /** @var int $x6 */ $x6 = ($f6 ^ $g6) & $b; /** @var int $x7 */ $x7 = ($f7 ^ $g7) & $b; /** @var int $x8 */ $x8 = ($f8 ^ $g8) & $b; /** @var int $x9 */ $x9 = ($f9 ^ $g9) & $b; $f[0] = ParagonIE_Sodium_Core32_Int32::fromInt($f0 ^ $x0); $f[1] = ParagonIE_Sodium_Core32_Int32::fromInt($f1 ^ $x1); $f[2] = ParagonIE_Sodium_Core32_Int32::fromInt($f2 ^ $x2); $f[3] = ParagonIE_Sodium_Core32_Int32::fromInt($f3 ^ $x3); $f[4] = ParagonIE_Sodium_Core32_Int32::fromInt($f4 ^ $x4); $f[5] = ParagonIE_Sodium_Core32_Int32::fromInt($f5 ^ $x5); $f[6] = ParagonIE_Sodium_Core32_Int32::fromInt($f6 ^ $x6); $f[7] = ParagonIE_Sodium_Core32_Int32::fromInt($f7 ^ $x7); $f[8] = ParagonIE_Sodium_Core32_Int32::fromInt($f8 ^ $x8); $f[9] = ParagonIE_Sodium_Core32_Int32::fromInt($f9 ^ $x9); $g[0] = ParagonIE_Sodium_Core32_Int32::fromInt($g0 ^ $x0); $g[1] = ParagonIE_Sodium_Core32_Int32::fromInt($g1 ^ $x1); $g[2] = ParagonIE_Sodium_Core32_Int32::fromInt($g2 ^ $x2); $g[3] = ParagonIE_Sodium_Core32_Int32::fromInt($g3 ^ $x3); $g[4] = ParagonIE_Sodium_Core32_Int32::fromInt($g4 ^ $x4); $g[5] = ParagonIE_Sodium_Core32_Int32::fromInt($g5 ^ $x5); $g[6] = ParagonIE_Sodium_Core32_Int32::fromInt($g6 ^ $x6); $g[7] = ParagonIE_Sodium_Core32_Int32::fromInt($g7 ^ $x7); $g[8] = ParagonIE_Sodium_Core32_Int32::fromInt($g8 ^ $x8); $g[9] = ParagonIE_Sodium_Core32_Int32::fromInt($g9 ^ $x9); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $f * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedMethodCall */ public static function fe_mul121666(ParagonIE_Sodium_Core32_Curve25519_Fe $f) { /** @var array<int, ParagonIE_Sodium_Core32_Int64> $h */ $h = array(); for ($i = 0; $i < 10; ++$i) { $h[$i] = $f[$i]->toInt64()->mulInt(121666, 17); } $carry9 = $h[9]->addInt(1 << 24)->shiftRight(25); $h[0] = $h[0]->addInt64($carry9->mulInt(19, 5)); $h[9] = $h[9]->subInt64($carry9->shiftLeft(25)); $carry1 = $h[1]->addInt(1 << 24)->shiftRight(25); $h[2] = $h[2]->addInt64($carry1); $h[1] = $h[1]->subInt64($carry1->shiftLeft(25)); $carry3 = $h[3]->addInt(1 << 24)->shiftRight(25); $h[4] = $h[4]->addInt64($carry3); $h[3] = $h[3]->subInt64($carry3->shiftLeft(25)); $carry5 = $h[5]->addInt(1 << 24)->shiftRight(25); $h[6] = $h[6]->addInt64($carry5); $h[5] = $h[5]->subInt64($carry5->shiftLeft(25)); $carry7 = $h[7]->addInt(1 << 24)->shiftRight(25); $h[8] = $h[8]->addInt64($carry7); $h[7] = $h[7]->subInt64($carry7->shiftLeft(25)); $carry0 = $h[0]->addInt(1 << 25)->shiftRight(26); $h[1] = $h[1]->addInt64($carry0); $h[0] = $h[0]->subInt64($carry0->shiftLeft(26)); $carry2 = $h[2]->addInt(1 << 25)->shiftRight(26); $h[3] = $h[3]->addInt64($carry2); $h[2] = $h[2]->subInt64($carry2->shiftLeft(26)); $carry4 = $h[4]->addInt(1 << 25)->shiftRight(26); $h[5] = $h[5]->addInt64($carry4); $h[4] = $h[4]->subInt64($carry4->shiftLeft(26)); $carry6 = $h[6]->addInt(1 << 25)->shiftRight(26); $h[7] = $h[7]->addInt64($carry6); $h[6] = $h[6]->subInt64($carry6->shiftLeft(26)); $carry8 = $h[8]->addInt(1 << 25)->shiftRight(26); $h[9] = $h[9]->addInt64($carry8); $h[8] = $h[8]->subInt64($carry8->shiftLeft(26)); for ($i = 0; $i < 10; ++$i) { $h[$i] = $h[$i]->toInt32(); } /** @var array<int, ParagonIE_Sodium_Core32_Int32> $h2 */ $h2 = $h; return ParagonIE_Sodium_Core32_Curve25519_Fe::fromArray($h2); } /** * @internal You should not use this directly from another application * * Inline comments preceded by # are from libsodium's ref10 code. * * @param string $n * @param string $p * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_scalarmult_curve25519_ref10($n, $p) { # for (i = 0;i < 32;++i) e[i] = n[i]; $e = '' . $n; # e[0] &= 248; $e[0] = self::intToChr( self::chrToInt($e[0]) & 248 ); # e[31] &= 127; # e[31] |= 64; $e[31] = self::intToChr( (self::chrToInt($e[31]) & 127) | 64 ); # fe_frombytes(x1,p); $x1 = self::fe_frombytes($p); # fe_1(x2); $x2 = self::fe_1(); # fe_0(z2); $z2 = self::fe_0(); # fe_copy(x3,x1); $x3 = self::fe_copy($x1); # fe_1(z3); $z3 = self::fe_1(); # swap = 0; /** @var int $swap */ $swap = 0; # for (pos = 254;pos >= 0;--pos) { for ($pos = 254; $pos >= 0; --$pos) { # b = e[pos / 8] >> (pos & 7); /** @var int $b */ $b = self::chrToInt( $e[(int) floor($pos / 8)] ) >> ($pos & 7); # b &= 1; $b &= 1; # swap ^= b; $swap ^= $b; # fe_cswap(x2,x3,swap); self::fe_cswap($x2, $x3, $swap); # fe_cswap(z2,z3,swap); self::fe_cswap($z2, $z3, $swap); # swap = b; /** @var int $swap */ $swap = $b; # fe_sub(tmp0,x3,z3); $tmp0 = self::fe_sub($x3, $z3); # fe_sub(tmp1,x2,z2); $tmp1 = self::fe_sub($x2, $z2); # fe_add(x2,x2,z2); $x2 = self::fe_add($x2, $z2); # fe_add(z2,x3,z3); $z2 = self::fe_add($x3, $z3); # fe_mul(z3,tmp0,x2); $z3 = self::fe_mul($tmp0, $x2); # fe_mul(z2,z2,tmp1); $z2 = self::fe_mul($z2, $tmp1); # fe_sq(tmp0,tmp1); $tmp0 = self::fe_sq($tmp1); # fe_sq(tmp1,x2); $tmp1 = self::fe_sq($x2); # fe_add(x3,z3,z2); $x3 = self::fe_add($z3, $z2); # fe_sub(z2,z3,z2); $z2 = self::fe_sub($z3, $z2); # fe_mul(x2,tmp1,tmp0); $x2 = self::fe_mul($tmp1, $tmp0); # fe_sub(tmp1,tmp1,tmp0); $tmp1 = self::fe_sub($tmp1, $tmp0); # fe_sq(z2,z2); $z2 = self::fe_sq($z2); # fe_mul121666(z3,tmp1); $z3 = self::fe_mul121666($tmp1); # fe_sq(x3,x3); $x3 = self::fe_sq($x3); # fe_add(tmp0,tmp0,z3); $tmp0 = self::fe_add($tmp0, $z3); # fe_mul(z3,x1,z2); $z3 = self::fe_mul($x1, $z2); # fe_mul(z2,tmp1,tmp0); $z2 = self::fe_mul($tmp1, $tmp0); } # fe_cswap(x2,x3,swap); self::fe_cswap($x2, $x3, $swap); # fe_cswap(z2,z3,swap); self::fe_cswap($z2, $z3, $swap); # fe_invert(z2,z2); $z2 = self::fe_invert($z2); # fe_mul(x2,x2,z2); $x2 = self::fe_mul($x2, $z2); # fe_tobytes(q,x2); return (string) self::fe_tobytes($x2); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY * @param ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ * @return ParagonIE_Sodium_Core32_Curve25519_Fe * @throws SodiumException * @throws TypeError */ public static function edwards_to_montgomery( ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsY, ParagonIE_Sodium_Core32_Curve25519_Fe $edwardsZ ) { $tempX = self::fe_add($edwardsZ, $edwardsY); $tempZ = self::fe_sub($edwardsZ, $edwardsY); $tempZ = self::fe_invert($tempZ); return self::fe_mul($tempX, $tempZ); } /** * @internal You should not use this directly from another application * * @param string $n * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_scalarmult_curve25519_ref10_base($n) { # for (i = 0;i < 32;++i) e[i] = n[i]; $e = '' . $n; # e[0] &= 248; $e[0] = self::intToChr( self::chrToInt($e[0]) & 248 ); # e[31] &= 127; # e[31] |= 64; $e[31] = self::intToChr( (self::chrToInt($e[31]) & 127) | 64 ); $A = self::ge_scalarmult_base($e); if ( !($A->Y instanceof ParagonIE_Sodium_Core32_Curve25519_Fe) || !($A->Z instanceof ParagonIE_Sodium_Core32_Curve25519_Fe) ) { throw new TypeError('Null points encountered'); } $pk = self::edwards_to_montgomery($A->Y, $A->Z); return self::fe_tobytes($pk); } } <?php /** * Libsodium compatibility layer * * This is the only class you should be interfacing with, as a user of * sodium_compat. * * If the PHP extension for libsodium is installed, it will always use that * instead of our implementations. You get better performance and stronger * guarantees against side-channels that way. * * However, if your users don't have the PHP extension installed, we offer a * compatible interface here. It will give you the correct results as if the * PHP extension was installed. It won't be as fast, of course. * * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * * * * Until audited, this is probably not safe to use! DANGER WILL ROBINSON * * * * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * CAUTION * */ if (class_exists('ParagonIE_Sodium_Compat', false)) { return; } class ParagonIE_Sodium_Compat { /** * This parameter prevents the use of the PECL extension. * It should only be used for unit testing. * * @var bool */ public static $disableFallbackForUnitTests = false; /** * Use fast multiplication rather than our constant-time multiplication * implementation. Can be enabled at runtime. Only enable this if you * are absolutely certain that there is no timing leak on your platform. * * @var bool */ public static $fastMult = false; const LIBRARY_MAJOR_VERSION = 9; const LIBRARY_MINOR_VERSION = 1; const LIBRARY_VERSION_MAJOR = 9; const LIBRARY_VERSION_MINOR = 1; const VERSION_STRING = 'polyfill-1.0.8'; // From libsodium const BASE64_VARIANT_ORIGINAL = 1; const BASE64_VARIANT_ORIGINAL_NO_PADDING = 3; const BASE64_VARIANT_URLSAFE = 5; const BASE64_VARIANT_URLSAFE_NO_PADDING = 7; const CRYPTO_AEAD_AES256GCM_KEYBYTES = 32; const CRYPTO_AEAD_AES256GCM_NSECBYTES = 0; const CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12; const CRYPTO_AEAD_AES256GCM_ABYTES = 16; const CRYPTO_AEAD_AEGIS128L_KEYBYTES = 16; const CRYPTO_AEAD_AEGIS128L_NSECBYTES = 0; const CRYPTO_AEAD_AEGIS128L_NPUBBYTES = 16; const CRYPTO_AEAD_AEGIS128L_ABYTES = 32; const CRYPTO_AEAD_AEGIS256_KEYBYTES = 32; const CRYPTO_AEAD_AEGIS256_NSECBYTES = 0; const CRYPTO_AEAD_AEGIS256_NPUBBYTES = 32; const CRYPTO_AEAD_AEGIS256_ABYTES = 32; const CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32; const CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0; const CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8; const CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12; const CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16; const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32; const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0; const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24; const CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16; const CRYPTO_AUTH_BYTES = 32; const CRYPTO_AUTH_KEYBYTES = 32; const CRYPTO_BOX_SEALBYTES = 16; const CRYPTO_BOX_SECRETKEYBYTES = 32; const CRYPTO_BOX_PUBLICKEYBYTES = 32; const CRYPTO_BOX_KEYPAIRBYTES = 64; const CRYPTO_BOX_MACBYTES = 16; const CRYPTO_BOX_NONCEBYTES = 24; const CRYPTO_BOX_SEEDBYTES = 32; const CRYPTO_CORE_RISTRETTO255_BYTES = 32; const CRYPTO_CORE_RISTRETTO255_SCALARBYTES = 32; const CRYPTO_CORE_RISTRETTO255_HASHBYTES = 64; const CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES = 64; const CRYPTO_KDF_BYTES_MIN = 16; const CRYPTO_KDF_BYTES_MAX = 64; const CRYPTO_KDF_CONTEXTBYTES = 8; const CRYPTO_KDF_KEYBYTES = 32; const CRYPTO_KX_BYTES = 32; const CRYPTO_KX_PRIMITIVE = 'x25519blake2b'; const CRYPTO_KX_SEEDBYTES = 32; const CRYPTO_KX_KEYPAIRBYTES = 64; const CRYPTO_KX_PUBLICKEYBYTES = 32; const CRYPTO_KX_SECRETKEYBYTES = 32; const CRYPTO_KX_SESSIONKEYBYTES = 32; const CRYPTO_GENERICHASH_BYTES = 32; const CRYPTO_GENERICHASH_BYTES_MIN = 16; const CRYPTO_GENERICHASH_BYTES_MAX = 64; const CRYPTO_GENERICHASH_KEYBYTES = 32; const CRYPTO_GENERICHASH_KEYBYTES_MIN = 16; const CRYPTO_GENERICHASH_KEYBYTES_MAX = 64; const CRYPTO_PWHASH_SALTBYTES = 16; const CRYPTO_PWHASH_STRPREFIX = '$argon2id$'; const CRYPTO_PWHASH_ALG_ARGON2I13 = 1; const CRYPTO_PWHASH_ALG_ARGON2ID13 = 2; const CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432; const CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4; const CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728; const CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6; const CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912; const CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$'; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432; const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824; const CRYPTO_SCALARMULT_BYTES = 32; const CRYPTO_SCALARMULT_SCALARBYTES = 32; const CRYPTO_SCALARMULT_RISTRETTO255_BYTES = 32; const CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES = 32; const CRYPTO_SHORTHASH_BYTES = 8; const CRYPTO_SHORTHASH_KEYBYTES = 16; const CRYPTO_SECRETBOX_KEYBYTES = 32; const CRYPTO_SECRETBOX_MACBYTES = 16; const CRYPTO_SECRETBOX_NONCEBYTES = 24; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3; const CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80; const CRYPTO_SIGN_BYTES = 64; const CRYPTO_SIGN_SEEDBYTES = 32; const CRYPTO_SIGN_PUBLICKEYBYTES = 32; const CRYPTO_SIGN_SECRETKEYBYTES = 64; const CRYPTO_SIGN_KEYPAIRBYTES = 96; const CRYPTO_STREAM_KEYBYTES = 32; const CRYPTO_STREAM_NONCEBYTES = 24; const CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32; const CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24; /** * Add two numbers (little-endian unsigned), storing the value in the first * parameter. * * This mutates $val. * * @param string $val * @param string $addv * @return void * @throws SodiumException */ public static function add( #[\SensitiveParameter] &$val, #[\SensitiveParameter] $addv ) { $val_len = ParagonIE_Sodium_Core_Util::strlen($val); $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv); if ($val_len !== $addv_len) { throw new SodiumException('values must have the same length'); } $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val); $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv); $c = 0; for ($i = 0; $i < $val_len; $i++) { $c += ($A[$i] + $B[$i]); $A[$i] = ($c & 0xff); $c >>= 8; } $val = ParagonIE_Sodium_Core_Util::intArrayToString($A); } /** * @param string $encoded * @param int $variant * @param string $ignore * @return string * @throws SodiumException */ public static function base642bin( #[\SensitiveParameter] $encoded, $variant, $ignore = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($encoded, 'string', 1); /** @var string $encoded */ $encoded = (string) $encoded; if (ParagonIE_Sodium_Core_Util::strlen($encoded) === 0) { return ''; } // Just strip before decoding if (!empty($ignore)) { $encoded = str_replace($ignore, '', $encoded); } try { switch ($variant) { case self::BASE64_VARIANT_ORIGINAL: return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, true); case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: return ParagonIE_Sodium_Core_Base64_Original::decode($encoded, false); case self::BASE64_VARIANT_URLSAFE: return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, true); case self::BASE64_VARIANT_URLSAFE_NO_PADDING: return ParagonIE_Sodium_Core_Base64_UrlSafe::decode($encoded, false); default: throw new SodiumException('invalid base64 variant identifier'); } } catch (Exception $ex) { if ($ex instanceof SodiumException) { throw $ex; } throw new SodiumException('invalid base64 string'); } } /** * @param string $decoded * @param int $variant * @return string * @throws SodiumException */ public static function bin2base64( #[\SensitiveParameter] $decoded, $variant ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($decoded, 'string', 1); /** @var string $decoded */ $decoded = (string) $decoded; if (ParagonIE_Sodium_Core_Util::strlen($decoded) === 0) { return ''; } switch ($variant) { case self::BASE64_VARIANT_ORIGINAL: return ParagonIE_Sodium_Core_Base64_Original::encode($decoded); case self::BASE64_VARIANT_ORIGINAL_NO_PADDING: return ParagonIE_Sodium_Core_Base64_Original::encodeUnpadded($decoded); case self::BASE64_VARIANT_URLSAFE: return ParagonIE_Sodium_Core_Base64_UrlSafe::encode($decoded); case self::BASE64_VARIANT_URLSAFE_NO_PADDING: return ParagonIE_Sodium_Core_Base64_UrlSafe::encodeUnpadded($decoded); default: throw new SodiumException('invalid base64 variant identifier'); } } /** * Cache-timing-safe implementation of bin2hex(). * * @param string $string A string (probably raw binary) * @return string A hexadecimal-encoded string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function bin2hex( #[\SensitiveParameter] $string ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($string, 'string', 1); if (self::useNewSodiumAPI()) { return (string) sodium_bin2hex($string); } if (self::use_fallback('bin2hex')) { return (string) call_user_func('\\Sodium\\bin2hex', $string); } return ParagonIE_Sodium_Core_Util::bin2hex($string); } /** * Compare two strings, in constant-time. * Compared to memcmp(), compare() is more useful for sorting. * * @param string $left The left operand; must be a string * @param string $right The right operand; must be a string * @return int If < 0 if the left operand is less than the right * If = 0 if both strings are equal * If > 0 if the right operand is less than the left * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function compare( #[\SensitiveParameter] $left, #[\SensitiveParameter] $right ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($left, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($right, 'string', 2); if (self::useNewSodiumAPI()) { return (int) sodium_compare($left, $right); } if (self::use_fallback('compare')) { return (int) call_user_func('\\Sodium\\compare', $left, $right); } return ParagonIE_Sodium_Core_Util::compare($left, $right); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * AEGIS-128L * * @param string $ciphertext Encrypted message (with MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 32 bytes * @param string $key Encryption key * * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_aegis128l_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS_128L_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long'); } $ct_length = ParagonIE_Sodium_Core_Util::strlen($ciphertext); if ($ct_length < self::CRYPTO_AEAD_AEGIS128L_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_AEGIS128L_ABYTES long'); } $ct = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, $ct_length - self::CRYPTO_AEAD_AEGIS128L_ABYTES ); $tag = ParagonIE_Sodium_Core_Util::substr( $ciphertext, $ct_length - self::CRYPTO_AEAD_AEGIS128L_ABYTES, self::CRYPTO_AEAD_AEGIS128L_ABYTES ); return ParagonIE_Sodium_Core_AEGIS128L::decrypt($ct, $tag, $assocData, $key, $nonce); } /** * Authenticated Encryption with Associated Data: Encryption * * Algorithm: * AEGIS-128L * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 32 bytes * @param string $key Encryption key * * @return string Ciphertext with 32-byte authentication tag appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_aegis128l_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS128L_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS128L_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long'); } list($ct, $tag) = ParagonIE_Sodium_Core_AEGIS128L::encrypt($plaintext, $assocData, $key, $nonce); return $ct . $tag; } /** * Return a secure random key for use with the AEGIS-128L * symmetric AEAD interface. * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_aegis128l_keygen() { return random_bytes(self::CRYPTO_AEAD_AEGIS128L_KEYBYTES); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * AEGIS-256 * * @param string $ciphertext Encrypted message (with MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 32 bytes * @param string $key Encryption key * * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_aegis256_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS256_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS256_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS256_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS256_KEYBYTES long'); } $ct_length = ParagonIE_Sodium_Core_Util::strlen($ciphertext); if ($ct_length < self::CRYPTO_AEAD_AEGIS256_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_AEGIS256_ABYTES long'); } $ct = ParagonIE_Sodium_Core_Util::substr( $ciphertext, 0, $ct_length - self::CRYPTO_AEAD_AEGIS256_ABYTES ); $tag = ParagonIE_Sodium_Core_Util::substr( $ciphertext, $ct_length - self::CRYPTO_AEAD_AEGIS256_ABYTES, self::CRYPTO_AEAD_AEGIS256_ABYTES ); return ParagonIE_Sodium_Core_AEGIS256::decrypt($ct, $tag, $assocData, $key, $nonce); } /** * Authenticated Encryption with Associated Data: Encryption * * Algorithm: * AEGIS-256 * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 32 bytes * @param string $key Encryption key * * @return string Ciphertext with 32-byte authentication tag appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_aegis256_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AEGIS256_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AEGIS256_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AEGIS128L_KEYBYTES long'); } list($ct, $tag) = ParagonIE_Sodium_Core_AEGIS256::encrypt($plaintext, $assocData, $key, $nonce); return $ct . $tag; } /** * Return a secure random key for use with the AEGIS-256 * symmetric AEAD interface. * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_aegis256_keygen() { return random_bytes(self::CRYPTO_AEAD_AEGIS256_KEYBYTES); } /** * Is AES-256-GCM even available to use? * * @return bool * @psalm-suppress UndefinedFunction * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_aes256gcm_is_available() { if (self::useNewSodiumAPI()) { return sodium_crypto_aead_aes256gcm_is_available(); } if (self::use_fallback('crypto_aead_aes256gcm_is_available')) { return call_user_func('\\Sodium\\crypto_aead_aes256gcm_is_available'); } if (PHP_VERSION_ID < 70100) { // OpenSSL doesn't support AEAD before 7.1.0 return false; } if (!is_callable('openssl_encrypt') || !is_callable('openssl_decrypt')) { // OpenSSL isn't installed return false; } return (bool) in_array('aes-256-gcm', openssl_get_cipher_methods()); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * AES-256-GCM * * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * * @return string|bool The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_aes256gcm_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { if (!self::crypto_aead_aes256gcm_is_available()) { throw new SodiumException('AES-256-GCM is not available'); } ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AES256GCM_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AES256GCM_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AES256GCM_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AES256GCM_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_AES256GCM_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_AES256GCM_ABYTES long'); } if (!is_callable('openssl_decrypt')) { throw new SodiumException('The OpenSSL extension is not installed, or openssl_decrypt() is not available'); } /** @var string $ctext */ $ctext = ParagonIE_Sodium_Core_Util::substr($ciphertext, 0, -self::CRYPTO_AEAD_AES256GCM_ABYTES); /** @var string $authTag */ $authTag = ParagonIE_Sodium_Core_Util::substr($ciphertext, -self::CRYPTO_AEAD_AES256GCM_ABYTES, 16); return openssl_decrypt( $ctext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $authTag, $assocData ); } /** * Authenticated Encryption with Associated Data: Encryption * * Algorithm: * AES-256-GCM * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * * @return string Ciphertext with a 16-byte GCM message * authentication code appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_aes256gcm_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { if (!self::crypto_aead_aes256gcm_is_available()) { throw new SodiumException('AES-256-GCM is not available'); } ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_AES256GCM_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_AES256GCM_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_AES256GCM_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_AES256GCM_KEYBYTES long'); } if (!is_callable('openssl_encrypt')) { throw new SodiumException('The OpenSSL extension is not installed, or openssl_encrypt() is not available'); } $authTag = ''; $ciphertext = openssl_encrypt( $plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $nonce, $authTag, $assocData ); return $ciphertext . $authTag; } /** * Return a secure random key for use with the AES-256-GCM * symmetric AEAD interface. * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_aes256gcm_keygen() { return random_bytes(self::CRYPTO_AEAD_AES256GCM_KEYBYTES); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * ChaCha20-Poly1305 * * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_chacha20poly1305_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_ABYTES long'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_aead_chacha20poly1305_decrypt( $ciphertext, $assocData, $nonce, $key ); } if (self::use_fallback('crypto_aead_chacha20poly1305_decrypt')) { return call_user_func( '\\Sodium\\crypto_aead_chacha20poly1305_decrypt', $ciphertext, $assocData, $nonce, $key ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_decrypt( $ciphertext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_chacha20poly1305_decrypt( $ciphertext, $assocData, $nonce, $key ); } /** * Authenticated Encryption with Associated Data * * Algorithm: * ChaCha20-Poly1305 * * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * * @return string Ciphertext with a 16-byte Poly1305 message * authentication code appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_chacha20poly1305_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_aead_chacha20poly1305_encrypt( $plaintext, $assocData, $nonce, $key ); } if (self::use_fallback('crypto_aead_chacha20poly1305_encrypt')) { return (string) call_user_func( '\\Sodium\\crypto_aead_chacha20poly1305_encrypt', $plaintext, $assocData, $nonce, $key ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_encrypt( $plaintext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_chacha20poly1305_encrypt( $plaintext, $assocData, $nonce, $key ); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * ChaCha20-Poly1305 * * IETF mode uses a 96-bit random nonce with a 32-bit counter. * Regular mode uses a 64-bit random nonce with a 64-bit counter. * * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 12 bytes * @param string $key Encryption key * * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_aead_chacha20poly1305_ietf_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_CHACHA20POLY1305_ABYTES long'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_aead_chacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } if (self::use_fallback('crypto_aead_chacha20poly1305_ietf_decrypt')) { return call_user_func( '\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt', $ciphertext, $assocData, $nonce, $key ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_chacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } /** * Return a secure random key for use with the ChaCha20-Poly1305 * symmetric AEAD interface. * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_chacha20poly1305_keygen() { return random_bytes(self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES); } /** * Authenticated Encryption with Associated Data * * Algorithm: * ChaCha20-Poly1305 * * IETF mode uses a 96-bit random nonce with a 32-bit counter. * Regular mode uses a 64-bit random nonce with a 64-bit counter. * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * * @return string Ciphertext with a 16-byte Poly1305 message * authentication code appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_chacha20poly1305_ietf_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); if (!is_null($assocData)) { ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES long'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_aead_chacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } if (self::use_fallback('crypto_aead_chacha20poly1305_ietf_encrypt')) { return (string) call_user_func( '\\Sodium\\crypto_aead_chacha20poly1305_ietf_encrypt', $plaintext, $assocData, $nonce, $key ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_chacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_chacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } /** * Return a secure random key for use with the ChaCha20-Poly1305 * symmetric AEAD interface. (IETF version) * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_chacha20poly1305_ietf_keygen() { return random_bytes(self::CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES); } /** * Authenticated Encryption with Associated Data: Decryption * * Algorithm: * XChaCha20-Poly1305 * * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * * @param string $ciphertext Encrypted message (with Poly1305 MAC appended) * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * @param bool $dontFallback Don't fallback to ext/sodium * * @return string|bool The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_xchacha20poly1305_ietf_decrypt( $ciphertext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '', $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); if (!is_null($assocData)) { ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); } else { $assocData = ''; } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES) { throw new SodiumException('Message must be at least CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES long'); } if (self::useNewSodiumAPI() && !$dontFallback) { if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_decrypt')) { return sodium_crypto_aead_xchacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_xchacha20poly1305_ietf_decrypt( $ciphertext, $assocData, $nonce, $key ); } /** * Authenticated Encryption with Associated Data * * Algorithm: * XChaCha20-Poly1305 * * This mode uses a 64-bit random nonce with a 64-bit counter. * IETF mode uses a 96-bit random nonce with a 32-bit counter. * * @param string $plaintext Message to be encrypted * @param string $assocData Authenticated Associated Data (unencrypted) * @param string $nonce Number to be used only Once; must be 8 bytes * @param string $key Encryption key * @param bool $dontFallback Don't fallback to ext/sodium * * @return string Ciphertext with a 16-byte Poly1305 message * authentication code appended * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_aead_xchacha20poly1305_ietf_encrypt( #[\SensitiveParameter] $plaintext = '', $assocData = '', $nonce = '', #[\SensitiveParameter] $key = '', $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); if (!is_null($assocData)) { ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2); } else { $assocData = ''; } ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) { throw new SodiumException('Nonce must be CRYPTO_AEAD_XCHACHA20POLY1305_NPUBBYTES long'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES) { throw new SodiumException('Key must be CRYPTO_AEAD_XCHACHA20POLY1305_KEYBYTES long'); } if (self::useNewSodiumAPI() && !$dontFallback) { if (is_callable('sodium_crypto_aead_xchacha20poly1305_ietf_encrypt')) { return sodium_crypto_aead_xchacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::aead_xchacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } return ParagonIE_Sodium_Crypto::aead_xchacha20poly1305_ietf_encrypt( $plaintext, $assocData, $nonce, $key ); } /** * Return a secure random key for use with the XChaCha20-Poly1305 * symmetric AEAD interface. * * @return string * @throws Exception * @throws Error */ public static function crypto_aead_xchacha20poly1305_ietf_keygen() { return random_bytes(self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES); } /** * Authenticate a message. Uses symmetric-key cryptography. * * Algorithm: * HMAC-SHA512-256. Which is HMAC-SHA-512 truncated to 256 bits. * Not to be confused with HMAC-SHA-512/256 which would use the * SHA-512/256 hash function (uses different initial parameters * but still truncates to 256 bits to sidestep length-extension * attacks). * * @param string $message Message to be authenticated * @param string $key Symmetric authentication key * @return string Message authentication code * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_auth( $message, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AUTH_KEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_AUTH_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_auth($message, $key); } if (self::use_fallback('crypto_auth')) { return (string) call_user_func('\\Sodium\\crypto_auth', $message, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::auth($message, $key); } return ParagonIE_Sodium_Crypto::auth($message, $key); } /** * @return string * @throws Exception * @throws Error */ public static function crypto_auth_keygen() { return random_bytes(self::CRYPTO_AUTH_KEYBYTES); } /** * Verify the MAC of a message previously authenticated with crypto_auth. * * @param string $mac Message authentication code * @param string $message Message whose authenticity you are attempting to * verify (with a given MAC and key) * @param string $key Symmetric authentication key * @return bool TRUE if authenticated, FALSE otherwise * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_auth_verify( $mac, $message, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($mac, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($mac) !== self::CRYPTO_AUTH_BYTES) { throw new SodiumException('Argument 1 must be CRYPTO_AUTH_BYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AUTH_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_AUTH_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return (bool) sodium_crypto_auth_verify($mac, $message, $key); } if (self::use_fallback('crypto_auth_verify')) { return (bool) call_user_func('\\Sodium\\crypto_auth_verify', $mac, $message, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::auth_verify($mac, $message, $key); } return ParagonIE_Sodium_Crypto::auth_verify($mac, $message, $key); } /** * Authenticated asymmetric-key encryption. Both the sender and recipient * may decrypt messages. * * Algorithm: X25519-XSalsa20-Poly1305. * X25519: Elliptic-Curve Diffie Hellman over Curve25519. * XSalsa20: Extended-nonce variant of salsa20. * Poyl1305: Polynomial MAC for one-time message authentication. * * @param string $plaintext The message to be encrypted * @param string $nonce A Number to only be used Once; must be 24 bytes * @param string $keypair Your secret key and your recipient's public key * @return string Ciphertext with 16-byte Poly1305 MAC * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box( $plaintext, $nonce, #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_BOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_BOX_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box($plaintext, $nonce, $keypair); } if (self::use_fallback('crypto_box')) { return (string) call_user_func('\\Sodium\\crypto_box', $plaintext, $nonce, $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box($plaintext, $nonce, $keypair); } return ParagonIE_Sodium_Crypto::box($plaintext, $nonce, $keypair); } /** * Anonymous public-key encryption. Only the recipient may decrypt messages. * * Algorithm: X25519-XSalsa20-Poly1305, as with crypto_box. * The sender's X25519 keypair is ephemeral. * Nonce is generated from the BLAKE2b hash of both public keys. * * This provides ciphertext integrity. * * @param string $plaintext Message to be sealed * @param string $publicKey Your recipient's public key * @return string Sealed message that only your recipient can * decrypt * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_seal( #[\SensitiveParameter] $plaintext, $publicKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($publicKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_seal($plaintext, $publicKey); } if (self::use_fallback('crypto_box_seal')) { return (string) call_user_func('\\Sodium\\crypto_box_seal', $plaintext, $publicKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_seal($plaintext, $publicKey); } return ParagonIE_Sodium_Crypto::box_seal($plaintext, $publicKey); } /** * Opens a message encrypted with crypto_box_seal(). Requires * the recipient's keypair (sk || pk) to decrypt successfully. * * This validates ciphertext integrity. * * @param string $ciphertext Sealed message to be opened * @param string $keypair Your crypto_box keypair * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_box_seal_open( $ciphertext, #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_box_seal_open($ciphertext, $keypair); } if (self::use_fallback('crypto_box_seal_open')) { return call_user_func('\\Sodium\\crypto_box_seal_open', $ciphertext, $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_seal_open($ciphertext, $keypair); } return ParagonIE_Sodium_Crypto::box_seal_open($ciphertext, $keypair); } /** * Generate a new random X25519 keypair. * * @return string A 64-byte string; the first 32 are your secret key, while * the last 32 are your public key. crypto_box_secretkey() * and crypto_box_publickey() exist to separate them so you * don't accidentally get them mixed up! * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_keypair() { if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_keypair(); } if (self::use_fallback('crypto_box_keypair')) { return (string) call_user_func('\\Sodium\\crypto_box_keypair'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_keypair(); } return ParagonIE_Sodium_Crypto::box_keypair(); } /** * Combine two keys into a keypair for use in library methods that expect * a keypair. This doesn't necessarily have to be the same person's keys. * * @param string $secretKey Secret key * @param string $publicKey Public key * @return string Keypair * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_keypair_from_secretkey_and_publickey( #[\SensitiveParameter] $secretKey, $publicKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($publicKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_BOX_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_keypair_from_secretkey_and_publickey($secretKey, $publicKey); } if (self::use_fallback('crypto_box_keypair_from_secretkey_and_publickey')) { return (string) call_user_func('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey', $secretKey, $publicKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_keypair_from_secretkey_and_publickey($secretKey, $publicKey); } return ParagonIE_Sodium_Crypto::box_keypair_from_secretkey_and_publickey($secretKey, $publicKey); } /** * Decrypt a message previously encrypted with crypto_box(). * * @param string $ciphertext Encrypted message * @param string $nonce Number to only be used Once; must be 24 bytes * @param string $keypair Your secret key and the sender's public key * @return string The original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_box_open( $ciphertext, $nonce, #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_BOX_MACBYTES) { throw new SodiumException('Argument 1 must be at least CRYPTO_BOX_MACBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_BOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_BOX_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_box_open($ciphertext, $nonce, $keypair); } if (self::use_fallback('crypto_box_open')) { return call_user_func('\\Sodium\\crypto_box_open', $ciphertext, $nonce, $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_open($ciphertext, $nonce, $keypair); } return ParagonIE_Sodium_Crypto::box_open($ciphertext, $nonce, $keypair); } /** * Extract the public key from a crypto_box keypair. * * @param string $keypair Keypair containing secret and public key * @return string Your crypto_box public key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_publickey( #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_publickey($keypair); } if (self::use_fallback('crypto_box_publickey')) { return (string) call_user_func('\\Sodium\\crypto_box_publickey', $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_publickey($keypair); } return ParagonIE_Sodium_Crypto::box_publickey($keypair); } /** * Calculate the X25519 public key from a given X25519 secret key. * * @param string $secretKey Any X25519 secret key * @return string The corresponding X25519 public key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_publickey_from_secretkey( #[\SensitiveParameter] $secretKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_BOX_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_publickey_from_secretkey($secretKey); } if (self::use_fallback('crypto_box_publickey_from_secretkey')) { return (string) call_user_func('\\Sodium\\crypto_box_publickey_from_secretkey', $secretKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_publickey_from_secretkey($secretKey); } return ParagonIE_Sodium_Crypto::box_publickey_from_secretkey($secretKey); } /** * Extract the secret key from a crypto_box keypair. * * @param string $keypair * @return string Your crypto_box secret key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_box_secretkey( #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_secretkey($keypair); } if (self::use_fallback('crypto_box_secretkey')) { return (string) call_user_func('\\Sodium\\crypto_box_secretkey', $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_secretkey($keypair); } return ParagonIE_Sodium_Crypto::box_secretkey($keypair); } /** * Generate an X25519 keypair from a seed. * * @param string $seed * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress UndefinedFunction */ public static function crypto_box_seed_keypair( #[\SensitiveParameter] $seed ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($seed, 'string', 1); if (self::useNewSodiumAPI()) { return (string) sodium_crypto_box_seed_keypair($seed); } if (self::use_fallback('crypto_box_seed_keypair')) { return (string) call_user_func('\\Sodium\\crypto_box_seed_keypair', $seed); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::box_seed_keypair($seed); } return ParagonIE_Sodium_Crypto::box_seed_keypair($seed); } /** * Calculates a BLAKE2b hash, with an optional key. * * @param string $message The message to be hashed * @param string|null $key If specified, must be a string between 16 * and 64 bytes long * @param int $length Output length in bytes; must be between 16 * and 64 (default = 32) * @return string Raw binary * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_generichash( $message, #[\SensitiveParameter] $key = '', $length = self::CRYPTO_GENERICHASH_BYTES ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); if (is_null($key)) { $key = ''; } ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 3); /* Input validation: */ if (!empty($key)) { if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) { throw new SodiumException('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) { throw new SodiumException('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.'); } } if (self::useNewSodiumAPI()) { return (string) sodium_crypto_generichash($message, $key, $length); } if (self::use_fallback('crypto_generichash')) { return (string) call_user_func('\\Sodium\\crypto_generichash', $message, $key, $length); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::generichash($message, $key, $length); } return ParagonIE_Sodium_Crypto::generichash($message, $key, $length); } /** * Get the final BLAKE2b hash output for a given context. * * @param string $ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). * @param int $length Hash output size. * @return string Final BLAKE2b hash. * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress ReferenceConstraintViolation * @psalm-suppress ConflictingReferenceConstraint */ public static function crypto_generichash_final( #[\SensitiveParameter] &$ctx, $length = self::CRYPTO_GENERICHASH_BYTES ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ctx, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 2); if (self::useNewSodiumAPI()) { return sodium_crypto_generichash_final($ctx, $length); } if (self::use_fallback('crypto_generichash_final')) { $func = '\\Sodium\\crypto_generichash_final'; return (string) $func($ctx, $length); } if ($length < 1) { try { self::memzero($ctx); } catch (SodiumException $ex) { unset($ctx); } return ''; } if (PHP_INT_SIZE === 4) { $result = ParagonIE_Sodium_Crypto32::generichash_final($ctx, $length); } else { $result = ParagonIE_Sodium_Crypto::generichash_final($ctx, $length); } try { self::memzero($ctx); } catch (SodiumException $ex) { unset($ctx); } return $result; } /** * Initialize a BLAKE2b hashing context, for use in a streaming interface. * * @param string|null $key If specified must be a string between 16 and 64 bytes * @param int $length The size of the desired hash output * @return string A BLAKE2 hashing context, encoded as a string * (To be 100% compatible with ext/libsodium) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_generichash_init( #[\SensitiveParameter] $key = '', $length = self::CRYPTO_GENERICHASH_BYTES ) { /* Type checks: */ if (is_null($key)) { $key = ''; } ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 2); /* Input validation: */ if (!empty($key)) { if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) { throw new SodiumException('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) { throw new SodiumException('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.'); } } if (self::useNewSodiumAPI()) { return sodium_crypto_generichash_init($key, $length); } if (self::use_fallback('crypto_generichash_init')) { return (string) call_user_func('\\Sodium\\crypto_generichash_init', $key, $length); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::generichash_init($key, $length); } return ParagonIE_Sodium_Crypto::generichash_init($key, $length); } /** * Initialize a BLAKE2b hashing context, for use in a streaming interface. * * @param string|null $key If specified must be a string between 16 and 64 bytes * @param int $length The size of the desired hash output * @param string $salt Salt (up to 16 bytes) * @param string $personal Personalization string (up to 16 bytes) * @return string A BLAKE2 hashing context, encoded as a string * (To be 100% compatible with ext/libsodium) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_generichash_init_salt_personal( #[\SensitiveParameter] $key = '', $length = self::CRYPTO_GENERICHASH_BYTES, $salt = '', $personal = '' ) { /* Type checks: */ if (is_null($key)) { $key = ''; } ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($length, 'int', 2); ParagonIE_Sodium_Core_Util::declareScalarType($salt, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($personal, 'string', 4); $salt = str_pad($salt, 16, "\0", STR_PAD_RIGHT); $personal = str_pad($personal, 16, "\0", STR_PAD_RIGHT); /* Input validation: */ if (!empty($key)) { /* if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) { throw new SodiumException('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.'); } */ if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) { throw new SodiumException('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.'); } } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::generichash_init_salt_personal($key, $length, $salt, $personal); } return ParagonIE_Sodium_Crypto::generichash_init_salt_personal($key, $length, $salt, $personal); } /** * Update a BLAKE2b hashing context with additional data. * * @param string $ctx BLAKE2 hashing context. Generated by crypto_generichash_init(). * $ctx is passed by reference and gets updated in-place. * @param-out string $ctx * @param string $message The message to append to the existing hash state. * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress ReferenceConstraintViolation */ public static function crypto_generichash_update( #[\SensitiveParameter] &$ctx, $message ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ctx, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 2); if (self::useNewSodiumAPI()) { sodium_crypto_generichash_update($ctx, $message); return; } if (self::use_fallback('crypto_generichash_update')) { $func = '\\Sodium\\crypto_generichash_update'; $func($ctx, $message); return; } if (PHP_INT_SIZE === 4) { $ctx = ParagonIE_Sodium_Crypto32::generichash_update($ctx, $message); } else { $ctx = ParagonIE_Sodium_Crypto::generichash_update($ctx, $message); } } /** * @return string * @throws Exception * @throws Error */ public static function crypto_generichash_keygen() { return random_bytes(self::CRYPTO_GENERICHASH_KEYBYTES); } /** * @param int $subkey_len * @param int $subkey_id * @param string $context * @param string $key * @return string * @throws SodiumException */ public static function crypto_kdf_derive_from_key( $subkey_len, $subkey_id, $context, #[\SensitiveParameter] $key ) { ParagonIE_Sodium_Core_Util::declareScalarType($subkey_len, 'int', 1); ParagonIE_Sodium_Core_Util::declareScalarType($subkey_id, 'int', 2); ParagonIE_Sodium_Core_Util::declareScalarType($context, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); $subkey_id = (int) $subkey_id; $subkey_len = (int) $subkey_len; $context = (string) $context; $key = (string) $key; if ($subkey_len < self::CRYPTO_KDF_BYTES_MIN) { throw new SodiumException('subkey cannot be smaller than SODIUM_CRYPTO_KDF_BYTES_MIN'); } if ($subkey_len > self::CRYPTO_KDF_BYTES_MAX) { throw new SodiumException('subkey cannot be larger than SODIUM_CRYPTO_KDF_BYTES_MAX'); } if ($subkey_id < 0) { throw new SodiumException('subkey_id cannot be negative'); } if (ParagonIE_Sodium_Core_Util::strlen($context) !== self::CRYPTO_KDF_CONTEXTBYTES) { throw new SodiumException('context should be SODIUM_CRYPTO_KDF_CONTEXTBYTES bytes'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_KDF_KEYBYTES) { throw new SodiumException('key should be SODIUM_CRYPTO_KDF_KEYBYTES bytes'); } $salt = ParagonIE_Sodium_Core_Util::store64_le($subkey_id); $state = self::crypto_generichash_init_salt_personal( $key, $subkey_len, $salt, $context ); return self::crypto_generichash_final($state, $subkey_len); } /** * @return string * @throws Exception * @throws Error */ public static function crypto_kdf_keygen() { return random_bytes(self::CRYPTO_KDF_KEYBYTES); } /** * Perform a key exchange, between a designated client and a server. * * Typically, you would designate one machine to be the client and the * other to be the server. The first two keys are what you'd expect for * scalarmult() below, but the latter two public keys don't swap places. * * | ALICE | BOB | * | Client | Server | * |--------------------------------|-------------------------------------| * | shared = crypto_kx( | shared = crypto_kx( | * | alice_sk, | bob_sk, | <- contextual * | bob_pk, | alice_pk, | <- contextual * | alice_pk, | alice_pk, | <----- static * | bob_pk | bob_pk | <----- static * | ) | ) | * * They are used along with the scalarmult product to generate a 256-bit * BLAKE2b hash unique to the client and server keys. * * @param string $my_secret * @param string $their_public * @param string $client_public * @param string $server_public * @param bool $dontFallback * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_kx( #[\SensitiveParameter] $my_secret, $their_public, $client_public, $server_public, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($my_secret, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($their_public, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($client_public, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($server_public, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($my_secret) !== self::CRYPTO_BOX_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($their_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($client_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($server_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI() && !$dontFallback) { if (is_callable('sodium_crypto_kx')) { return (string) sodium_crypto_kx( $my_secret, $their_public, $client_public, $server_public ); } } if (self::use_fallback('crypto_kx')) { return (string) call_user_func( '\\Sodium\\crypto_kx', $my_secret, $their_public, $client_public, $server_public ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::keyExchange( $my_secret, $their_public, $client_public, $server_public ); } return ParagonIE_Sodium_Crypto::keyExchange( $my_secret, $their_public, $client_public, $server_public ); } /** * @param string $seed * @return string * @throws SodiumException */ public static function crypto_kx_seed_keypair( #[\SensitiveParameter] $seed ) { ParagonIE_Sodium_Core_Util::declareScalarType($seed, 'string', 1); $seed = (string) $seed; if (ParagonIE_Sodium_Core_Util::strlen($seed) !== self::CRYPTO_KX_SEEDBYTES) { throw new SodiumException('seed must be SODIUM_CRYPTO_KX_SEEDBYTES bytes'); } $sk = self::crypto_generichash($seed, '', self::CRYPTO_KX_SECRETKEYBYTES); $pk = self::crypto_scalarmult_base($sk); return $sk . $pk; } /** * @return string * @throws Exception */ public static function crypto_kx_keypair() { $sk = self::randombytes_buf(self::CRYPTO_KX_SECRETKEYBYTES); $pk = self::crypto_scalarmult_base($sk); return $sk . $pk; } /** * @param string $keypair * @param string $serverPublicKey * @return array{0: string, 1: string} * @throws SodiumException */ public static function crypto_kx_client_session_keys( #[\SensitiveParameter] $keypair, $serverPublicKey ) { ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($serverPublicKey, 'string', 2); $keypair = (string) $keypair; $serverPublicKey = (string) $serverPublicKey; if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) { throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes'); } if (ParagonIE_Sodium_Core_Util::strlen($serverPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) { throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes'); } $sk = self::crypto_kx_secretkey($keypair); $pk = self::crypto_kx_publickey($keypair); $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2); self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $serverPublicKey)); self::crypto_generichash_update($h, $pk); self::crypto_generichash_update($h, $serverPublicKey); $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2); return array( ParagonIE_Sodium_Core_Util::substr( $sessionKeys, 0, self::CRYPTO_KX_SESSIONKEYBYTES ), ParagonIE_Sodium_Core_Util::substr( $sessionKeys, self::CRYPTO_KX_SESSIONKEYBYTES, self::CRYPTO_KX_SESSIONKEYBYTES ) ); } /** * @param string $keypair * @param string $clientPublicKey * @return array{0: string, 1: string} * @throws SodiumException */ public static function crypto_kx_server_session_keys( #[\SensitiveParameter] $keypair, $clientPublicKey ) { ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($clientPublicKey, 'string', 2); $keypair = (string) $keypair; $clientPublicKey = (string) $clientPublicKey; if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_KX_KEYPAIRBYTES) { throw new SodiumException('keypair should be SODIUM_CRYPTO_KX_KEYPAIRBYTES bytes'); } if (ParagonIE_Sodium_Core_Util::strlen($clientPublicKey) !== self::CRYPTO_KX_PUBLICKEYBYTES) { throw new SodiumException('public keys must be SODIUM_CRYPTO_KX_PUBLICKEYBYTES bytes'); } $sk = self::crypto_kx_secretkey($keypair); $pk = self::crypto_kx_publickey($keypair); $h = self::crypto_generichash_init(null, self::CRYPTO_KX_SESSIONKEYBYTES * 2); self::crypto_generichash_update($h, self::crypto_scalarmult($sk, $clientPublicKey)); self::crypto_generichash_update($h, $clientPublicKey); self::crypto_generichash_update($h, $pk); $sessionKeys = self::crypto_generichash_final($h, self::CRYPTO_KX_SESSIONKEYBYTES * 2); return array( ParagonIE_Sodium_Core_Util::substr( $sessionKeys, self::CRYPTO_KX_SESSIONKEYBYTES, self::CRYPTO_KX_SESSIONKEYBYTES ), ParagonIE_Sodium_Core_Util::substr( $sessionKeys, 0, self::CRYPTO_KX_SESSIONKEYBYTES ) ); } /** * @param string $kp * @return string * @throws SodiumException */ public static function crypto_kx_secretkey( #[\SensitiveParameter] $kp ) { return ParagonIE_Sodium_Core_Util::substr( $kp, 0, self::CRYPTO_KX_SECRETKEYBYTES ); } /** * @param string $kp * @return string * @throws SodiumException */ public static function crypto_kx_publickey($kp) { return ParagonIE_Sodium_Core_Util::substr( $kp, self::CRYPTO_KX_SECRETKEYBYTES, self::CRYPTO_KX_PUBLICKEYBYTES ); } /** * @param int $outlen * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @param int|null $alg * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_pwhash( $outlen, #[\SensitiveParameter] $passwd, $salt, $opslimit, $memlimit, $alg = null ) { ParagonIE_Sodium_Core_Util::declareScalarType($outlen, 'int', 1); ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($salt, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 4); ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 5); if (self::useNewSodiumAPI()) { if (!is_null($alg)) { ParagonIE_Sodium_Core_Util::declareScalarType($alg, 'int', 6); return sodium_crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit, $alg); } return sodium_crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit); } if (self::use_fallback('crypto_pwhash')) { return (string) call_user_func('\\Sodium\\crypto_pwhash', $outlen, $passwd, $salt, $opslimit, $memlimit); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Argon2i with acceptable performance in pure-PHP' ); } /** * !Exclusive to sodium_compat! * * This returns TRUE if the native crypto_pwhash API is available by libsodium. * This returns FALSE if only sodium_compat is available. * * @return bool */ public static function crypto_pwhash_is_available() { if (self::useNewSodiumAPI()) { return true; } if (self::use_fallback('crypto_pwhash')) { return true; } return false; } /** * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_pwhash_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 2); ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 3); if (self::useNewSodiumAPI()) { return sodium_crypto_pwhash_str($passwd, $opslimit, $memlimit); } if (self::use_fallback('crypto_pwhash_str')) { return (string) call_user_func('\\Sodium\\crypto_pwhash_str', $passwd, $opslimit, $memlimit); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Argon2i with acceptable performance in pure-PHP' ); } /** * Do we need to rehash this password? * * @param string $hash * @param int $opslimit * @param int $memlimit * @return bool * @throws SodiumException */ public static function crypto_pwhash_str_needs_rehash( #[\SensitiveParameter] $hash, $opslimit, $memlimit ) { ParagonIE_Sodium_Core_Util::declareScalarType($hash, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 2); ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 3); // Just grab the first 4 pieces. $pieces = explode('$', (string) $hash); $prefix = implode('$', array_slice($pieces, 0, 4)); // Rebuild the expected header. /** @var int $ops */ $ops = (int) $opslimit; /** @var int $mem */ $mem = (int) $memlimit >> 10; $encoded = self::CRYPTO_PWHASH_STRPREFIX . 'v=19$m=' . $mem . ',t=' . $ops . ',p=1'; // Do they match? If so, we don't need to rehash, so return false. return !ParagonIE_Sodium_Core_Util::hashEquals($encoded, $prefix); } /** * @param string $passwd * @param string $hash * @return bool * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_pwhash_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($hash, 'string', 2); if (self::useNewSodiumAPI()) { return (bool) sodium_crypto_pwhash_str_verify($passwd, $hash); } if (self::use_fallback('crypto_pwhash_str_verify')) { return (bool) call_user_func('\\Sodium\\crypto_pwhash_str_verify', $passwd, $hash); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Argon2i with acceptable performance in pure-PHP' ); } /** * @param int $outlen * @param string $passwd * @param string $salt * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_pwhash_scryptsalsa208sha256( $outlen, #[\SensitiveParameter] $passwd, $salt, $opslimit, $memlimit ) { ParagonIE_Sodium_Core_Util::declareScalarType($outlen, 'int', 1); ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($salt, 'string', 3); ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 4); ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 5); if (self::useNewSodiumAPI()) { return (string) sodium_crypto_pwhash_scryptsalsa208sha256( (int) $outlen, (string) $passwd, (string) $salt, (int) $opslimit, (int) $memlimit ); } if (self::use_fallback('crypto_pwhash_scryptsalsa208sha256')) { return (string) call_user_func( '\\Sodium\\crypto_pwhash_scryptsalsa208sha256', (int) $outlen, (string) $passwd, (string) $salt, (int) $opslimit, (int) $memlimit ); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Scrypt with acceptable performance in pure-PHP' ); } /** * !Exclusive to sodium_compat! * * This returns TRUE if the native crypto_pwhash API is available by libsodium. * This returns FALSE if only sodium_compat is available. * * @return bool */ public static function crypto_pwhash_scryptsalsa208sha256_is_available() { if (self::useNewSodiumAPI()) { return true; } if (self::use_fallback('crypto_pwhash_scryptsalsa208sha256')) { return true; } return false; } /** * @param string $passwd * @param int $opslimit * @param int $memlimit * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_pwhash_scryptsalsa208sha256_str( #[\SensitiveParameter] $passwd, $opslimit, $memlimit ) { ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($opslimit, 'int', 2); ParagonIE_Sodium_Core_Util::declareScalarType($memlimit, 'int', 3); if (self::useNewSodiumAPI()) { return (string) sodium_crypto_pwhash_scryptsalsa208sha256_str( (string) $passwd, (int) $opslimit, (int) $memlimit ); } if (self::use_fallback('crypto_pwhash_scryptsalsa208sha256_str')) { return (string) call_user_func( '\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str', (string) $passwd, (int) $opslimit, (int) $memlimit ); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Scrypt with acceptable performance in pure-PHP' ); } /** * @param string $passwd * @param string $hash * @return bool * @throws SodiumException * @throws TypeError */ public static function crypto_pwhash_scryptsalsa208sha256_str_verify( #[\SensitiveParameter] $passwd, #[\SensitiveParameter] $hash ) { ParagonIE_Sodium_Core_Util::declareScalarType($passwd, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($hash, 'string', 2); if (self::useNewSodiumAPI()) { return (bool) sodium_crypto_pwhash_scryptsalsa208sha256_str_verify( (string) $passwd, (string) $hash ); } if (self::use_fallback('crypto_pwhash_scryptsalsa208sha256_str_verify')) { return (bool) call_user_func( '\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify', (string) $passwd, (string) $hash ); } // This is the best we can do. throw new SodiumException( 'This is not implemented, as it is not possible to implement Scrypt with acceptable performance in pure-PHP' ); } /** * Calculate the shared secret between your secret key and your * recipient's public key. * * Algorithm: X25519 (ECDH over Curve25519) * * @param string $secretKey * @param string $publicKey * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_scalarmult( #[\SensitiveParameter] $secretKey, $publicKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($publicKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_BOX_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_BOX_PUBLICKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_scalarmult($secretKey, $publicKey); } if (self::use_fallback('crypto_scalarmult')) { return (string) call_user_func('\\Sodium\\crypto_scalarmult', $secretKey, $publicKey); } /* Output validation: Forbid all-zero keys */ if (ParagonIE_Sodium_Core_Util::hashEquals($secretKey, str_repeat("\0", self::CRYPTO_BOX_SECRETKEYBYTES))) { throw new SodiumException('Zero secret key is not allowed'); } if (ParagonIE_Sodium_Core_Util::hashEquals($publicKey, str_repeat("\0", self::CRYPTO_BOX_PUBLICKEYBYTES))) { throw new SodiumException('Zero public key is not allowed'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::scalarmult($secretKey, $publicKey); } return ParagonIE_Sodium_Crypto::scalarmult($secretKey, $publicKey); } /** * Calculate an X25519 public key from an X25519 secret key. * * @param string $secretKey * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress TooFewArguments * @psalm-suppress MixedArgument */ public static function crypto_scalarmult_base( #[\SensitiveParameter] $secretKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_BOX_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_scalarmult_base($secretKey); } if (self::use_fallback('crypto_scalarmult_base')) { return (string) call_user_func('\\Sodium\\crypto_scalarmult_base', $secretKey); } if (ParagonIE_Sodium_Core_Util::hashEquals($secretKey, str_repeat("\0", self::CRYPTO_BOX_SECRETKEYBYTES))) { throw new SodiumException('Zero secret key is not allowed'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::scalarmult_base($secretKey); } return ParagonIE_Sodium_Crypto::scalarmult_base($secretKey); } /** * Authenticated symmetric-key encryption. * * Algorithm: XSalsa20-Poly1305 * * @param string $plaintext The message you're encrypting * @param string $nonce A Number to be used Once; must be 24 bytes * @param string $key Symmetric encryption key * @return string Ciphertext with Poly1305 MAC * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_secretbox( #[\SensitiveParameter] $plaintext, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_secretbox($plaintext, $nonce, $key); } if (self::use_fallback('crypto_secretbox')) { return (string) call_user_func('\\Sodium\\crypto_secretbox', $plaintext, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretbox($plaintext, $nonce, $key); } return ParagonIE_Sodium_Crypto::secretbox($plaintext, $nonce, $key); } /** * Decrypts a message previously encrypted with crypto_secretbox(). * * @param string $ciphertext Ciphertext with Poly1305 MAC * @param string $nonce A Number to be used Once; must be 24 bytes * @param string $key Symmetric encryption key * @return string Original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_secretbox_open( $ciphertext, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_secretbox_open($ciphertext, $nonce, $key); } if (self::use_fallback('crypto_secretbox_open')) { return call_user_func('\\Sodium\\crypto_secretbox_open', $ciphertext, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretbox_open($ciphertext, $nonce, $key); } return ParagonIE_Sodium_Crypto::secretbox_open($ciphertext, $nonce, $key); } /** * Return a secure random key for use with crypto_secretbox * * @return string * @throws Exception * @throws Error */ public static function crypto_secretbox_keygen() { return random_bytes(self::CRYPTO_SECRETBOX_KEYBYTES); } /** * Authenticated symmetric-key encryption. * * Algorithm: XChaCha20-Poly1305 * * @param string $plaintext The message you're encrypting * @param string $nonce A Number to be used Once; must be 24 bytes * @param string $key Symmetric encryption key * @return string Ciphertext with Poly1305 MAC * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_secretbox_xchacha20poly1305($plaintext, $nonce, $key) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305($plaintext, $nonce, $key); } return ParagonIE_Sodium_Crypto::secretbox_xchacha20poly1305($plaintext, $nonce, $key); } /** * Decrypts a message previously encrypted with crypto_secretbox_xchacha20poly1305(). * * @param string $ciphertext Ciphertext with Poly1305 MAC * @param string $nonce A Number to be used Once; must be 24 bytes * @param string $key Symmetric encryption key * @return string Original plaintext message * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_secretbox_xchacha20poly1305_open( $ciphertext, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key); } return ParagonIE_Sodium_Crypto::secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key); } /** * @param string $key * @return array<int, string> Returns a state and a header. * @throws Exception * @throws SodiumException */ public static function crypto_secretstream_xchacha20poly1305_init_push( #[\SensitiveParameter] $key ) { if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_push($key); } return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_push($key); } /** * @param string $header * @param string $key * @return string Returns a state. * @throws Exception */ public static function crypto_secretstream_xchacha20poly1305_init_pull( $header, #[\SensitiveParameter] $key ) { if (ParagonIE_Sodium_Core_Util::strlen($header) < self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES) { throw new SodiumException( 'header size should be SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES bytes' ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_init_pull($key, $header); } return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_init_pull($key, $header); } /** * @param string $state * @param string $msg * @param string $aad * @param int $tag * @return string * @throws SodiumException */ public static function crypto_secretstream_xchacha20poly1305_push( #[\SensitiveParameter] &$state, #[\SensitiveParameter] $msg, $aad = '', $tag = 0 ) { if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_push( $state, $msg, $aad, $tag ); } return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_push( $state, $msg, $aad, $tag ); } /** * @param string $state * @param string $msg * @param string $aad * @return bool|array{0: string, 1: int} * @throws SodiumException */ public static function crypto_secretstream_xchacha20poly1305_pull( #[\SensitiveParameter] &$state, $msg, $aad = '' ) { if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_pull( $state, $msg, $aad ); } return ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_pull( $state, $msg, $aad ); } /** * @return string * @throws Exception */ public static function crypto_secretstream_xchacha20poly1305_keygen() { return random_bytes(self::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES); } /** * @param string $state * @return void * @throws SodiumException */ public static function crypto_secretstream_xchacha20poly1305_rekey( #[\SensitiveParameter] &$state ) { if (PHP_INT_SIZE === 4) { ParagonIE_Sodium_Crypto32::secretstream_xchacha20poly1305_rekey($state); } else { ParagonIE_Sodium_Crypto::secretstream_xchacha20poly1305_rekey($state); } } /** * Calculates a SipHash-2-4 hash of a message for a given key. * * @param string $message Input message * @param string $key SipHash-2-4 key * @return string Hash * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_shorthash( $message, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SHORTHASH_KEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SHORTHASH_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_shorthash($message, $key); } if (self::use_fallback('crypto_shorthash')) { return (string) call_user_func('\\Sodium\\crypto_shorthash', $message, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_SipHash::sipHash24($message, $key); } return ParagonIE_Sodium_Core_SipHash::sipHash24($message, $key); } /** * Return a secure random key for use with crypto_shorthash * * @return string * @throws Exception * @throws Error */ public static function crypto_shorthash_keygen() { return random_bytes(self::CRYPTO_SHORTHASH_KEYBYTES); } /** * Returns a signed message. You probably want crypto_sign_detached() * instead, which only returns the signature. * * Algorithm: Ed25519 (EdDSA over Curve25519) * * @param string $message Message to be signed. * @param string $secretKey Secret signing key. * @return string Signed message (signature is prefixed). * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_sign( $message, #[\SensitiveParameter] $secretKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_SIGN_SECRETKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign($message, $secretKey); } if (self::use_fallback('crypto_sign')) { return (string) call_user_func('\\Sodium\\crypto_sign', $message, $secretKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::sign($message, $secretKey); } return ParagonIE_Sodium_Crypto::sign($message, $secretKey); } /** * Validates a signed message then returns the message. * * @param string $signedMessage A signed message * @param string $publicKey A public key * @return string The original message (if the signature is * valid for this public key) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedInferredReturnType * @psalm-suppress MixedReturnStatement */ public static function crypto_sign_open( $signedMessage, $publicKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($signedMessage, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($publicKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($signedMessage) < self::CRYPTO_SIGN_BYTES) { throw new SodiumException('Argument 1 must be at least CRYPTO_SIGN_BYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SIGN_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { /** * @psalm-suppress InvalidReturnStatement * @psalm-suppress FalsableReturnStatement */ return sodium_crypto_sign_open($signedMessage, $publicKey); } if (self::use_fallback('crypto_sign_open')) { return call_user_func('\\Sodium\\crypto_sign_open', $signedMessage, $publicKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::sign_open($signedMessage, $publicKey); } return ParagonIE_Sodium_Crypto::sign_open($signedMessage, $publicKey); } /** * Generate a new random Ed25519 keypair. * * @return string * @throws SodiumException * @throws TypeError */ public static function crypto_sign_keypair() { if (self::useNewSodiumAPI()) { return sodium_crypto_sign_keypair(); } if (self::use_fallback('crypto_sign_keypair')) { return (string) call_user_func('\\Sodium\\crypto_sign_keypair'); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_Ed25519::keypair(); } return ParagonIE_Sodium_Core_Ed25519::keypair(); } /** * @param string $sk * @param string $pk * @return string * @throws SodiumException */ public static function crypto_sign_keypair_from_secretkey_and_publickey( #[\SensitiveParameter] $sk, $pk ) { ParagonIE_Sodium_Core_Util::declareScalarType($sk, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($pk, 'string', 1); $sk = (string) $sk; $pk = (string) $pk; if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) { throw new SodiumException('secretkey should be SODIUM_CRYPTO_SIGN_SECRETKEYBYTES bytes'); } if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) { throw new SodiumException('publickey should be SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES bytes'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk); } return $sk . $pk; } /** * Generate an Ed25519 keypair from a seed. * * @param string $seed Input seed * @return string Keypair * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_seed_keypair( #[\SensitiveParameter] $seed ) { ParagonIE_Sodium_Core_Util::declareScalarType($seed, 'string', 1); if (self::useNewSodiumAPI()) { return sodium_crypto_sign_seed_keypair($seed); } if (self::use_fallback('crypto_sign_keypair')) { return (string) call_user_func('\\Sodium\\crypto_sign_seed_keypair', $seed); } $publicKey = ''; $secretKey = ''; if (PHP_INT_SIZE === 4) { ParagonIE_Sodium_Core32_Ed25519::seed_keypair($publicKey, $secretKey, $seed); } else { ParagonIE_Sodium_Core_Ed25519::seed_keypair($publicKey, $secretKey, $seed); } return $secretKey . $publicKey; } /** * Extract an Ed25519 public key from an Ed25519 keypair. * * @param string $keypair Keypair * @return string Public key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_publickey( #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_SIGN_KEYPAIRBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_SIGN_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_publickey($keypair); } if (self::use_fallback('crypto_sign_publickey')) { return (string) call_user_func('\\Sodium\\crypto_sign_publickey', $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_Ed25519::publickey($keypair); } return ParagonIE_Sodium_Core_Ed25519::publickey($keypair); } /** * Calculate an Ed25519 public key from an Ed25519 secret key. * * @param string $secretKey Your Ed25519 secret key * @return string The corresponding Ed25519 public key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_publickey_from_secretkey( #[\SensitiveParameter] $secretKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_SIGN_SECRETKEYBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_SIGN_SECRETKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_publickey_from_secretkey($secretKey); } if (self::use_fallback('crypto_sign_publickey_from_secretkey')) { return (string) call_user_func('\\Sodium\\crypto_sign_publickey_from_secretkey', $secretKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_Ed25519::publickey_from_secretkey($secretKey); } return ParagonIE_Sodium_Core_Ed25519::publickey_from_secretkey($secretKey); } /** * Extract an Ed25519 secret key from an Ed25519 keypair. * * @param string $keypair Keypair * @return string Secret key * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_secretkey( #[\SensitiveParameter] $keypair ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($keypair, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_SIGN_KEYPAIRBYTES) { throw new SodiumException('Argument 1 must be CRYPTO_SIGN_KEYPAIRBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_secretkey($keypair); } if (self::use_fallback('crypto_sign_secretkey')) { return (string) call_user_func('\\Sodium\\crypto_sign_secretkey', $keypair); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_Ed25519::secretkey($keypair); } return ParagonIE_Sodium_Core_Ed25519::secretkey($keypair); } /** * Calculate the Ed25519 signature of a message and return ONLY the signature. * * Algorithm: Ed25519 (EdDSA over Curve25519) * * @param string $message Message to be signed * @param string $secretKey Secret signing key * @return string Digital signature * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_detached( $message, #[\SensitiveParameter] $secretKey ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($secretKey, 'string', 2); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($secretKey) !== self::CRYPTO_SIGN_SECRETKEYBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_detached($message, $secretKey); } if (self::use_fallback('crypto_sign_detached')) { return (string) call_user_func('\\Sodium\\crypto_sign_detached', $message, $secretKey); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::sign_detached($message, $secretKey); } return ParagonIE_Sodium_Crypto::sign_detached($message, $secretKey); } /** * Verify the Ed25519 signature of a message. * * @param string $signature Digital sginature * @param string $message Message to be verified * @param string $publicKey Public key * @return bool TRUE if this signature is good for this public key; * FALSE otherwise * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_verify_detached($signature, $message, $publicKey) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($signature, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($publicKey, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($signature) !== self::CRYPTO_SIGN_BYTES) { throw new SodiumException('Argument 1 must be CRYPTO_SIGN_BYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_sign_verify_detached($signature, $message, $publicKey); } if (self::use_fallback('crypto_sign_verify_detached')) { return (bool) call_user_func( '\\Sodium\\crypto_sign_verify_detached', $signature, $message, $publicKey ); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Crypto32::sign_verify_detached($signature, $message, $publicKey); } return ParagonIE_Sodium_Crypto::sign_verify_detached($signature, $message, $publicKey); } /** * Convert an Ed25519 public key to a Curve25519 public key * * @param string $pk * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_ed25519_pk_to_curve25519($pk) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($pk, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($pk) < self::CRYPTO_SIGN_PUBLICKEYBYTES) { throw new SodiumException('Argument 1 must be at least CRYPTO_SIGN_PUBLICKEYBYTES long.'); } if (self::useNewSodiumAPI()) { if (is_callable('crypto_sign_ed25519_pk_to_curve25519')) { return (string) sodium_crypto_sign_ed25519_pk_to_curve25519($pk); } } if (self::use_fallback('crypto_sign_ed25519_pk_to_curve25519')) { return (string) call_user_func('\\Sodium\\crypto_sign_ed25519_pk_to_curve25519', $pk); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_Ed25519::pk_to_curve25519($pk); } return ParagonIE_Sodium_Core_Ed25519::pk_to_curve25519($pk); } /** * Convert an Ed25519 secret key to a Curve25519 secret key * * @param string $sk * @return string * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_sign_ed25519_sk_to_curve25519( #[\SensitiveParameter] $sk ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($sk, 'string', 1); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($sk) < self::CRYPTO_SIGN_SEEDBYTES) { throw new SodiumException('Argument 1 must be at least CRYPTO_SIGN_SEEDBYTES long.'); } if (self::useNewSodiumAPI()) { if (is_callable('crypto_sign_ed25519_sk_to_curve25519')) { return sodium_crypto_sign_ed25519_sk_to_curve25519($sk); } } if (self::use_fallback('crypto_sign_ed25519_sk_to_curve25519')) { return (string) call_user_func('\\Sodium\\crypto_sign_ed25519_sk_to_curve25519', $sk); } $h = hash('sha512', ParagonIE_Sodium_Core_Util::substr($sk, 0, 32), true); $h[0] = ParagonIE_Sodium_Core_Util::intToChr( ParagonIE_Sodium_Core_Util::chrToInt($h[0]) & 248 ); $h[31] = ParagonIE_Sodium_Core_Util::intToChr( (ParagonIE_Sodium_Core_Util::chrToInt($h[31]) & 127) | 64 ); return ParagonIE_Sodium_Core_Util::substr($h, 0, 32); } /** * Expand a key and nonce into a keystream of pseudorandom bytes. * * @param int $len Number of bytes desired * @param string $nonce Number to be used Once; must be 24 bytes * @param string $key XSalsa20 key * @return string Pseudorandom stream that can be XORed with messages * to provide encryption (but not authentication; see * Poly1305 or crypto_auth() for that, which is not * optional for security) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_stream( $len, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($len, 'int', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_STREAM_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_stream($len, $nonce, $key); } if (self::use_fallback('crypto_stream')) { return (string) call_user_func('\\Sodium\\crypto_stream', $len, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_XSalsa20::xsalsa20($len, $nonce, $key); } return ParagonIE_Sodium_Core_XSalsa20::xsalsa20($len, $nonce, $key); } /** * DANGER! UNAUTHENTICATED ENCRYPTION! * * Unless you are following expert advice, do not use this feature. * * Algorithm: XSalsa20 * * This DOES NOT provide ciphertext integrity. * * @param string $message Plaintext message * @param string $nonce Number to be used Once; must be 24 bytes * @param string $key Encryption key * @return string Encrypted text which is vulnerable to chosen- * ciphertext attacks unless you implement some * other mitigation to the ciphertext (i.e. * Encrypt then MAC) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_stream_xor( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.'); } if (self::useNewSodiumAPI()) { return sodium_crypto_stream_xor($message, $nonce, $key); } if (self::use_fallback('crypto_stream_xor')) { return (string) call_user_func('\\Sodium\\crypto_stream_xor', $message, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_XSalsa20::xsalsa20_xor($message, $nonce, $key); } return ParagonIE_Sodium_Core_XSalsa20::xsalsa20_xor($message, $nonce, $key); } /** * Return a secure random key for use with crypto_stream * * @return string * @throws Exception * @throws Error */ public static function crypto_stream_keygen() { return random_bytes(self::CRYPTO_STREAM_KEYBYTES); } /** * Expand a key and nonce into a keystream of pseudorandom bytes. * * @param int $len Number of bytes desired * @param string $nonce Number to be used Once; must be 24 bytes * @param string $key XChaCha20 key * @param bool $dontFallback * @return string Pseudorandom stream that can be XORed with messages * to provide encryption (but not authentication; see * Poly1305 or crypto_auth() for that, which is not * optional for security) * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_stream_xchacha20( $len, $nonce, #[\SensitiveParameter] $key, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($len, 'int', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_STREAM_XCHACHA20_KEYBYTES long.'); } if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_stream_xchacha20($len, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_XChaCha20::stream($len, $nonce, $key); } return ParagonIE_Sodium_Core_XChaCha20::stream($len, $nonce, $key); } /** * DANGER! UNAUTHENTICATED ENCRYPTION! * * Unless you are following expert advice, do not use this feature. * * Algorithm: XChaCha20 * * This DOES NOT provide ciphertext integrity. * * @param string $message Plaintext message * @param string $nonce Number to be used Once; must be 24 bytes * @param string $key Encryption key * @return string Encrypted text which is vulnerable to chosen- * ciphertext attacks unless you implement some * other mitigation to the ciphertext (i.e. * Encrypt then MAC) * @param bool $dontFallback * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_stream_xchacha20_xor( #[\SensitiveParameter] $message, $nonce, #[\SensitiveParameter] $key, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_XCHACHA20_KEYBYTES long.'); } if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_stream_xchacha20_xor($message, $nonce, $key); } if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_XChaCha20::streamXorIc($message, $nonce, $key); } return ParagonIE_Sodium_Core_XChaCha20::streamXorIc($message, $nonce, $key); } /** * DANGER! UNAUTHENTICATED ENCRYPTION! * * Unless you are following expert advice, do not use this feature. * * Algorithm: XChaCha20 * * This DOES NOT provide ciphertext integrity. * * @param string $message Plaintext message * @param string $nonce Number to be used Once; must be 24 bytes * @param int $counter * @param string $key Encryption key * @return string Encrypted text which is vulnerable to chosen- * ciphertext attacks unless you implement some * other mitigation to the ciphertext (i.e. * Encrypt then MAC) * @param bool $dontFallback * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function crypto_stream_xchacha20_xor_ic( #[\SensitiveParameter] $message, $nonce, $counter, #[\SensitiveParameter] $key, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2); ParagonIE_Sodium_Core_Util::declareScalarType($counter, 'int', 3); ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4); /* Input validation: */ if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) { throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.'); } if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) { throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_XCHACHA20_KEYBYTES long.'); } if (is_callable('sodium_crypto_stream_xchacha20_xor_ic') && !$dontFallback) { return sodium_crypto_stream_xchacha20_xor_ic($message, $nonce, $counter, $key); } $ic = ParagonIE_Sodium_Core_Util::store64_le($counter); if (PHP_INT_SIZE === 4) { return ParagonIE_Sodium_Core32_XChaCha20::streamXorIc($message, $nonce, $key, $ic); } return ParagonIE_Sodium_Core_XChaCha20::streamXorIc($message, $nonce, $key, $ic); } /** * Return a secure random key for use with crypto_stream_xchacha20 * * @return string * @throws Exception * @throws Error */ public static function crypto_stream_xchacha20_keygen() { return random_bytes(self::CRYPTO_STREAM_XCHACHA20_KEYBYTES); } /** * Cache-timing-safe implementation of hex2bin(). * * @param string $string Hexadecimal string * @param string $ignore List of characters to ignore; useful for whitespace * @return string Raw binary string * @throws SodiumException * @throws TypeError * @psalm-suppress TooFewArguments * @psalm-suppress MixedArgument */ public static function hex2bin( #[\SensitiveParameter] $string, $ignore = '' ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($string, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($ignore, 'string', 2); if (self::useNewSodiumAPI()) { if (is_callable('sodium_hex2bin')) { return (string) sodium_hex2bin($string, $ignore); } } if (self::use_fallback('hex2bin')) { return (string) call_user_func('\\Sodium\\hex2bin', $string, $ignore); } return ParagonIE_Sodium_Core_Util::hex2bin($string, $ignore); } /** * Increase a string (little endian) * * @param string $var * * @return void * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function increment( #[\SensitiveParameter] &$var ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($var, 'string', 1); if (self::useNewSodiumAPI()) { sodium_increment($var); return; } if (self::use_fallback('increment')) { $func = '\\Sodium\\increment'; $func($var); return; } $len = ParagonIE_Sodium_Core_Util::strlen($var); $c = 1; $copy = ''; for ($i = 0; $i < $len; ++$i) { $c += ParagonIE_Sodium_Core_Util::chrToInt( ParagonIE_Sodium_Core_Util::substr($var, $i, 1) ); $copy .= ParagonIE_Sodium_Core_Util::intToChr($c); $c >>= 8; } $var = $copy; } /** * @param string $str * @return bool * * @throws SodiumException */ public static function is_zero( #[\SensitiveParameter] $str ) { $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= ParagonIE_Sodium_Core_Util::chrToInt($str[$i]); } return ((($d - 1) >> 31) & 1) === 1; } /** * The equivalent to the libsodium minor version we aim to be compatible * with (sans pwhash and memzero). * * @return int */ public static function library_version_major() { if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MAJOR_VERSION')) { return SODIUM_LIBRARY_MAJOR_VERSION; } if (self::use_fallback('library_version_major')) { /** @psalm-suppress UndefinedFunction */ return (int) call_user_func('\\Sodium\\library_version_major'); } return self::LIBRARY_VERSION_MAJOR; } /** * The equivalent to the libsodium minor version we aim to be compatible * with (sans pwhash and memzero). * * @return int */ public static function library_version_minor() { if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MINOR_VERSION')) { return SODIUM_LIBRARY_MINOR_VERSION; } if (self::use_fallback('library_version_minor')) { /** @psalm-suppress UndefinedFunction */ return (int) call_user_func('\\Sodium\\library_version_minor'); } return self::LIBRARY_VERSION_MINOR; } /** * Compare two strings. * * @param string $left * @param string $right * @return int * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument */ public static function memcmp( #[\SensitiveParameter] $left, #[\SensitiveParameter] $right ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($left, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($right, 'string', 2); if (self::useNewSodiumAPI()) { return sodium_memcmp($left, $right); } if (self::use_fallback('memcmp')) { return (int) call_user_func('\\Sodium\\memcmp', $left, $right); } /** @var string $left */ /** @var string $right */ return ParagonIE_Sodium_Core_Util::memcmp($left, $right); } /** * It's actually not possible to zero memory buffers in PHP. You need the * native library for that. * * @param string|null $var * @param-out string|null $var * * @return void * @throws SodiumException (Unless libsodium is installed) * @throws TypeError * @psalm-suppress TooFewArguments */ public static function memzero( #[\SensitiveParameter] &$var ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($var, 'string', 1); if (self::useNewSodiumAPI()) { /** @psalm-suppress MixedArgument */ sodium_memzero($var); return; } if (self::use_fallback('memzero')) { $func = '\\Sodium\\memzero'; $func($var); if ($var === null) { return; } } // This is the best we can do. throw new SodiumException( 'This is not implemented in sodium_compat, as it is not possible to securely wipe memory from PHP. ' . 'To fix this error, make sure libsodium is installed and the PHP extension is enabled.' ); } /** * @param string $unpadded * @param int $blockSize * @param bool $dontFallback * @return string * @throws SodiumException */ public static function pad( #[\SensitiveParameter] $unpadded, $blockSize, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($unpadded, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2); $unpadded = (string) $unpadded; $blockSize = (int) $blockSize; if (self::useNewSodiumAPI() && !$dontFallback) { return (string) sodium_pad($unpadded, $blockSize); } if ($blockSize <= 0) { throw new SodiumException( 'block size cannot be less than 1' ); } $unpadded_len = ParagonIE_Sodium_Core_Util::strlen($unpadded); $xpadlen = ($blockSize - 1); if (($blockSize & ($blockSize - 1)) === 0) { $xpadlen -= $unpadded_len & ($blockSize - 1); } else { $xpadlen -= $unpadded_len % $blockSize; } $xpadded_len = $unpadded_len + $xpadlen; $padded = str_repeat("\0", $xpadded_len - 1); if ($unpadded_len > 0) { $st = 1; $i = 0; $k = $unpadded_len; for ($j = 0; $j <= $xpadded_len; ++$j) { $i = (int) $i; $k = (int) $k; $st = (int) $st; if ($j >= $unpadded_len) { $padded[$j] = "\0"; } else { $padded[$j] = $unpadded[$j]; } /** @var int $k */ $k -= $st; $st = (int) (~( ( ( ($k >> 48) | ($k >> 32) | ($k >> 16) | $k ) - 1 ) >> 16 ) ) & 1; $i += $st; } } $mask = 0; $tail = $xpadded_len; for ($i = 0; $i < $blockSize; ++$i) { # barrier_mask = (unsigned char) # (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT)); $barrier_mask = (($i ^ $xpadlen) -1) >> ((PHP_INT_SIZE << 3) - 1); # tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask); $padded[$tail - $i] = ParagonIE_Sodium_Core_Util::intToChr( (ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]) & $mask) | (0x80 & $barrier_mask) ); # mask |= barrier_mask; $mask |= $barrier_mask; } return $padded; } /** * @param string $padded * @param int $blockSize * @param bool $dontFallback * @return string * @throws SodiumException */ public static function unpad( #[\SensitiveParameter] $padded, $blockSize, $dontFallback = false ) { /* Type checks: */ ParagonIE_Sodium_Core_Util::declareScalarType($padded, 'string', 1); ParagonIE_Sodium_Core_Util::declareScalarType($blockSize, 'int', 2); $padded = (string) $padded; $blockSize = (int) $blockSize; if (self::useNewSodiumAPI() && !$dontFallback) { return (string) sodium_unpad($padded, $blockSize); } if ($blockSize <= 0) { throw new SodiumException('block size cannot be less than 1'); } $padded_len = ParagonIE_Sodium_Core_Util::strlen($padded); if ($padded_len < $blockSize) { throw new SodiumException('invalid padding'); } # tail = &padded[padded_len - 1U]; $tail = $padded_len - 1; $acc = 0; $valid = 0; $pad_len = 0; $found = 0; for ($i = 0; $i < $blockSize; ++$i) { # c = tail[-i]; $c = ParagonIE_Sodium_Core_Util::chrToInt($padded[$tail - $i]); # is_barrier = # (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U; $is_barrier = ( ( ($acc - 1) & ($pad_len - 1) & (($c ^ 80) - 1) ) >> 7 ) & 1; $is_barrier &= ~$found; $found |= $is_barrier; # acc |= c; $acc |= $c; # pad_len |= i & (1U + ~is_barrier); $pad_len |= $i & (1 + ~$is_barrier); # valid |= (unsigned char) is_barrier; $valid |= ($is_barrier & 0xff); } # unpadded_len = padded_len - 1U - pad_len; $unpadded_len = $padded_len - 1 - $pad_len; if ($valid !== 1) { throw new SodiumException('invalid padding'); } return ParagonIE_Sodium_Core_Util::substr($padded, 0, $unpadded_len); } /** * Will sodium_compat run fast on the current hardware and PHP configuration? * * @return bool */ public static function polyfill_is_fast() { if (extension_loaded('sodium')) { return true; } if (extension_loaded('libsodium')) { return true; } return PHP_INT_SIZE === 8; } /** * Generate a string of bytes from the kernel's CSPRNG. * Proudly uses /dev/urandom (if getrandom(2) is not available). * * @param int $numBytes * @return string * @throws Exception * @throws TypeError */ public static function randombytes_buf($numBytes) { /* Type checks: */ if (!is_int($numBytes)) { if (is_numeric($numBytes)) { $numBytes = (int) $numBytes; } else { throw new TypeError( 'Argument 1 must be an integer, ' . gettype($numBytes) . ' given.' ); } } /** @var positive-int $numBytes */ if (self::use_fallback('randombytes_buf')) { return (string) call_user_func('\\Sodium\\randombytes_buf', $numBytes); } if ($numBytes < 0) { throw new SodiumException("Number of bytes must be a positive integer"); } return random_bytes($numBytes); } /** * Generate an integer between 0 and $range (non-inclusive). * * @param int $range * @return int * @throws Exception * @throws Error * @throws TypeError */ public static function randombytes_uniform($range) { /* Type checks: */ if (!is_int($range)) { if (is_numeric($range)) { $range = (int) $range; } else { throw new TypeError( 'Argument 1 must be an integer, ' . gettype($range) . ' given.' ); } } if (self::use_fallback('randombytes_uniform')) { return (int) call_user_func('\\Sodium\\randombytes_uniform', $range); } return random_int(0, $range - 1); } /** * Generate a random 16-bit integer. * * @return int * @throws Exception * @throws Error * @throws TypeError */ public static function randombytes_random16() { if (self::use_fallback('randombytes_random16')) { return (int) call_user_func('\\Sodium\\randombytes_random16'); } return random_int(0, 65535); } /** * @param string $p * @param bool $dontFallback * @return bool * @throws SodiumException */ public static function ristretto255_is_valid_point( #[\SensitiveParameter] $p, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_is_valid_point($p); } try { $r = ParagonIE_Sodium_Core_Ristretto255::ristretto255_frombytes($p); return $r['res'] === 0 && ParagonIE_Sodium_Core_Ristretto255::ristretto255_point_is_canonical($p) === 1; } catch (SodiumException $ex) { if ($ex->getMessage() === 'S is not canonical') { return false; } throw $ex; } } /** * @param string $p * @param string $q * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_add( #[\SensitiveParameter] $p, #[\SensitiveParameter] $q, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_add($p, $q); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_add($p, $q); } /** * @param string $p * @param string $q * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_sub( #[\SensitiveParameter] $p, #[\SensitiveParameter] $q, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_sub($p, $q); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_sub($p, $q); } /** * @param string $r * @param bool $dontFallback * @return string * * @throws SodiumException */ public static function ristretto255_from_hash( #[\SensitiveParameter] $r, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_from_hash($r); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_from_hash($r); } /** * @param bool $dontFallback * @return string * * @throws SodiumException */ public static function ristretto255_random($dontFallback = false) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_random(); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_random(); } /** * @param bool $dontFallback * @return string * * @throws SodiumException */ public static function ristretto255_scalar_random($dontFallback = false) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_random(); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_random(); } /** * @param string $s * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_invert( #[\SensitiveParameter] $s, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_invert($s); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_invert($s); } /** * @param string $s * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_negate( #[\SensitiveParameter] $s, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_negate($s); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_negate($s); } /** * @param string $s * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_complement( #[\SensitiveParameter] $s, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_complement($s); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_complement($s); } /** * @param string $x * @param string $y * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_add( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_add($x, $y); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_add($x, $y); } /** * @param string $x * @param string $y * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_sub( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_sub($x, $y); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_sub($x, $y); } /** * @param string $x * @param string $y * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_mul( #[\SensitiveParameter] $x, #[\SensitiveParameter] $y, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_mul($x, $y); } return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_mul($x, $y); } /** * @param string $n * @param string $p * @param bool $dontFallback * @return string * @throws SodiumException */ public static function scalarmult_ristretto255( #[\SensitiveParameter] $n, #[\SensitiveParameter] $p, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_scalarmult_ristretto255($n, $p); } return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255($n, $p); } /** * @param string $n * @param string $p * @param bool $dontFallback * @return string * @throws SodiumException */ public static function scalarmult_ristretto255_base( #[\SensitiveParameter] $n, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_scalarmult_ristretto255_base($n); } return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255_base($n); } /** * @param string $s * @param bool $dontFallback * @return string * @throws SodiumException */ public static function ristretto255_scalar_reduce( #[\SensitiveParameter] $s, $dontFallback = false ) { if (self::useNewSodiumAPI() && !$dontFallback) { return sodium_crypto_core_ristretto255_scalar_reduce($s); } return ParagonIE_Sodium_Core_Ristretto255::sc_reduce($s); } /** * Runtime testing method for 32-bit platforms. * * Usage: If runtime_speed_test() returns FALSE, then our 32-bit * implementation is to slow to use safely without risking timeouts. * If this happens, install sodium from PECL to get acceptable * performance. * * @param int $iterations Number of multiplications to attempt * @param int $maxTimeout Milliseconds * @return bool TRUE if we're fast enough, FALSE is not * @throws SodiumException */ public static function runtime_speed_test($iterations, $maxTimeout) { if (self::polyfill_is_fast()) { return true; } /** @var float $end */ $end = 0.0; /** @var float $start */ $start = microtime(true); /** @var ParagonIE_Sodium_Core32_Int64 $a */ $a = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16)); for ($i = 0; $i < $iterations; ++$i) { /** @var ParagonIE_Sodium_Core32_Int64 $b */ $b = ParagonIE_Sodium_Core32_Int64::fromInt(random_int(3, 1 << 16)); $a->mulInt64($b); } /** @var float $end */ $end = microtime(true); /** @var int $diff */ $diff = (int) ceil(($end - $start) * 1000); return $diff < $maxTimeout; } /** * Add two numbers (little-endian unsigned), storing the value in the first * parameter. * * This mutates $val. * * @param string $val * @param string $addv * @return void * @throws SodiumException */ public static function sub( #[\SensitiveParameter] &$val, #[\SensitiveParameter] $addv ) { $val_len = ParagonIE_Sodium_Core_Util::strlen($val); $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv); if ($val_len !== $addv_len) { throw new SodiumException('values must have the same length'); } $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val); $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv); $c = 0; for ($i = 0; $i < $val_len; $i++) { $c = ($A[$i] - $B[$i] - $c); $A[$i] = ($c & 0xff); $c = ($c >> 8) & 1; } $val = ParagonIE_Sodium_Core_Util::intArrayToString($A); } /** * This emulates libsodium's version_string() function, except ours is * prefixed with 'polyfill-'. * * @return string * @psalm-suppress MixedInferredReturnType * @psalm-suppress UndefinedFunction */ public static function version_string() { if (self::useNewSodiumAPI()) { return (string) sodium_version_string(); } if (self::use_fallback('version_string')) { return (string) call_user_func('\\Sodium\\version_string'); } return (string) self::VERSION_STRING; } /** * Should we use the libsodium core function instead? * This is always a good idea, if it's available. (Unless we're in the * middle of running our unit test suite.) * * If ext/libsodium is available, use it. Return TRUE. * Otherwise, we have to use the code provided herein. Return FALSE. * * @param string $sodium_func_name * * @return bool */ protected static function use_fallback($sodium_func_name = '') { static $res = null; if ($res === null) { $res = extension_loaded('libsodium') && PHP_VERSION_ID >= 50300; } if ($res === false) { // No libsodium installed return false; } if (self::$disableFallbackForUnitTests) { // Don't fallback. Use the PHP implementation. return false; } if (!empty($sodium_func_name)) { return is_callable('\\Sodium\\' . $sodium_func_name); } return true; } /** * Libsodium as implemented in PHP 7.2 * and/or ext/sodium (via PECL) * * @ref https://wiki.php.net/rfc/libsodium * @return bool */ protected static function useNewSodiumAPI() { static $res = null; if ($res === null) { $res = PHP_VERSION_ID >= 70000 && extension_loaded('sodium'); } if (self::$disableFallbackForUnitTests) { // Don't fallback. Use the PHP implementation. return false; } return (bool) $res; } } <?php if (class_exists('ParagonIE_Sodium_Crypto32', false)) { return; } /** * Class ParagonIE_Sodium_Crypto * * ATTENTION! * * If you are using this library, you should be using * ParagonIE_Sodium_Compat in your code, not this class. */ abstract class ParagonIE_Sodium_Crypto32 { const aead_chacha20poly1305_KEYBYTES = 32; const aead_chacha20poly1305_NSECBYTES = 0; const aead_chacha20poly1305_NPUBBYTES = 8; const aead_chacha20poly1305_ABYTES = 16; const aead_chacha20poly1305_IETF_KEYBYTES = 32; const aead_chacha20poly1305_IETF_NSECBYTES = 0; const aead_chacha20poly1305_IETF_NPUBBYTES = 12; const aead_chacha20poly1305_IETF_ABYTES = 16; const aead_xchacha20poly1305_IETF_KEYBYTES = 32; const aead_xchacha20poly1305_IETF_NSECBYTES = 0; const aead_xchacha20poly1305_IETF_NPUBBYTES = 24; const aead_xchacha20poly1305_IETF_ABYTES = 16; const box_curve25519xsalsa20poly1305_SEEDBYTES = 32; const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; const box_curve25519xsalsa20poly1305_NONCEBYTES = 24; const box_curve25519xsalsa20poly1305_MACBYTES = 16; const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; const box_curve25519xsalsa20poly1305_ZEROBYTES = 32; const onetimeauth_poly1305_BYTES = 16; const onetimeauth_poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_KEYBYTES = 32; const secretbox_xsalsa20poly1305_NONCEBYTES = 24; const secretbox_xsalsa20poly1305_MACBYTES = 16; const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; const secretbox_xsalsa20poly1305_ZEROBYTES = 32; const secretbox_xchacha20poly1305_KEYBYTES = 32; const secretbox_xchacha20poly1305_NONCEBYTES = 24; const secretbox_xchacha20poly1305_MACBYTES = 16; const secretbox_xchacha20poly1305_BOXZEROBYTES = 16; const secretbox_xchacha20poly1305_ZEROBYTES = 32; const stream_salsa20_KEYBYTES = 32; /** * AEAD Decryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_ABYTES; /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core32_Util::substr( $message, $clen, self::aead_chacha20poly1305_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 0, $clen); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 32, $nonce, $key ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); $state->update($ad); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update($ciphertext); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $adlen - Length of associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var int $len - Length of message (ciphertext + MAC) */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $clen - Length of ciphertext */ $clen = $len - self::aead_chacha20poly1305_IETF_ABYTES; /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream( 32, $nonce, $key ); /** @var string $mac - Message authentication code */ $mac = ParagonIE_Sodium_Core32_Util::substr( $message, $len - self::aead_chacha20poly1305_IETF_ABYTES, self::aead_chacha20poly1305_IETF_ABYTES ); /** @var string $ciphertext - The encrypted message (sans MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr( $message, 0, $len - self::aead_chacha20poly1305_IETF_ABYTES ); /* Recalculate the Poly1305 authentication tag (MAC): */ $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", (0x10 - $clen) & 0xf)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($clen)); $computed_mac = $state->finish(); /* Compare the given MAC with the recalculated MAC: */ if (!ParagonIE_Sodium_Core32_Util::verify_16($computed_mac, $mac)) { throw new SodiumException('Invalid MAC'); } // Here, we know that the MAC is valid, so we decrypt and return the plaintext return ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $ciphertext, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_chacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { /** @var int $len - Length of the plaintext message */ $len = ParagonIE_Sodium_Core32_Util::strlen($message); /** @var int $adlen - Length of the associated data */ $adlen = ParagonIE_Sodium_Core32_Util::strlen($ad); /** @var string The first block of the chacha20 keystream, used as a poly1305 key */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::ietfStream( 32, $nonce, $key ); $state = new ParagonIE_Sodium_Core32_Poly1305_State($block0); try { ParagonIE_Sodium_Compat::memzero($block0); } catch (SodiumException $ex) { $block0 = null; } /** @var string $ciphertext - Raw encrypted data */ $ciphertext = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $message, $nonce, $key, ParagonIE_Sodium_Core32_Util::store64_le(1) ); $state->update($ad); $state->update(str_repeat("\x00", ((0x10 - $adlen) & 0xf))); $state->update($ciphertext); $state->update(str_repeat("\x00", ((0x10 - $len) & 0xf))); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($adlen)); $state->update(ParagonIE_Sodium_Core32_Util::store64_le($len)); return $ciphertext . $state->finish(); } /** * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_decrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_decrypt($message, $ad, $nonceLast, $subkey); } /** * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $ad * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function aead_xchacha20poly1305_ietf_encrypt( $message = '', $ad = '', $nonce = '', $key = '' ) { $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = "\x00\x00\x00\x00" . ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); return self::aead_chacha20poly1305_ietf_encrypt($message, $ad, $nonceLast, $subkey); } /** * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $key * @return string * @throws TypeError */ public static function auth($message, $key) { return ParagonIE_Sodium_Core32_Util::substr( hash_hmac('sha512', $message, $key, true), 0, 32 ); } /** * HMAC-SHA-512-256 validation. Constant-time via hash_equals(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $mac * @param string $message * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function auth_verify($mac, $message, $key) { return ParagonIE_Sodium_Core32_Util::hashEquals( $mac, self::auth($message, $key) ); } /** * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box($plaintext, $nonce, $keypair) { return self::secretbox( $plaintext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $publicKey * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal($message, $publicKey) { /** @var string $ephemeralKeypair */ $ephemeralKeypair = self::box_keypair(); /** @var string $ephemeralSK */ $ephemeralSK = self::box_secretkey($ephemeralKeypair); /** @var string $ephemeralPK */ $ephemeralPK = self::box_publickey($ephemeralKeypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair - The combined keypair used in crypto_box() */ $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey); /** @var string $ciphertext Ciphertext + MAC from crypto_box */ $ciphertext = self::box($message, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($ephemeralKeypair); ParagonIE_Sodium_Compat::memzero($ephemeralSK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $ephemeralKeypair = null; $ephemeralSK = null; $nonce = null; } return $ephemeralPK . $ciphertext; } /** * Opens a message encrypted via box_seal(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_seal_open($message, $keypair) { /** @var string $ephemeralPK */ $ephemeralPK = ParagonIE_Sodium_Core32_Util::substr($message, 0, 32); /** @var string $ciphertext (ciphertext + MAC) */ $ciphertext = ParagonIE_Sodium_Core32_Util::substr($message, 32); /** @var string $secretKey */ $secretKey = self::box_secretkey($keypair); /** @var string $publicKey */ $publicKey = self::box_publickey($keypair); /** @var string $nonce */ $nonce = self::generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var string $keypair */ $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK); /** @var string $m */ $m = self::box_open($ciphertext, $nonce, $keypair); try { ParagonIE_Sodium_Compat::memzero($secretKey); ParagonIE_Sodium_Compat::memzero($ephemeralPK); ParagonIE_Sodium_Compat::memzero($nonce); } catch (SodiumException $ex) { $secretKey = null; $ephemeralPK = null; $nonce = null; } return $m; } /** * Used by crypto_box() to get the crypto_secretbox() key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sk * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function box_beforenm($sk, $pk) { return ParagonIE_Sodium_Core32_HSalsa20::hsalsa20( str_repeat("\x00", 16), self::scalarmult($sk, $pk) ); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @return string * @throws Exception * @throws SodiumException * @throws TypeError */ public static function box_keypair() { $sKey = random_bytes(32); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @param string $seed * @return string * @throws SodiumException * @throws TypeError */ public static function box_seed_keypair($seed) { $sKey = ParagonIE_Sodium_Core32_Util::substr( hash('sha512', $seed, true), 0, 32 ); $pKey = self::scalarmult_base($sKey); return $sKey . $pKey; } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * @throws TypeError */ public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey) { return ParagonIE_Sodium_Core32_Util::substr($sKey, 0, 32) . ParagonIE_Sodium_Core32_Util::substr($pKey, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_secretkey($keypair) { if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== 64) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core32_Util::substr($keypair, 0, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $keypair * @return string * @throws RangeException * @throws TypeError */ public static function box_publickey($keypair) { if (ParagonIE_Sodium_Core32_Util::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES bytes long.' ); } return ParagonIE_Sodium_Core32_Util::substr($keypair, 32, 32); } /** * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function box_publickey_from_secretkey($sKey) { if (ParagonIE_Sodium_Core32_Util::strlen($sKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES) { throw new RangeException( 'Must be ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES bytes long.' ); } return self::scalarmult_base($sKey); } /** * Decrypt a message encrypted with box(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $keypair * @return string * @throws SodiumException * @throws TypeError */ public static function box_open($ciphertext, $nonce, $keypair) { return self::secretbox_open( $ciphertext, $nonce, self::box_beforenm( self::box_secretkey($keypair), self::box_publickey($keypair) ) ); } /** * Calculate a BLAKE2b hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string|null $key * @param int $outlen * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash($message, $key = '', $outlen = 32) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { /** @var SplFixedArray $k */ $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message); /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outlen); ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $in, $in->count()); /** @var SplFixedArray $out */ $out = new SplFixedArray($outlen); $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($ctx, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray); } /** * Finalize a BLAKE2b hashing context, returning the hash. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param int $outlen * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_final($ctx, $outlen = 32) { if (!is_string($ctx)) { throw new TypeError('Context must be a string'); } $out = new SplFixedArray($outlen); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $out */ $out = ParagonIE_Sodium_Core32_BLAKE2b::finish($context, $out); /** @var array<int, int> */ $outArray = $out->toArray(); return ParagonIE_Sodium_Core32_Util::intArrayToString($outArray); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init($key = '', $outputLength = 32) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx); } /** * Initialize a hashing context for BLAKE2b. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $key * @param int $outputLength * @param string $salt * @param string $personal * @return string * @throws RangeException * @throws SodiumException * @throws TypeError */ public static function generichash_init_salt_personal( $key = '', $outputLength = 32, $salt = '', $personal = '' ) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); $k = null; if (!empty($key)) { $k = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($key); if ($k->count() > ParagonIE_Sodium_Core32_BLAKE2b::KEYBYTES) { throw new RangeException('Invalid key size'); } } if (!empty($salt)) { $s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($salt); } else { $s = null; } if (!empty($salt)) { $p = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($personal); } else { $p = null; } /** @var SplFixedArray $ctx */ $ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($k, $outputLength, $s, $p); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx); } /** * Update a hashing context for BLAKE2b with $message * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ctx * @param string $message * @return string * @throws SodiumException * @throws TypeError */ public static function generichash_update($ctx, $message) { // This ensures that ParagonIE_Sodium_Core32_BLAKE2b::$iv is initialized ParagonIE_Sodium_Core32_BLAKE2b::pseudoConstructor(); /** @var SplFixedArray $context */ $context = ParagonIE_Sodium_Core32_BLAKE2b::stringToContext($ctx); /** @var SplFixedArray $in */ $in = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($message); ParagonIE_Sodium_Core32_BLAKE2b::update($context, $in, $in->count()); return ParagonIE_Sodium_Core32_BLAKE2b::contextToString($context); } /** * Libsodium's crypto_kx(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $my_sk * @param string $their_pk * @param string $client_pk * @param string $server_pk * @return string * @throws SodiumException * @throws TypeError */ public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) { return self::generichash( self::scalarmult($my_sk, $their_pk) . $client_pk . $server_pk ); } /** * ECDH over Curve25519 * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $sKey * @param string $pKey * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult($sKey, $pKey) { $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10($sKey, $pKey); self::scalarmult_throw_if_zero($q); return $q; } /** * ECDH over Curve25519, using the basepoint. * Used to get a secret key from a public key. * * @param string $secret * @return string * * @throws SodiumException * @throws TypeError */ public static function scalarmult_base($secret) { $q = ParagonIE_Sodium_Core32_X25519::crypto_scalarmult_curve25519_ref10_base($secret); self::scalarmult_throw_if_zero($q); return $q; } /** * This throws an Error if a zero public key was passed to the function. * * @param string $q * @return void * @throws SodiumException * @throws TypeError */ protected static function scalarmult_throw_if_zero($q) { $d = 0; for ($i = 0; $i < self::box_curve25519xsalsa20poly1305_SECRETKEYBYTES; ++$i) { $d |= ParagonIE_Sodium_Core32_Util::chrToInt($q[$i]); } /* branch-free variant of === 0 */ if (-(1 & (($d - 1) >> 8))) { throw new SodiumException('Zero public key is not allowed'); } } /** * XSalsa20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor( $block0, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $block0, self::secretbox_xsalsa20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core32_Util::substr( $plaintext, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), 1, $subkey ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, 0, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, self::secretbox_xsalsa20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core32_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20( 64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core32_Util::xorStrings( ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( ParagonIE_Sodium_Core32_Util::substr( $c, self::secretbox_xsalsa20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), 1, (string) $subkey ); } return $m; } /** * XChaCha20-Poly1305 authenticated symmetric-key encryption. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $plaintext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key) { /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($nonce, 0, 16), $key ); $nonceLast = ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen = ParagonIE_Sodium_Core32_Util::strlen($plaintext); $mlen0 = $mlen; if ($mlen0 > 64 - self::secretbox_xchacha20poly1305_ZEROBYTES) { $mlen0 = 64 - self::secretbox_xchacha20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( $block0, $nonceLast, $subkey ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $block0, self::secretbox_xchacha20poly1305_ZEROBYTES ); if ($mlen > $mlen0) { $c .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( ParagonIE_Sodium_Core32_Util::substr( $plaintext, self::secretbox_xchacha20poly1305_ZEROBYTES ), $nonceLast, $subkey, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } $state = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_Util::substr( $block0, 0, self::onetimeauth_poly1305_KEYBYTES ) ); try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $state->update($c); /** @var string $c - MAC || ciphertext */ $c = $state->finish() . $c; unset($state); return $c; } /** * Decrypt a ciphertext generated via secretbox_xchacha20poly1305(). * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $ciphertext * @param string $nonce * @param string $key * @return string * @throws SodiumException * @throws TypeError */ public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) { /** @var string $mac */ $mac = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, 0, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var string $c */ $c = ParagonIE_Sodium_Core32_Util::substr( $ciphertext, self::secretbox_xchacha20poly1305_MACBYTES ); /** @var int $clen */ $clen = ParagonIE_Sodium_Core32_Util::strlen($c); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HChaCha20::hchacha20($nonce, $key); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_ChaCha20::stream( 64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); $verified = ParagonIE_Sodium_Core32_Poly1305::onetimeauth_verify( $mac, $c, ParagonIE_Sodium_Core32_Util::substr($block0, 0, 32) ); if (!$verified) { try { ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $subkey = null; } throw new SodiumException('Invalid MAC'); } /** @var string $m - Decrypted message */ $m = ParagonIE_Sodium_Core32_Util::xorStrings( ParagonIE_Sodium_Core32_Util::substr($block0, self::secretbox_xchacha20poly1305_ZEROBYTES), ParagonIE_Sodium_Core32_Util::substr($c, 0, self::secretbox_xchacha20poly1305_ZEROBYTES) ); if ($clen > self::secretbox_xchacha20poly1305_ZEROBYTES) { // We had more than 1 block, so let's continue to decrypt the rest. $m .= ParagonIE_Sodium_Core32_ChaCha20::streamXorIc( ParagonIE_Sodium_Core32_Util::substr( $c, self::secretbox_xchacha20poly1305_ZEROBYTES ), ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), (string) $subkey, ParagonIE_Sodium_Core32_Util::store64_le(1) ); } return $m; } /** * @param string $key * @return array<int, string> Returns a state and a header. * @throws Exception * @throws SodiumException */ public static function secretstream_xchacha20poly1305_init_push($key) { # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); $out = random_bytes(24); # crypto_core_hchacha20(state->k, out, k, NULL); $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20($out, $key); $state = new ParagonIE_Sodium_Core32_SecretStream_State( $subkey, ParagonIE_Sodium_Core32_Util::substr($out, 16, 8) . str_repeat("\0", 4) ); # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $state->counterReset(); # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); return array( $state->toString(), $out ); } /** * @param string $key * @param string $header * @return string Returns a state. * @throws Exception */ public static function secretstream_xchacha20poly1305_init_pull($key, $header) { # crypto_core_hchacha20(state->k, in, k, NULL); $subkey = ParagonIE_Sodium_Core32_HChaCha20::hChaCha20( ParagonIE_Sodium_Core32_Util::substr($header, 0, 16), $key ); $state = new ParagonIE_Sodium_Core32_SecretStream_State( $subkey, ParagonIE_Sodium_Core32_Util::substr($header, 16) ); $state->counterReset(); # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); # memset(state->_pad, 0, sizeof state->_pad); # return 0; return $state->toString(); } /** * @param string $state * @param string $msg * @param string $aad * @param int $tag * @return string * @throws SodiumException */ public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); # crypto_onetimeauth_poly1305_state poly1305_state; # unsigned char block[64U]; # unsigned char slen[8U]; # unsigned char *c; # unsigned char *mac; $msglen = ParagonIE_Sodium_Core32_Util::strlen($msg); $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # if (outlen_p != NULL) { # *outlen_p = 0U; # } # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = tag; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core32_Util::intToChr($tag) . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(1) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $auth->update($block); # out[0] = block[0]; $out = $block[0]; # c = out + (sizeof tag); # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); $cipher = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $msg, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(2) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update($cipher); $out .= $cipher; unset($cipher); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $auth->update($slen); # mac = c + mlen; # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); $mac = $auth->finish(); $out .= $mac; # sodium_memzero(&poly1305_state, sizeof poly1305_state); unset($auth); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } # if (outlen_p != NULL) { # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; # } return $out; } /** * @param string $state * @param string $cipher * @param string $aad * @return bool|array{0: string, 1: int} * @throws SodiumException */ public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); $cipherlen = ParagonIE_Sodium_Core32_Util::strlen($cipher); # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; $aadlen = ParagonIE_Sodium_Core32_Util::strlen($aad); # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { # sodium_misuse(); # } if ((($msglen + 63) >> 6) > 0xfffffffe) { throw new SodiumException( 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' ); } # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); # crypto_onetimeauth_poly1305_init(&poly1305_state, block); # sodium_memzero(block, sizeof block); $auth = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) ); # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); $auth->update($aad); # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, # (0x10 - adlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); # memset(block, 0, sizeof block); # block[0] = in[0]; # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, # state->nonce, 1U, state->k); $block = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $cipher[0] . str_repeat("\0", 63), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(1) ); # tag = block[0]; # block[0] = in[0]; # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); $tag = ParagonIE_Sodium_Core32_Util::chrToInt($block[0]); $block[0] = $cipher[0]; $auth->update($block); # c = in + (sizeof tag); # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); $auth->update(ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen)); # crypto_onetimeauth_poly1305_update # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); # STORE64_LE(slen, (uint64_t) adlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core32_Util::store64_le($aadlen); $auth->update($slen); # STORE64_LE(slen, (sizeof block) + mlen); # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); $slen = ParagonIE_Sodium_Core32_Util::store64_le(64 + $msglen); $auth->update($slen); # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); # sodium_memzero(&poly1305_state, sizeof poly1305_state); $mac = $auth->finish(); # stored_mac = c + mlen; # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { # sodium_memzero(mac, sizeof mac); # return -1; # } $stored = ParagonIE_Sodium_Core32_Util::substr($cipher, $msglen + 1, 16); if (!ParagonIE_Sodium_Core32_Util::hashEquals($mac, $stored)) { return false; } # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); $out = ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( ParagonIE_Sodium_Core32_Util::substr($cipher, 1, $msglen), $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(2) ); # XOR_BUF(STATE_INONCE(state), mac, # crypto_secretstream_xchacha20poly1305_INONCEBYTES); $st->xorNonce($mac); # sodium_increment(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); $st->incrementCounter(); # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || # sodium_is_zero(STATE_COUNTER(state), # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { # crypto_secretstream_xchacha20poly1305_rekey(state); # } // Overwrite by reference: $state = $st->toString(); /** @var bool $rekey */ $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; if ($rekey || $st->needsRekey()) { // DO REKEY self::secretstream_xchacha20poly1305_rekey($state); } return array($out, $tag); } /** * @param string $state * @return void * @throws SodiumException */ public static function secretstream_xchacha20poly1305_rekey(&$state) { $st = ParagonIE_Sodium_Core32_SecretStream_State::fromString($state); # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; # size_t i; # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # new_key_and_inonce[i] = state->k[i]; # } $new_key_and_inonce = $st->getKey(); # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = # STATE_INONCE(state)[i]; # } $new_key_and_inonce .= ParagonIE_Sodium_Core32_Util::substR($st->getNonce(), 0, 8); # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, # sizeof new_key_and_inonce, # state->nonce, state->k); $st->rekey(ParagonIE_Sodium_Core32_ChaCha20::ietfStreamXorIc( $new_key_and_inonce, $st->getCombinedNonce(), $st->getKey(), ParagonIE_Sodium_Core32_Util::store64_le(0) )); # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { # state->k[i] = new_key_and_inonce[i]; # } # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { # STATE_INONCE(state)[i] = # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; # } # _crypto_secretstream_xchacha20poly1305_counter_reset(state); $st->counterReset(); $state = $st->toString(); } /** * Detached Ed25519 signature. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_detached($message, $sk) { return ParagonIE_Sodium_Core32_Ed25519::sign_detached($message, $sk); } /** * Attached Ed25519 signature. (Returns a signed message.) * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $message * @param string $sk * @return string * @throws SodiumException * @throws TypeError */ public static function sign($message, $sk) { return ParagonIE_Sodium_Core32_Ed25519::sign($message, $sk); } /** * Opens a signed message. If valid, returns the message. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signedMessage * @param string $pk * @return string * @throws SodiumException * @throws TypeError */ public static function sign_open($signedMessage, $pk) { return ParagonIE_Sodium_Core32_Ed25519::sign_open($signedMessage, $pk); } /** * Verify a detached signature of a given message and public key. * * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. * * @param string $signature * @param string $message * @param string $pk * @return bool * @throws SodiumException * @throws TypeError */ public static function sign_verify_detached($signature, $message, $pk) { return ParagonIE_Sodium_Core32_Ed25519::verify_detached($signature, $message, $pk); } } <?php if (class_exists('ParagonIE_Sodium_File', false)) { return; } /** * Class ParagonIE_Sodium_File */ class ParagonIE_Sodium_File extends ParagonIE_Sodium_Core_Util { /* PHP's default buffer size is 8192 for fread()/fwrite(). */ const BUFFER_SIZE = 8192; /** * Box a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_box(), but produces * the same result. * * @param string $inputFile Absolute path to a file on the filesystem * @param string $outputFile Absolute path to a file on the filesystem * @param string $nonce Number to be used only once * @param string $keyPair ECDH secret key and ECDH public key concatenated * * @return bool * @throws SodiumException * @throws TypeError */ public static function box( $inputFile, $outputFile, $nonce, #[\SensitiveParameter] $keyPair ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($nonce)) { throw new TypeError('Argument 3 must be a string, ' . gettype($nonce) . ' given.'); } /* Input validation: */ if (!is_string($keyPair)) { throw new TypeError('Argument 4 must be a string, ' . gettype($keyPair) . ' given.'); } if (self::strlen($nonce) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES) { throw new TypeError('Argument 3 must be CRYPTO_BOX_NONCEBYTES bytes'); } if (self::strlen($keyPair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new TypeError('Argument 4 must be CRYPTO_BOX_KEYPAIRBYTES bytes'); } /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } $res = self::box_encrypt($ifp, $ofp, $size, $nonce, $keyPair); fclose($ifp); fclose($ofp); return $res; } /** * Open a boxed file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_box_open(), but produces * the same result. * * Warning: Does not protect against TOCTOU attacks. You should * just load the file into memory and use crypto_box_open() if * you are worried about those. * * @param string $inputFile * @param string $outputFile * @param string $nonce * @param string $keypair * @return bool * @throws SodiumException * @throws TypeError */ public static function box_open( $inputFile, $outputFile, $nonce, #[\SensitiveParameter] $keypair ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($nonce)) { throw new TypeError('Argument 3 must be a string, ' . gettype($nonce) . ' given.'); } if (!is_string($keypair)) { throw new TypeError('Argument 4 must be a string, ' . gettype($keypair) . ' given.'); } /* Input validation: */ if (self::strlen($nonce) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES) { throw new TypeError('Argument 4 must be CRYPTO_BOX_NONCEBYTES bytes'); } if (self::strlen($keypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new TypeError('Argument 4 must be CRYPTO_BOX_KEYPAIRBYTES bytes'); } /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $keypair); fclose($ifp); fclose($ofp); try { ParagonIE_Sodium_Compat::memzero($nonce); ParagonIE_Sodium_Compat::memzero($ephKeypair); } catch (SodiumException $ex) { if (isset($ephKeypair)) { unset($ephKeypair); } } return $res; } /** * Seal a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_box_seal(), but produces * the same result. * * @param string $inputFile Absolute path to a file on the filesystem * @param string $outputFile Absolute path to a file on the filesystem * @param string $publicKey ECDH public key * * @return bool * @throws SodiumException * @throws TypeError */ public static function box_seal( $inputFile, $outputFile, #[\SensitiveParameter] $publicKey ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($publicKey)) { throw new TypeError('Argument 3 must be a string, ' . gettype($publicKey) . ' given.'); } /* Input validation: */ if (self::strlen($publicKey) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES) { throw new TypeError('Argument 3 must be CRYPTO_BOX_PUBLICKEYBYTES bytes'); } /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } /** @var string $ephKeypair */ $ephKeypair = ParagonIE_Sodium_Compat::crypto_box_keypair(); /** @var string $msgKeypair */ $msgKeypair = ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey( ParagonIE_Sodium_Compat::crypto_box_secretkey($ephKeypair), $publicKey ); /** @var string $ephemeralPK */ $ephemeralPK = ParagonIE_Sodium_Compat::crypto_box_publickey($ephKeypair); /** @var string $nonce */ $nonce = ParagonIE_Sodium_Compat::crypto_generichash( $ephemeralPK . $publicKey, '', 24 ); /** @var int $firstWrite */ $firstWrite = fwrite( $ofp, $ephemeralPK, ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES ); if (!is_int($firstWrite)) { fclose($ifp); fclose($ofp); ParagonIE_Sodium_Compat::memzero($ephKeypair); throw new SodiumException('Could not write to output file'); } if ($firstWrite !== ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES) { ParagonIE_Sodium_Compat::memzero($ephKeypair); fclose($ifp); fclose($ofp); throw new SodiumException('Error writing public key to output file'); } $res = self::box_encrypt($ifp, $ofp, $size, $nonce, $msgKeypair); fclose($ifp); fclose($ofp); try { ParagonIE_Sodium_Compat::memzero($nonce); ParagonIE_Sodium_Compat::memzero($ephKeypair); } catch (SodiumException $ex) { /** @psalm-suppress PossiblyUndefinedVariable */ unset($ephKeypair); } return $res; } /** * Open a sealed file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_box_seal_open(), but produces * the same result. * * Warning: Does not protect against TOCTOU attacks. You should * just load the file into memory and use crypto_box_seal_open() if * you are worried about those. * * @param string $inputFile * @param string $outputFile * @param string $ecdhKeypair * @return bool * @throws SodiumException * @throws TypeError */ public static function box_seal_open( $inputFile, $outputFile, #[\SensitiveParameter] $ecdhKeypair ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($ecdhKeypair)) { throw new TypeError('Argument 3 must be a string, ' . gettype($ecdhKeypair) . ' given.'); } /* Input validation: */ if (self::strlen($ecdhKeypair) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES) { throw new TypeError('Argument 3 must be CRYPTO_BOX_KEYPAIRBYTES bytes'); } $publicKey = ParagonIE_Sodium_Compat::crypto_box_publickey($ecdhKeypair); /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } $ephemeralPK = fread($ifp, ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES); if (!is_string($ephemeralPK)) { throw new SodiumException('Could not read input file'); } if (self::strlen($ephemeralPK) !== ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES) { fclose($ifp); fclose($ofp); throw new SodiumException('Could not read public key from sealed file'); } $nonce = ParagonIE_Sodium_Compat::crypto_generichash( $ephemeralPK . $publicKey, '', 24 ); $msgKeypair = ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey( ParagonIE_Sodium_Compat::crypto_box_secretkey($ecdhKeypair), $ephemeralPK ); $res = self::box_decrypt($ifp, $ofp, $size, $nonce, $msgKeypair); fclose($ifp); fclose($ofp); try { ParagonIE_Sodium_Compat::memzero($nonce); ParagonIE_Sodium_Compat::memzero($ephKeypair); } catch (SodiumException $ex) { if (isset($ephKeypair)) { unset($ephKeypair); } } return $res; } /** * Calculate the BLAKE2b hash of a file. * * @param string $filePath Absolute path to a file on the filesystem * @param string|null $key BLAKE2b key * @param int $outputLength Length of hash output * * @return string BLAKE2b hash * @throws SodiumException * @throws TypeError * @psalm-suppress FailedTypeResolution */ public static function generichash( $filePath, #[\SensitiveParameter] $key = '', $outputLength = 32 ) { /* Type checks: */ if (!is_string($filePath)) { throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.'); } if (!is_string($key)) { if (is_null($key)) { $key = ''; } else { throw new TypeError('Argument 2 must be a string, ' . gettype($key) . ' given.'); } } if (!is_int($outputLength)) { if (!is_numeric($outputLength)) { throw new TypeError('Argument 3 must be an integer, ' . gettype($outputLength) . ' given.'); } $outputLength = (int) $outputLength; } /* Input validation: */ if (!empty($key)) { if (self::strlen($key) < ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MIN) { throw new TypeError('Argument 2 must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes'); } if (self::strlen($key) > ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MAX) { throw new TypeError('Argument 2 must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes'); } } if ($outputLength < ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MIN) { throw new SodiumException('Argument 3 must be at least CRYPTO_GENERICHASH_BYTES_MIN'); } if ($outputLength > ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MAX) { throw new SodiumException('Argument 3 must be at least CRYPTO_GENERICHASH_BYTES_MAX'); } /** @var int $size */ $size = filesize($filePath); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $fp */ $fp = fopen($filePath, 'rb'); if (!is_resource($fp)) { throw new SodiumException('Could not open input file for reading'); } $ctx = ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outputLength); while ($size > 0) { $blockSize = $size > 64 ? 64 : $size; $read = fread($fp, $blockSize); if (!is_string($read)) { throw new SodiumException('Could not read input file'); } ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $read); $size -= $blockSize; } fclose($fp); return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength); } /** * Encrypt a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_secretbox(), but produces * the same result. * * @param string $inputFile Absolute path to a file on the filesystem * @param string $outputFile Absolute path to a file on the filesystem * @param string $nonce Number to be used only once * @param string $key Encryption key * * @return bool * @throws SodiumException * @throws TypeError */ public static function secretbox( $inputFile, $outputFile, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given..'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($nonce)) { throw new TypeError('Argument 3 must be a string, ' . gettype($nonce) . ' given.'); } /* Input validation: */ if (self::strlen($nonce) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES) { throw new TypeError('Argument 3 must be CRYPTO_SECRETBOX_NONCEBYTES bytes'); } if (!is_string($key)) { throw new TypeError('Argument 4 must be a string, ' . gettype($key) . ' given.'); } if (self::strlen($key) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES) { throw new TypeError('Argument 4 must be CRYPTO_SECRETBOX_KEYBYTES bytes'); } /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } $res = self::secretbox_encrypt($ifp, $ofp, $size, $nonce, $key); fclose($ifp); fclose($ofp); return $res; } /** * Seal a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_secretbox_open(), but produces * the same result. * * Warning: Does not protect against TOCTOU attacks. You should * just load the file into memory and use crypto_secretbox_open() if * you are worried about those. * * @param string $inputFile * @param string $outputFile * @param string $nonce * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ public static function secretbox_open( $inputFile, $outputFile, $nonce, #[\SensitiveParameter] $key ) { /* Type checks: */ if (!is_string($inputFile)) { throw new TypeError('Argument 1 must be a string, ' . gettype($inputFile) . ' given.'); } if (!is_string($outputFile)) { throw new TypeError('Argument 2 must be a string, ' . gettype($outputFile) . ' given.'); } if (!is_string($nonce)) { throw new TypeError('Argument 3 must be a string, ' . gettype($nonce) . ' given.'); } if (!is_string($key)) { throw new TypeError('Argument 4 must be a string, ' . gettype($key) . ' given.'); } /* Input validation: */ if (self::strlen($nonce) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES) { throw new TypeError('Argument 4 must be CRYPTO_SECRETBOX_NONCEBYTES bytes'); } if (self::strlen($key) !== ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES) { throw new TypeError('Argument 4 must be CRYPTO_SECRETBOXBOX_KEYBYTES bytes'); } /** @var int $size */ $size = filesize($inputFile); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $ifp */ $ifp = fopen($inputFile, 'rb'); if (!is_resource($ifp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $ofp */ $ofp = fopen($outputFile, 'wb'); if (!is_resource($ofp)) { fclose($ifp); throw new SodiumException('Could not open output file for writing'); } $res = self::secretbox_decrypt($ifp, $ofp, $size, $nonce, $key); fclose($ifp); fclose($ofp); try { ParagonIE_Sodium_Compat::memzero($key); } catch (SodiumException $ex) { /** @psalm-suppress PossiblyUndefinedVariable */ unset($key); } return $res; } /** * Sign a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_sign_detached(), but produces * the same result. * * @param string $filePath Absolute path to a file on the filesystem * @param string $secretKey Secret signing key * * @return string Ed25519 signature * @throws SodiumException * @throws TypeError */ public static function sign( $filePath, #[\SensitiveParameter] $secretKey ) { /* Type checks: */ if (!is_string($filePath)) { throw new TypeError('Argument 1 must be a string, ' . gettype($filePath) . ' given.'); } if (!is_string($secretKey)) { throw new TypeError('Argument 2 must be a string, ' . gettype($secretKey) . ' given.'); } /* Input validation: */ if (self::strlen($secretKey) !== ParagonIE_Sodium_Compat::CRYPTO_SIGN_SECRETKEYBYTES) { throw new TypeError('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES bytes'); } if (PHP_INT_SIZE === 4) { return self::sign_core32($filePath, $secretKey); } /** @var int $size */ $size = filesize($filePath); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $fp */ $fp = fopen($filePath, 'rb'); if (!is_resource($fp)) { throw new SodiumException('Could not open input file for reading'); } /** @var string $az */ $az = hash('sha512', self::substr($secretKey, 0, 32), true); $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($az, 32, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); /** @var string $nonceHash */ $nonceHash = hash_final($hs, true); /** @var string $pk */ $pk = self::substr($secretKey, 32, 32); /** @var string $nonce */ $nonce = ParagonIE_Sodium_Core_Ed25519::sc_reduce($nonceHash) . self::substr($nonceHash, 32); /** @var string $sig */ $sig = ParagonIE_Sodium_Core_Ed25519::ge_p3_tobytes( ParagonIE_Sodium_Core_Ed25519::ge_scalarmult_base($nonce) ); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($sig, 0, 32)); self::hash_update($hs, self::substr($pk, 0, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); /** @var string $hramHash */ $hramHash = hash_final($hs, true); /** @var string $hram */ $hram = ParagonIE_Sodium_Core_Ed25519::sc_reduce($hramHash); /** @var string $sigAfter */ $sigAfter = ParagonIE_Sodium_Core_Ed25519::sc_muladd($hram, $az, $nonce); /** @var string $sig */ $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32); try { ParagonIE_Sodium_Compat::memzero($az); } catch (SodiumException $ex) { $az = null; } fclose($fp); return $sig; } /** * Verify a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_sign_verify_detached(), but * produces the same result. * * @param string $sig Ed25519 signature * @param string $filePath Absolute path to a file on the filesystem * @param string $publicKey Signing public key * * @return bool * @throws SodiumException * @throws TypeError * @throws Exception */ public static function verify( $sig, $filePath, $publicKey ) { /* Type checks: */ if (!is_string($sig)) { throw new TypeError('Argument 1 must be a string, ' . gettype($sig) . ' given.'); } if (!is_string($filePath)) { throw new TypeError('Argument 2 must be a string, ' . gettype($filePath) . ' given.'); } if (!is_string($publicKey)) { throw new TypeError('Argument 3 must be a string, ' . gettype($publicKey) . ' given.'); } /* Input validation: */ if (self::strlen($sig) !== ParagonIE_Sodium_Compat::CRYPTO_SIGN_BYTES) { throw new TypeError('Argument 1 must be CRYPTO_SIGN_BYTES bytes'); } if (self::strlen($publicKey) !== ParagonIE_Sodium_Compat::CRYPTO_SIGN_PUBLICKEYBYTES) { throw new TypeError('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES bytes'); } if (self::strlen($sig) < 64) { throw new SodiumException('Signature is too short'); } if (PHP_INT_SIZE === 4) { return self::verify_core32($sig, $filePath, $publicKey); } /* Security checks */ if ( (ParagonIE_Sodium_Core_Ed25519::chrToInt($sig[63]) & 240) && ParagonIE_Sodium_Core_Ed25519::check_S_lt_L(self::substr($sig, 32, 32)) ) { throw new SodiumException('S < L - Invalid signature'); } if (ParagonIE_Sodium_Core_Ed25519::small_order($sig)) { throw new SodiumException('Signature is on too small of an order'); } if ((self::chrToInt($sig[63]) & 224) !== 0) { throw new SodiumException('Invalid signature'); } $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= self::chrToInt($publicKey[$i]); } if ($d === 0) { throw new SodiumException('All zero public key'); } /** @var int $size */ $size = filesize($filePath); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var resource $fp */ $fp = fopen($filePath, 'rb'); if (!is_resource($fp)) { throw new SodiumException('Could not open input file for reading'); } /** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */ $orig = ParagonIE_Sodium_Compat::$fastMult; // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification. ParagonIE_Sodium_Compat::$fastMult = true; /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A */ $A = ParagonIE_Sodium_Core_Ed25519::ge_frombytes_negate_vartime($publicKey); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($sig, 0, 32)); self::hash_update($hs, self::substr($publicKey, 0, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); /** @var string $hDigest */ $hDigest = hash_final($hs, true); /** @var string $h */ $h = ParagonIE_Sodium_Core_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32); /** @var ParagonIE_Sodium_Core_Curve25519_Ge_P2 $R */ $R = ParagonIE_Sodium_Core_Ed25519::ge_double_scalarmult_vartime( $h, $A, self::substr($sig, 32) ); /** @var string $rcheck */ $rcheck = ParagonIE_Sodium_Core_Ed25519::ge_tobytes($R); // Close the file handle fclose($fp); // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before. ParagonIE_Sodium_Compat::$fastMult = $orig; return self::verify_32($rcheck, self::substr($sig, 0, 32)); } /** * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $boxKeypair * @return bool * @throws SodiumException * @throws TypeError */ protected static function box_encrypt($ifp, $ofp, $mlen, $nonce, $boxKeypair) { if (PHP_INT_SIZE === 4) { return self::secretbox_encrypt( $ifp, $ofp, $mlen, $nonce, ParagonIE_Sodium_Crypto32::box_beforenm( ParagonIE_Sodium_Crypto32::box_secretkey($boxKeypair), ParagonIE_Sodium_Crypto32::box_publickey($boxKeypair) ) ); } return self::secretbox_encrypt( $ifp, $ofp, $mlen, $nonce, ParagonIE_Sodium_Crypto::box_beforenm( ParagonIE_Sodium_Crypto::box_secretkey($boxKeypair), ParagonIE_Sodium_Crypto::box_publickey($boxKeypair) ) ); } /** * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $boxKeypair * @return bool * @throws SodiumException * @throws TypeError */ protected static function box_decrypt($ifp, $ofp, $mlen, $nonce, $boxKeypair) { if (PHP_INT_SIZE === 4) { return self::secretbox_decrypt( $ifp, $ofp, $mlen, $nonce, ParagonIE_Sodium_Crypto32::box_beforenm( ParagonIE_Sodium_Crypto32::box_secretkey($boxKeypair), ParagonIE_Sodium_Crypto32::box_publickey($boxKeypair) ) ); } return self::secretbox_decrypt( $ifp, $ofp, $mlen, $nonce, ParagonIE_Sodium_Crypto::box_beforenm( ParagonIE_Sodium_Crypto::box_secretkey($boxKeypair), ParagonIE_Sodium_Crypto::box_publickey($boxKeypair) ) ); } /** * Encrypt a file * * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ protected static function secretbox_encrypt($ifp, $ofp, $mlen, $nonce, $key) { if (PHP_INT_SIZE === 4) { return self::secretbox_encrypt_core32($ifp, $ofp, $mlen, $nonce, $key); } $plaintext = fread($ifp, 32); if (!is_string($plaintext)) { throw new SodiumException('Could not read input file'); } $first32 = self::ftell($ifp); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $realNonce */ $realNonce = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen0 = $mlen; if ($mlen0 > 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20_xor( $block0, $realNonce, $subkey ); $state = new ParagonIE_Sodium_Core_Poly1305_State( ParagonIE_Sodium_Core_Util::substr( $block0, 0, ParagonIE_Sodium_Crypto::onetimeauth_poly1305_KEYBYTES ) ); // Pre-write 16 blank bytes for the Poly1305 tag $start = self::ftell($ofp); fwrite($ofp, str_repeat("\x00", 16)); /** @var string $c */ $cBlock = ParagonIE_Sodium_Core_Util::substr( $block0, ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES ); $state->update($cBlock); fwrite($ofp, $cBlock); $mlen -= 32; /** @var int $iter */ $iter = 1; /** @var int $incr */ $incr = self::BUFFER_SIZE >> 6; /* * Set the cursor to the end of the first half-block. All future bytes will * generated from salsa20_xor_ic, starting from 1 (second block). */ fseek($ifp, $first32, SEEK_SET); while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $plaintext = fread($ifp, $blockSize); if (!is_string($plaintext)) { throw new SodiumException('Could not read input file'); } $cBlock = ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( $plaintext, $realNonce, $iter, $subkey ); fwrite($ofp, $cBlock, $blockSize); $state->update($cBlock); $mlen -= $blockSize; $iter += $incr; } try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $end = self::ftell($ofp); /* * Write the Poly1305 authentication tag that provides integrity * over the ciphertext (encrypt-then-MAC) */ fseek($ofp, $start, SEEK_SET); fwrite($ofp, $state->finish(), ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES); fseek($ofp, $end, SEEK_SET); unset($state); return true; } /** * Decrypt a file * * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ protected static function secretbox_decrypt($ifp, $ofp, $mlen, $nonce, $key) { if (PHP_INT_SIZE === 4) { return self::secretbox_decrypt_core32($ifp, $ofp, $mlen, $nonce, $key); } $tag = fread($ifp, 16); if (!is_string($tag)) { throw new SodiumException('Could not read input file'); } /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key); /** @var string $realNonce */ $realNonce = ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20( 64, ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8), $subkey ); /* Verify the Poly1305 MAC -before- attempting to decrypt! */ $state = new ParagonIE_Sodium_Core_Poly1305_State(self::substr($block0, 0, 32)); if (!self::onetimeauth_verify($state, $ifp, $tag, $mlen)) { throw new SodiumException('Invalid MAC'); } /* * Set the cursor to the end of the first half-block. All future bytes will * generated from salsa20_xor_ic, starting from 1 (second block). */ $first32 = fread($ifp, 32); if (!is_string($first32)) { throw new SodiumException('Could not read input file'); } $first32len = self::strlen($first32); fwrite( $ofp, self::xorStrings( self::substr($block0, 32, $first32len), self::substr($first32, 0, $first32len) ) ); $mlen -= 32; /** @var int $iter */ $iter = 1; /** @var int $incr */ $incr = self::BUFFER_SIZE >> 6; /* Decrypts ciphertext, writes to output file. */ while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $ciphertext = fread($ifp, $blockSize); if (!is_string($ciphertext)) { throw new SodiumException('Could not read input file'); } $pBlock = ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic( $ciphertext, $realNonce, $iter, $subkey ); fwrite($ofp, $pBlock, $blockSize); $mlen -= $blockSize; $iter += $incr; } return true; } /** * @param ParagonIE_Sodium_Core_Poly1305_State $state * @param resource $ifp * @param string $tag * @param int $mlen * @return bool * @throws SodiumException * @throws TypeError */ protected static function onetimeauth_verify( ParagonIE_Sodium_Core_Poly1305_State $state, $ifp, $tag = '', $mlen = 0 ) { /** @var int $pos */ $pos = self::ftell($ifp); /** @var int $iter */ $iter = 1; /** @var int $incr */ $incr = self::BUFFER_SIZE >> 6; while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $ciphertext = fread($ifp, $blockSize); if (!is_string($ciphertext)) { throw new SodiumException('Could not read input file'); } $state->update($ciphertext); $mlen -= $blockSize; $iter += $incr; } $res = ParagonIE_Sodium_Core_Util::verify_16($tag, $state->finish()); fseek($ifp, $pos, SEEK_SET); return $res; } /** * Update a hash context with the contents of a file, without * loading the entire file into memory. * * @param resource|HashContext $hash * @param resource $fp * @param int $size * @return resource|object Resource on PHP < 7.2, HashContext object on PHP >= 7.2 * @throws SodiumException * @throws TypeError * @psalm-suppress PossiblyInvalidArgument * PHP 7.2 changes from a resource to an object, * which causes Psalm to complain about an error. * @psalm-suppress TypeCoercion * Ditto. */ public static function updateHashWithFile($hash, $fp, $size = 0) { /* Type checks: */ if (PHP_VERSION_ID < 70200) { if (!is_resource($hash)) { throw new TypeError('Argument 1 must be a resource, ' . gettype($hash) . ' given.'); } } else { if (!is_object($hash)) { throw new TypeError('Argument 1 must be an object (PHP 7.2+), ' . gettype($hash) . ' given.'); } } if (!is_resource($fp)) { throw new TypeError('Argument 2 must be a resource, ' . gettype($fp) . ' given.'); } if (!is_int($size)) { throw new TypeError('Argument 3 must be an integer, ' . gettype($size) . ' given.'); } /** @var int $originalPosition */ $originalPosition = self::ftell($fp); // Move file pointer to beginning of file fseek($fp, 0, SEEK_SET); for ($i = 0; $i < $size; $i += self::BUFFER_SIZE) { /** @var string|bool $message */ $message = fread( $fp, ($size - $i) > self::BUFFER_SIZE ? $size - $i : self::BUFFER_SIZE ); if (!is_string($message)) { throw new SodiumException('Unexpected error reading from file.'); } /** @var string $message */ /** @psalm-suppress InvalidArgument */ self::hash_update($hash, $message); } // Reset file pointer's position fseek($fp, $originalPosition, SEEK_SET); return $hash; } /** * Sign a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_sign_detached(), but produces * the same result. (32-bit) * * @param string $filePath Absolute path to a file on the filesystem * @param string $secretKey Secret signing key * * @return string Ed25519 signature * @throws SodiumException * @throws TypeError */ private static function sign_core32($filePath, $secretKey) { $size = filesize($filePath); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } $fp = fopen($filePath, 'rb'); if (!is_resource($fp)) { throw new SodiumException('Could not open input file for reading'); } /** @var string $az */ $az = hash('sha512', self::substr($secretKey, 0, 32), true); $az[0] = self::intToChr(self::chrToInt($az[0]) & 248); $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($az, 32, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); $nonceHash = hash_final($hs, true); $pk = self::substr($secretKey, 32, 32); $nonce = ParagonIE_Sodium_Core32_Ed25519::sc_reduce($nonceHash) . self::substr($nonceHash, 32); $sig = ParagonIE_Sodium_Core32_Ed25519::ge_p3_tobytes( ParagonIE_Sodium_Core32_Ed25519::ge_scalarmult_base($nonce) ); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($sig, 0, 32)); self::hash_update($hs, self::substr($pk, 0, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); $hramHash = hash_final($hs, true); $hram = ParagonIE_Sodium_Core32_Ed25519::sc_reduce($hramHash); $sigAfter = ParagonIE_Sodium_Core32_Ed25519::sc_muladd($hram, $az, $nonce); /** @var string $sig */ $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32); try { ParagonIE_Sodium_Compat::memzero($az); } catch (SodiumException $ex) { $az = null; } fclose($fp); return $sig; } /** * * Verify a file (rather than a string). Uses less memory than * ParagonIE_Sodium_Compat::crypto_sign_verify_detached(), but * produces the same result. (32-bit) * * @param string $sig Ed25519 signature * @param string $filePath Absolute path to a file on the filesystem * @param string $publicKey Signing public key * * @return bool * @throws SodiumException * @throws Exception */ public static function verify_core32($sig, $filePath, $publicKey) { /* Security checks */ if (ParagonIE_Sodium_Core32_Ed25519::check_S_lt_L(self::substr($sig, 32, 32))) { throw new SodiumException('S < L - Invalid signature'); } if (ParagonIE_Sodium_Core32_Ed25519::small_order($sig)) { throw new SodiumException('Signature is on too small of an order'); } if ((self::chrToInt($sig[63]) & 224) !== 0) { throw new SodiumException('Invalid signature'); } $d = 0; for ($i = 0; $i < 32; ++$i) { $d |= self::chrToInt($publicKey[$i]); } if ($d === 0) { throw new SodiumException('All zero public key'); } /** @var int|bool $size */ $size = filesize($filePath); if (!is_int($size)) { throw new SodiumException('Could not obtain the file size'); } /** @var int $size */ /** @var resource|bool $fp */ $fp = fopen($filePath, 'rb'); if (!is_resource($fp)) { throw new SodiumException('Could not open input file for reading'); } /** @var resource $fp */ /** @var bool The original value of ParagonIE_Sodium_Compat::$fastMult */ $orig = ParagonIE_Sodium_Compat::$fastMult; // Set ParagonIE_Sodium_Compat::$fastMult to true to speed up verification. ParagonIE_Sodium_Compat::$fastMult = true; /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P3 $A */ $A = ParagonIE_Sodium_Core32_Ed25519::ge_frombytes_negate_vartime($publicKey); $hs = hash_init('sha512'); self::hash_update($hs, self::substr($sig, 0, 32)); self::hash_update($hs, self::substr($publicKey, 0, 32)); /** @var resource $hs */ $hs = self::updateHashWithFile($hs, $fp, $size); /** @var string $hDigest */ $hDigest = hash_final($hs, true); /** @var string $h */ $h = ParagonIE_Sodium_Core32_Ed25519::sc_reduce($hDigest) . self::substr($hDigest, 32); /** @var ParagonIE_Sodium_Core32_Curve25519_Ge_P2 $R */ $R = ParagonIE_Sodium_Core32_Ed25519::ge_double_scalarmult_vartime( $h, $A, self::substr($sig, 32) ); /** @var string $rcheck */ $rcheck = ParagonIE_Sodium_Core32_Ed25519::ge_tobytes($R); // Close the file handle fclose($fp); // Reset ParagonIE_Sodium_Compat::$fastMult to what it was before. ParagonIE_Sodium_Compat::$fastMult = $orig; return self::verify_32($rcheck, self::substr($sig, 0, 32)); } /** * Encrypt a file (32-bit) * * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ protected static function secretbox_encrypt_core32($ifp, $ofp, $mlen, $nonce, $key) { $plaintext = fread($ifp, 32); if (!is_string($plaintext)) { throw new SodiumException('Could not read input file'); } $first32 = self::ftell($ifp); /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $realNonce */ $realNonce = ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = str_repeat("\x00", 32); /** @var int $mlen - Length of the plaintext message */ $mlen0 = $mlen; if ($mlen0 > 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES) { $mlen0 = 64 - ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES; } $block0 .= ParagonIE_Sodium_Core32_Util::substr($plaintext, 0, $mlen0); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor( $block0, $realNonce, $subkey ); $state = new ParagonIE_Sodium_Core32_Poly1305_State( ParagonIE_Sodium_Core32_Util::substr( $block0, 0, ParagonIE_Sodium_Crypto::onetimeauth_poly1305_KEYBYTES ) ); // Pre-write 16 blank bytes for the Poly1305 tag $start = self::ftell($ofp); fwrite($ofp, str_repeat("\x00", 16)); /** @var string $c */ $cBlock = ParagonIE_Sodium_Core32_Util::substr( $block0, ParagonIE_Sodium_Crypto::secretbox_xsalsa20poly1305_ZEROBYTES ); $state->update($cBlock); fwrite($ofp, $cBlock); $mlen -= 32; /** @var int $iter */ $iter = 1; /** @var int $incr */ $incr = self::BUFFER_SIZE >> 6; /* * Set the cursor to the end of the first half-block. All future bytes will * generated from salsa20_xor_ic, starting from 1 (second block). */ fseek($ifp, $first32, SEEK_SET); while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $plaintext = fread($ifp, $blockSize); if (!is_string($plaintext)) { throw new SodiumException('Could not read input file'); } $cBlock = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( $plaintext, $realNonce, $iter, $subkey ); fwrite($ofp, $cBlock, $blockSize); $state->update($cBlock); $mlen -= $blockSize; $iter += $incr; } try { ParagonIE_Sodium_Compat::memzero($block0); ParagonIE_Sodium_Compat::memzero($subkey); } catch (SodiumException $ex) { $block0 = null; $subkey = null; } $end = self::ftell($ofp); /* * Write the Poly1305 authentication tag that provides integrity * over the ciphertext (encrypt-then-MAC) */ fseek($ofp, $start, SEEK_SET); fwrite($ofp, $state->finish(), ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES); fseek($ofp, $end, SEEK_SET); unset($state); return true; } /** * Decrypt a file (32-bit) * * @param resource $ifp * @param resource $ofp * @param int $mlen * @param string $nonce * @param string $key * @return bool * @throws SodiumException * @throws TypeError */ protected static function secretbox_decrypt_core32($ifp, $ofp, $mlen, $nonce, $key) { $tag = fread($ifp, 16); if (!is_string($tag)) { throw new SodiumException('Could not read input file'); } /** @var string $subkey */ $subkey = ParagonIE_Sodium_Core32_HSalsa20::hsalsa20($nonce, $key); /** @var string $realNonce */ $realNonce = ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8); /** @var string $block0 */ $block0 = ParagonIE_Sodium_Core32_Salsa20::salsa20( 64, ParagonIE_Sodium_Core32_Util::substr($nonce, 16, 8), $subkey ); /* Verify the Poly1305 MAC -before- attempting to decrypt! */ $state = new ParagonIE_Sodium_Core32_Poly1305_State(self::substr($block0, 0, 32)); if (!self::onetimeauth_verify_core32($state, $ifp, $tag, $mlen)) { throw new SodiumException('Invalid MAC'); } /* * Set the cursor to the end of the first half-block. All future bytes will * generated from salsa20_xor_ic, starting from 1 (second block). */ $first32 = fread($ifp, 32); if (!is_string($first32)) { throw new SodiumException('Could not read input file'); } $first32len = self::strlen($first32); fwrite( $ofp, self::xorStrings( self::substr($block0, 32, $first32len), self::substr($first32, 0, $first32len) ) ); $mlen -= 32; /** @var int $iter */ $iter = 1; /** @var int $incr */ $incr = self::BUFFER_SIZE >> 6; /* Decrypts ciphertext, writes to output file. */ while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $ciphertext = fread($ifp, $blockSize); if (!is_string($ciphertext)) { throw new SodiumException('Could not read input file'); } $pBlock = ParagonIE_Sodium_Core32_Salsa20::salsa20_xor_ic( $ciphertext, $realNonce, $iter, $subkey ); fwrite($ofp, $pBlock, $blockSize); $mlen -= $blockSize; $iter += $incr; } return true; } /** * One-time message authentication for 32-bit systems * * @param ParagonIE_Sodium_Core32_Poly1305_State $state * @param resource $ifp * @param string $tag * @param int $mlen * @return bool * @throws SodiumException * @throws TypeError */ protected static function onetimeauth_verify_core32( ParagonIE_Sodium_Core32_Poly1305_State $state, $ifp, $tag = '', $mlen = 0 ) { /** @var int $pos */ $pos = self::ftell($ifp); while ($mlen > 0) { $blockSize = $mlen > self::BUFFER_SIZE ? self::BUFFER_SIZE : $mlen; $ciphertext = fread($ifp, $blockSize); if (!is_string($ciphertext)) { throw new SodiumException('Could not read input file'); } $state->update($ciphertext); $mlen -= $blockSize; } $res = ParagonIE_Sodium_Core32_Util::verify_16($tag, $state->finish()); fseek($ifp, $pos, SEEK_SET); return $res; } /** * @param resource $resource * @return int * @throws SodiumException */ private static function ftell($resource) { $return = ftell($resource); if (!is_int($return)) { throw new SodiumException('ftell() returned false'); } return (int) $return; } } { "name": "paragonie/sodium_compat", "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists", "keywords": [ "PHP", "cryptography", "elliptic curve", "elliptic curve cryptography", "Pure-PHP cryptography", "side-channel resistant", "Curve25519", "X25519", "ECDH", "Elliptic Curve Diffie-Hellman", "Ed25519", "RFC 7748", "RFC 8032", "EdDSA", "Edwards-curve Digital Signature Algorithm", "ChaCha20", "Salsa20", "Xchacha20", "Xsalsa20", "Poly1305", "BLAKE2b", "public-key cryptography", "secret-key cryptography", "AEAD", "Chapoly", "Salpoly", "ChaCha20-Poly1305", "XSalsa20-Poly1305", "XChaCha20-Poly1305", "encryption", "authentication", "libsodium" ], "license": "ISC", "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com" }, { "name": "Frank Denis", "email": "jedisct1@pureftpd.org" } ], "autoload": { "files": ["autoload.php"] }, "require": { "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8", "paragonie/random_compat": ">=1" }, "require-dev": { "phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9" }, "scripts": { "test": "phpunit" }, "suggest": { "ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.", "ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security." } } <?php namespace ParagonIE\Sodium\Core; class Ed25519 extends \ParagonIE_Sodium_Core_Ed25519 { } <?php namespace ParagonIE\Sodium\Core; class XChaCha20 extends \ParagonIE_Sodium_Core_XChaCha20 { } <?php namespace ParagonIE\Sodium\Core; class HChaCha20 extends \ParagonIE_Sodium_Core_HChaCha20 { } <?php namespace ParagonIE\Sodium\Core; class Curve25519 extends \ParagonIE_Sodium_Core_Curve25519 { } <?php namespace ParagonIE\Sodium\Core; class SipHash extends \ParagonIE_Sodium_Core_SipHash { } <?php namespace ParagonIE\Sodium\Core; class HSalsa20 extends \ParagonIE_Sodium_Core_HSalsa20 { } <?php namespace ParagonIE\Sodium\Core\Poly1305; class State extends \ParagonIE_Sodium_Core_Poly1305_State { } <?php namespace ParagonIE\Sodium\Core; class ChaCha20 extends \ParagonIE_Sodium_Core_ChaCha20 { } <?php namespace ParagonIE\Sodium\Core\Curve25519; class Fe extends \ParagonIE_Sodium_Core_Curve25519_Fe { } <?php namespace ParagonIE\Sodium\Core\Curve25519; class H extends \ParagonIE_Sodium_Core_Curve25519_H { } <?php namespace ParagonIE\Sodium\Core\Curve25519\Ge; class Cached extends \ParagonIE_Sodium_Core_Curve25519_Ge_Cached { } <?php namespace ParagonIE\Sodium\Core\Curve25519\Ge; class P3 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P3 { } <?php namespace ParagonIE\Sodium\Core\Curve25519\Ge; class P1p1 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 { } <?php namespace ParagonIE\Sodium\Core\Curve25519\Ge; class Precomp extends \ParagonIE_Sodium_Core_Curve25519_Ge_Precomp { } <?php namespace ParagonIE\Sodium\Core\Curve25519\Ge; class P2 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P2 { } <?php namespace ParagonIE\Sodium\Core; class Poly1305 extends \ParagonIE_Sodium_Core_Poly1305 { } <?php namespace ParagonIE\Sodium\Core\ChaCha20; class IetfCtx extends \ParagonIE_Sodium_Core_ChaCha20_IetfCtx { } <?php namespace ParagonIE\Sodium\Core\ChaCha20; class Ctx extends \ParagonIE_Sodium_Core_ChaCha20_Ctx { } <?php namespace ParagonIE\Sodium\Core; class BLAKE2b extends \ParagonIE_Sodium_Core_BLAKE2b { } <?php namespace ParagonIE\Sodium\Core; class Util extends \ParagonIE_Sodium_Core_Util { } <?php namespace ParagonIE\Sodium\Core; class Salsa20 extends \ParagonIE_Sodium_Core_Salsa20 { } <?php namespace ParagonIE\Sodium\Core; class X25519 extends \ParagonIE_Sodium_Core_X25519 { } <?php namespace ParagonIE\Sodium\Core; class Xsalsa20 extends \ParagonIE_Sodium_Core_XSalsa20 { } <?php namespace ParagonIE\Sodium; class Crypto extends \ParagonIE_Sodium_Crypto { } <?php namespace ParagonIE\Sodium; class Compat extends \ParagonIE_Sodium_Compat { } <?php if (PHP_VERSION_ID < 70000) { if (!is_callable('sodiumCompatAutoloader')) { /** * Sodium_Compat autoloader. * * @param string $class Class name to be autoloaded. * * @return bool Stop autoloading? */ function sodiumCompatAutoloader($class) { $namespace = 'ParagonIE_Sodium_'; // Does the class use the namespace prefix? $len = strlen($namespace); if (strncmp($namespace, $class, $len) !== 0) { // no, move to the next registered autoloader return false; } // Get the relative class name $relative_class = substr($class, $len); // Replace the namespace prefix with the base directory, replace namespace // separators with directory separators in the relative class name, append // with .php $file = dirname(__FILE__) . '/src/' . str_replace('_', '/', $relative_class) . '.php'; // if the file exists, require it if (file_exists($file)) { require_once $file; return true; } return false; } // Now that we have an autoloader, let's register it! spl_autoload_register('sodiumCompatAutoloader'); } } else { require_once dirname(__FILE__) . '/autoload-php7.php'; } /* Explicitly, always load the Compat class: */ if (!class_exists('ParagonIE_Sodium_Compat', false)) { require_once dirname(__FILE__) . '/src/Compat.php'; } if (!class_exists('SodiumException', false)) { require_once dirname(__FILE__) . '/src/SodiumException.php'; } if (PHP_VERSION_ID >= 50300) { // Namespaces didn't exist before 5.3.0, so don't even try to use this // unless PHP >= 5.3.0 require_once dirname(__FILE__) . '/lib/namespaced.php'; require_once dirname(__FILE__) . '/lib/sodium_compat.php'; if (!defined('SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES')) { require_once dirname(__FILE__) . '/lib/php84compat_const.php'; } } else { require_once dirname(__FILE__) . '/src/PHP52/SplFixedArray.php'; } if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) { if (PHP_VERSION_ID >= 50300 && !defined('SODIUM_CRYPTO_SCALARMULT_BYTES')) { require_once dirname(__FILE__) . '/lib/php72compat_const.php'; } if (PHP_VERSION_ID >= 70000) { assert(class_exists('ParagonIE_Sodium_Compat'), 'Possible filesystem/autoloader bug?'); } else { assert(class_exists('ParagonIE_Sodium_Compat')); } require_once(dirname(__FILE__) . '/lib/php72compat.php'); } elseif (!function_exists('sodium_crypto_stream_xchacha20_xor')) { // Older versions of {PHP, ext/sodium} will not define these require_once(dirname(__FILE__) . '/lib/php72compat.php'); } if (PHP_VERSION_ID < 80400 || !extension_loaded('sodium')) { require_once dirname(__FILE__) . '/lib/php84compat.php'; } require_once(dirname(__FILE__) . '/lib/stream-xchacha20.php'); require_once(dirname(__FILE__) . '/lib/ristretto255.php'); <?php /** * PHPMailer RFC821 SMTP email transport class. * PHP Version 5.5. * * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project * * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> * @author Jim Jagielski (jimjag) <jimjag@gmail.com> * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> * @author Brent R. Matzelle (original founder) * @copyright 2012 - 2020 Marcus Bointon * @copyright 2010 - 2012 Jim Jagielski * @copyright 2004 - 2009 Andy Prevost * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License * @note This program is distributed in the hope that it will be useful - WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ namespace PHPMailer\PHPMailer; /** * PHPMailer RFC821 SMTP email transport class. * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. * * @author Chris Ryan * @author Marcus Bointon <phpmailer@synchromedia.co.uk> */ class SMTP { /** * The PHPMailer SMTP version number. * * @var string */ const VERSION = '6.9.3'; /** * SMTP line break constant. * * @var string */ const LE = "\r\n"; /** * The SMTP port to use if one is not specified. * * @var int */ const DEFAULT_PORT = 25; /** * The SMTPs port to use if one is not specified. * * @var int */ const DEFAULT_SECURE_PORT = 465; /** * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, * *excluding* a trailing CRLF break. * * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.6 * * @var int */ const MAX_LINE_LENGTH = 998; /** * The maximum line length allowed for replies in RFC 5321 section 4.5.3.1.5, * *including* a trailing CRLF line break. * * @see https://www.rfc-editor.org/rfc/rfc5321#section-4.5.3.1.5 * * @var int */ const MAX_REPLY_LENGTH = 512; /** * Debug level for no output. * * @var int */ const DEBUG_OFF = 0; /** * Debug level to show client -> server messages. * * @var int */ const DEBUG_CLIENT = 1; /** * Debug level to show client -> server and server -> client messages. * * @var int */ const DEBUG_SERVER = 2; /** * Debug level to show connection status, client -> server and server -> client messages. * * @var int */ const DEBUG_CONNECTION = 3; /** * Debug level to show all messages. * * @var int */ const DEBUG_LOWLEVEL = 4; /** * Debug output level. * Options: * * self::DEBUG_OFF (`0`) No debug output, default * * self::DEBUG_CLIENT (`1`) Client commands * * self::DEBUG_SERVER (`2`) Client commands and server responses * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages. * * @var int */ public $do_debug = self::DEBUG_OFF; /** * How to handle debug output. * Options: * * `echo` Output plain-text as-is, appropriate for CLI * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output * * `error_log` Output to error log as configured in php.ini * Alternatively, you can provide a callable expecting two params: a message string and the debug level: * * ```php * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; * ``` * * Alternatively, you can pass in an instance of a PSR-3 compatible logger, though only `debug` * level output is used: * * ```php * $mail->Debugoutput = new myPsr3Logger; * ``` * * @var string|callable|\Psr\Log\LoggerInterface */ public $Debugoutput = 'echo'; /** * Whether to use VERP. * * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path * @see https://www.postfix.org/VERP_README.html Info on VERP * * @var bool */ public $do_verp = false; /** * The timeout value for connection, in seconds. * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. * * @see https://www.rfc-editor.org/rfc/rfc2821#section-4.5.3.2 * * @var int */ public $Timeout = 300; /** * How long to wait for commands to complete, in seconds. * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2. * * @var int */ public $Timelimit = 300; /** * Patterns to extract an SMTP transaction id from reply to a DATA command. * The first capture group in each regex will be used as the ID. * MS ESMTP returns the message ID, which may not be correct for internal tracking. * * @var string[] */ protected $smtp_transaction_id_patterns = [ 'exim' => '/[\d]{3} OK id=(.*)/', 'sendmail' => '/[\d]{3} 2\.0\.0 (.*) Message/', 'postfix' => '/[\d]{3} 2\.0\.0 Ok: queued as (.*)/', 'Microsoft_ESMTP' => '/[0-9]{3} 2\.[\d]\.0 (.*)@(?:.*) Queued mail for delivery/', 'Amazon_SES' => '/[\d]{3} Ok (.*)/', 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', 'CampaignMonitor' => '/[\d]{3} 2\.0\.0 OK:([a-zA-Z\d]{48})/', 'Haraka' => '/[\d]{3} Message Queued \((.*)\)/', 'ZoneMTA' => '/[\d]{3} Message queued as (.*)/', 'Mailjet' => '/[\d]{3} OK queued as (.*)/', ]; /** * Allowed SMTP XCLIENT attributes. * Must be allowed by the SMTP server. EHLO response is not checked. * * @see https://www.postfix.org/XCLIENT_README.html * * @var array */ public static $xclient_allowed_attributes = [ 'NAME', 'ADDR', 'PORT', 'PROTO', 'HELO', 'LOGIN', 'DESTADDR', 'DESTPORT' ]; /** * The last transaction ID issued in response to a DATA command, * if one was detected. * * @var string|bool|null */ protected $last_smtp_transaction_id; /** * The socket for the server connection. * * @var ?resource */ protected $smtp_conn; /** * Error information, if any, for the last SMTP command. * * @var array */ protected $error = [ 'error' => '', 'detail' => '', 'smtp_code' => '', 'smtp_code_ex' => '', ]; /** * The reply the server sent to us for HELO. * If null, no HELO string has yet been received. * * @var string|null */ protected $helo_rply; /** * The set of SMTP extensions sent in reply to EHLO command. * Indexes of the array are extension names. * Value at index 'HELO' or 'EHLO' (according to command that was sent) * represents the server name. In case of HELO it is the only element of the array. * Other values can be boolean TRUE or an array containing extension options. * If null, no HELO/EHLO string has yet been received. * * @var array|null */ protected $server_caps; /** * The most recent reply received from the server. * * @var string */ protected $last_reply = ''; /** * Output debugging info via a user-selected method. * * @param string $str Debug string to output * @param int $level The debug level of this message; see DEBUG_* constants * * @see SMTP::$Debugoutput * @see SMTP::$do_debug */ protected function edebug($str, $level = 0) { if ($level > $this->do_debug) { return; } //Is this a PSR-3 logger? if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { //Remove trailing line breaks potentially added by calls to SMTP::client_send() $this->Debugoutput->debug(rtrim($str, "\r\n")); return; } //Avoid clash with built-in function names if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { call_user_func($this->Debugoutput, $str, $level); return; } switch ($this->Debugoutput) { case 'error_log': //Don't output, just log /** @noinspection ForgottenDebugOutputInspection */ error_log($str); break; case 'html': //Cleans up output a bit for a better looking, HTML-safe output echo gmdate('Y-m-d H:i:s'), ' ', htmlentities( preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8' ), "<br>\n"; break; case 'echo': default: //Normalize line breaks $str = preg_replace('/\r\n|\r/m', "\n", $str); echo gmdate('Y-m-d H:i:s'), "\t", //Trim trailing space trim( //Indent for readability, except for trailing break str_replace( "\n", "\n \t ", trim($str) ) ), "\n"; } } /** * Connect to an SMTP server. * * @param string $host SMTP server IP or host name * @param int $port The port number to connect to * @param int $timeout How long to wait for the connection to open * @param array $options An array of options for stream_context_create() * * @return bool */ public function connect($host, $port = null, $timeout = 30, $options = []) { //Clear errors to avoid confusion $this->setError(''); //Make sure we are __not__ connected if ($this->connected()) { //Already connected, generate error $this->setError('Already connected to a server'); return false; } if (empty($port)) { $port = self::DEFAULT_PORT; } //Connect to the SMTP server $this->edebug( "Connection: opening to $host:$port, timeout=$timeout, options=" . (count($options) > 0 ? var_export($options, true) : 'array()'), self::DEBUG_CONNECTION ); $this->smtp_conn = $this->getSMTPConnection($host, $port, $timeout, $options); if ($this->smtp_conn === false) { //Error info already set inside `getSMTPConnection()` return false; } $this->edebug('Connection: opened', self::DEBUG_CONNECTION); //Get any announcement $this->last_reply = $this->get_lines(); $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); $responseCode = (int)substr($this->last_reply, 0, 3); if ($responseCode === 220) { return true; } //Anything other than a 220 response means something went wrong //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error //https://www.rfc-editor.org/rfc/rfc5321#section-3.1 if ($responseCode === 554) { $this->quit(); } //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down) $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION); $this->close(); return false; } /** * Create connection to the SMTP server. * * @param string $host SMTP server IP or host name * @param int $port The port number to connect to * @param int $timeout How long to wait for the connection to open * @param array $options An array of options for stream_context_create() * * @return false|resource */ protected function getSMTPConnection($host, $port = null, $timeout = 30, $options = []) { static $streamok; //This is enabled by default since 5.0.0 but some providers disable it //Check this once and cache the result if (null === $streamok) { $streamok = function_exists('stream_socket_client'); } $errno = 0; $errstr = ''; if ($streamok) { $socket_context = stream_context_create($options); set_error_handler(function () { call_user_func_array([$this, 'errorHandler'], func_get_args()); }); $connection = stream_socket_client( $host . ':' . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $socket_context ); } else { //Fall back to fsockopen which should work in more places, but is missing some features $this->edebug( 'Connection: stream_socket_client not available, falling back to fsockopen', self::DEBUG_CONNECTION ); set_error_handler(function () { call_user_func_array([$this, 'errorHandler'], func_get_args()); }); $connection = fsockopen( $host, $port, $errno, $errstr, $timeout ); } restore_error_handler(); //Verify we connected properly if (!is_resource($connection)) { $this->setError( 'Failed to connect to server', '', (string) $errno, $errstr ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] . ": $errstr ($errno)", self::DEBUG_CLIENT ); return false; } //SMTP server can take longer to respond, give longer timeout for first read //Windows does not have support for this timeout function if (strpos(PHP_OS, 'WIN') !== 0) { $max = (int)ini_get('max_execution_time'); //Don't bother if unlimited, or if set_time_limit is disabled if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) { @set_time_limit($timeout); } stream_set_timeout($connection, $timeout, 0); } return $connection; } /** * Initiate a TLS (encrypted) session. * * @return bool */ public function startTLS() { if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { return false; } //Allow the best TLS version(s) we can $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT; //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT //so add them back in manually if we can if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; } //Begin encrypted connection set_error_handler(function () { call_user_func_array([$this, 'errorHandler'], func_get_args()); }); $crypto_ok = stream_socket_enable_crypto( $this->smtp_conn, true, $crypto_method ); restore_error_handler(); return (bool) $crypto_ok; } /** * Perform SMTP authentication. * Must be run after hello(). * * @see hello() * * @param string $username The user name * @param string $password The password * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) * @param OAuthTokenProvider $OAuth An optional OAuthTokenProvider instance for XOAUTH2 authentication * * @return bool True if successfully authenticated */ public function authenticate( $username, $password, $authtype = null, $OAuth = null ) { if (!$this->server_caps) { $this->setError('Authentication is not allowed before HELO/EHLO'); return false; } if (array_key_exists('EHLO', $this->server_caps)) { //SMTP extensions are available; try to find a proper authentication method if (!array_key_exists('AUTH', $this->server_caps)) { $this->setError('Authentication is not allowed at this stage'); //'at this stage' means that auth may be allowed after the stage changes //e.g. after STARTTLS return false; } $this->edebug('Auth method requested: ' . ($authtype ?: 'UNSPECIFIED'), self::DEBUG_LOWLEVEL); $this->edebug( 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), self::DEBUG_LOWLEVEL ); //If we have requested a specific auth type, check the server supports it before trying others if (null !== $authtype && !in_array($authtype, $this->server_caps['AUTH'], true)) { $this->edebug('Requested auth method not available: ' . $authtype, self::DEBUG_LOWLEVEL); $authtype = null; } if (empty($authtype)) { //If no auth mechanism is specified, attempt to use these, in this order //Try CRAM-MD5 first as it's more secure than the others foreach (['CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2'] as $method) { if (in_array($method, $this->server_caps['AUTH'], true)) { $authtype = $method; break; } } if (empty($authtype)) { $this->setError('No supported authentication methods found'); return false; } $this->edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL); } if (!in_array($authtype, $this->server_caps['AUTH'], true)) { $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); return false; } } elseif (empty($authtype)) { $authtype = 'LOGIN'; } switch ($authtype) { case 'PLAIN': //Start authentication if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { return false; } //Send encoded username and password if ( //Format from https://www.rfc-editor.org/rfc/rfc4616#section-2 //We skip the first field (it's forgery), so the string starts with a null byte !$this->sendCommand( 'User & Password', base64_encode("\0" . $username . "\0" . $password), 235 ) ) { return false; } break; case 'LOGIN': //Start authentication if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { return false; } if (!$this->sendCommand('Username', base64_encode($username), 334)) { return false; } if (!$this->sendCommand('Password', base64_encode($password), 235)) { return false; } break; case 'CRAM-MD5': //Start authentication if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { return false; } //Get the challenge $challenge = base64_decode(substr($this->last_reply, 4)); //Build the response $response = $username . ' ' . $this->hmac($challenge, $password); //send encoded credentials return $this->sendCommand('Username', base64_encode($response), 235); case 'XOAUTH2': //The OAuth instance must be set up prior to requesting auth. if (null === $OAuth) { return false; } $oauth = $OAuth->getOauth64(); //Start authentication if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { return false; } break; default: $this->setError("Authentication method \"$authtype\" is not supported"); return false; } return true; } /** * Calculate an MD5 HMAC hash. * Works like hash_hmac('md5', $data, $key) * in case that function is not available. * * @param string $data The data to hash * @param string $key The key to hash with * * @return string */ protected function hmac($data, $key) { if (function_exists('hash_hmac')) { return hash_hmac('md5', $data, $key); } //The following borrowed from //https://www.php.net/manual/en/function.mhash.php#27225 //RFC 2104 HMAC implementation for php. //Creates an md5 HMAC. //Eliminates the need to install mhash to compute a HMAC //by Lance Rushing $bytelen = 64; //byte length for md5 if (strlen($key) > $bytelen) { $key = pack('H*', md5($key)); } $key = str_pad($key, $bytelen, chr(0x00)); $ipad = str_pad('', $bytelen, chr(0x36)); $opad = str_pad('', $bytelen, chr(0x5c)); $k_ipad = $key ^ $ipad; $k_opad = $key ^ $opad; return md5($k_opad . pack('H*', md5($k_ipad . $data))); } /** * Check connection state. * * @return bool True if connected */ public function connected() { if (is_resource($this->smtp_conn)) { $sock_status = stream_get_meta_data($this->smtp_conn); if ($sock_status['eof']) { //The socket is valid but we are not connected $this->edebug( 'SMTP NOTICE: EOF caught while checking if connected', self::DEBUG_CLIENT ); $this->close(); return false; } return true; //everything looks good } return false; } /** * Close the socket and clean up the state of the class. * Don't use this function without first trying to use QUIT. * * @see quit() */ public function close() { $this->server_caps = null; $this->helo_rply = null; if (is_resource($this->smtp_conn)) { //Close the connection and cleanup fclose($this->smtp_conn); $this->smtp_conn = null; //Makes for cleaner serialization $this->edebug('Connection: closed', self::DEBUG_CONNECTION); } } /** * Send an SMTP DATA command. * Issues a data command and sends the msg_data to the server, * finalizing the mail transaction. $msg_data is the message * that is to be sent with the headers. Each header needs to be * on a single line followed by a <CRLF> with the message headers * and the message body being separated by an additional <CRLF>. * Implements RFC 821: DATA <CRLF>. * * @param string $msg_data Message data to send * * @return bool */ public function data($msg_data) { //This will use the standard timelimit if (!$this->sendCommand('DATA', 'DATA', 354)) { return false; } /* The server is ready to accept data! * According to rfc821 we should not send more than 1000 characters on a single line (including the LE) * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into * smaller lines to fit within the limit. * We will also look for lines that start with a '.' and prepend an additional '.'. * NOTE: this does not count towards line-length limit. */ //Normalize line breaks before exploding $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field * of the first line (':' separated) does not contain a space then it _should_ be a header, and we will * process all lines before a blank line as headers. */ $field = substr($lines[0], 0, strpos($lines[0], ':')); $in_headers = false; if (!empty($field) && strpos($field, ' ') === false) { $in_headers = true; } foreach ($lines as $line) { $lines_out = []; if ($in_headers && $line === '') { $in_headers = false; } //Break this line up into several smaller lines if it's too long //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len), while (isset($line[self::MAX_LINE_LENGTH])) { //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on //so as to avoid breaking in the middle of a word $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); //Deliberately matches both false and 0 if (!$pos) { //No nice break found, add a hard break $pos = self::MAX_LINE_LENGTH - 1; $lines_out[] = substr($line, 0, $pos); $line = substr($line, $pos); } else { //Break at the found point $lines_out[] = substr($line, 0, $pos); //Move along by the amount we dealt with $line = substr($line, $pos + 1); } //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1 if ($in_headers) { $line = "\t" . $line; } } $lines_out[] = $line; //Send the lines to the server foreach ($lines_out as $line_out) { //Dot-stuffing as per RFC5321 section 4.5.2 //https://www.rfc-editor.org/rfc/rfc5321#section-4.5.2 if (!empty($line_out) && $line_out[0] === '.') { $line_out = '.' . $line_out; } $this->client_send($line_out . static::LE, 'DATA'); } } //Message data has been sent, complete the command //Increase timelimit for end of DATA command $savetimelimit = $this->Timelimit; $this->Timelimit *= 2; $result = $this->sendCommand('DATA END', '.', 250); $this->recordLastTransactionID(); //Restore timelimit $this->Timelimit = $savetimelimit; return $result; } /** * Send an SMTP HELO or EHLO command. * Used to identify the sending server to the receiving server. * This makes sure that client and server are in a known state. * Implements RFC 821: HELO <SP> <domain> <CRLF> * and RFC 2821 EHLO. * * @param string $host The host name or IP to connect to * * @return bool */ public function hello($host = '') { //Try extended hello first (RFC 2821) if ($this->sendHello('EHLO', $host)) { return true; } //Some servers shut down the SMTP service here (RFC 5321) if (substr($this->helo_rply, 0, 3) == '421') { return false; } return $this->sendHello('HELO', $host); } /** * Send an SMTP HELO or EHLO command. * Low-level implementation used by hello(). * * @param string $hello The HELO string * @param string $host The hostname to say we are * * @return bool * * @see hello() */ protected function sendHello($hello, $host) { $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); $this->helo_rply = $this->last_reply; if ($noerror) { $this->parseHelloFields($hello); } else { $this->server_caps = null; } return $noerror; } /** * Parse a reply to HELO/EHLO command to discover server extensions. * In case of HELO, the only parameter that can be discovered is a server name. * * @param string $type `HELO` or `EHLO` */ protected function parseHelloFields($type) { $this->server_caps = []; $lines = explode("\n", $this->helo_rply); foreach ($lines as $n => $s) { //First 4 chars contain response code followed by - or space $s = trim(substr($s, 4)); if (empty($s)) { continue; } $fields = explode(' ', $s); if (!empty($fields)) { if (!$n) { $name = $type; $fields = $fields[0]; } else { $name = array_shift($fields); switch ($name) { case 'SIZE': $fields = ($fields ? $fields[0] : 0); break; case 'AUTH': if (!is_array($fields)) { $fields = []; } break; default: $fields = true; } } $this->server_caps[$name] = $fields; } } } /** * Send an SMTP MAIL command. * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more recipient * commands may be called followed by a data command. * Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>. * * @param string $from Source address of this message * * @return bool */ public function mail($from) { $useVerp = ($this->do_verp ? ' XVERP' : ''); return $this->sendCommand( 'MAIL FROM', 'MAIL FROM:<' . $from . '>' . $useVerp, 250 ); } /** * Send an SMTP QUIT command. * Closes the socket if there is no error or the $close_on_error argument is true. * Implements from RFC 821: QUIT <CRLF>. * * @param bool $close_on_error Should the connection close if an error occurs? * * @return bool */ public function quit($close_on_error = true) { $noerror = $this->sendCommand('QUIT', 'QUIT', 221); $err = $this->error; //Save any error if ($noerror || $close_on_error) { $this->close(); $this->error = $err; //Restore any error from the quit command } return $noerror; } /** * Send an SMTP RCPT command. * Sets the TO argument to $toaddr. * Returns true if the recipient was accepted false if it was rejected. * Implements from RFC 821: RCPT <SP> TO:<forward-path> <CRLF>. * * @param string $address The address the message is being sent to * @param string $dsn Comma separated list of DSN notifications. NEVER, SUCCESS, FAILURE * or DELAY. If you specify NEVER all other notifications are ignored. * * @return bool */ public function recipient($address, $dsn = '') { if (empty($dsn)) { $rcpt = 'RCPT TO:<' . $address . '>'; } else { $dsn = strtoupper($dsn); $notify = []; if (strpos($dsn, 'NEVER') !== false) { $notify[] = 'NEVER'; } else { foreach (['SUCCESS', 'FAILURE', 'DELAY'] as $value) { if (strpos($dsn, $value) !== false) { $notify[] = $value; } } } $rcpt = 'RCPT TO:<' . $address . '> NOTIFY=' . implode(',', $notify); } return $this->sendCommand( 'RCPT TO', $rcpt, [250, 251] ); } /** * Send SMTP XCLIENT command to server and check its return code. * * @return bool True on success */ public function xclient(array $vars) { $xclient_options = ""; foreach ($vars as $key => $value) { if (in_array($key, SMTP::$xclient_allowed_attributes)) { $xclient_options .= " {$key}={$value}"; } } if (!$xclient_options) { return true; } return $this->sendCommand('XCLIENT', 'XCLIENT' . $xclient_options, 250); } /** * Send an SMTP RSET command. * Abort any transaction that is currently in progress. * Implements RFC 821: RSET <CRLF>. * * @return bool True on success */ public function reset() { return $this->sendCommand('RSET', 'RSET', 250); } /** * Send a command to an SMTP server and check its return code. * * @param string $command The command name - not sent to the server * @param string $commandstring The actual command to send * @param int|array $expect One or more expected integer success codes * * @return bool True on success */ protected function sendCommand($command, $commandstring, $expect) { if (!$this->connected()) { $this->setError("Called $command without being connected"); return false; } //Reject line breaks in all commands if ((strpos($commandstring, "\n") !== false) || (strpos($commandstring, "\r") !== false)) { $this->setError("Command '$command' contained line breaks"); return false; } $this->client_send($commandstring . static::LE, $command); $this->last_reply = $this->get_lines(); //Fetch SMTP code and possible error code explanation $matches = []; if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) { $code = (int) $matches[1]; $code_ex = (count($matches) > 2 ? $matches[2] : null); //Cut off error code from each response line $detail = preg_replace( "/{$code}[ -]" . ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m', '', $this->last_reply ); } else { //Fall back to simple parsing if regex fails $code = (int) substr($this->last_reply, 0, 3); $code_ex = null; $detail = substr($this->last_reply, 4); } $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); if (!in_array($code, (array) $expect, true)) { $this->setError( "$command command failed", $detail, $code, $code_ex ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, self::DEBUG_CLIENT ); return false; } //Don't clear the error store when using keepalive if ($command !== 'RSET') { $this->setError(''); } return true; } /** * Send an SMTP SAML command. * Starts a mail transaction from the email address specified in $from. * Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more recipient * commands may be called followed by a data command. This command * will send the message to the users terminal if they are logged * in and send them an email. * Implements RFC 821: SAML <SP> FROM:<reverse-path> <CRLF>. * * @param string $from The address the message is from * * @return bool */ public function sendAndMail($from) { return $this->sendCommand('SAML', "SAML FROM:$from", 250); } /** * Send an SMTP VRFY command. * * @param string $name The name to verify * * @return bool */ public function verify($name) { return $this->sendCommand('VRFY', "VRFY $name", [250, 251]); } /** * Send an SMTP NOOP command. * Used to keep keep-alives alive, doesn't actually do anything. * * @return bool */ public function noop() { return $this->sendCommand('NOOP', 'NOOP', 250); } /** * Send an SMTP TURN command. * This is an optional command for SMTP that this class does not support. * This method is here to make the RFC821 Definition complete for this class * and _may_ be implemented in future. * Implements from RFC 821: TURN <CRLF>. * * @return bool */ public function turn() { $this->setError('The SMTP TURN command is not implemented'); $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); return false; } /** * Send raw data to the server. * * @param string $data The data to send * @param string $command Optionally, the command this is part of, used only for controlling debug output * * @return int|bool The number of bytes sent to the server or false on error */ public function client_send($data, $command = '') { //If SMTP transcripts are left enabled, or debug output is posted online //it can leak credentials, so hide credentials in all but lowest level if ( self::DEBUG_LOWLEVEL > $this->do_debug && in_array($command, ['User & Password', 'Username', 'Password'], true) ) { $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT); } else { $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT); } set_error_handler(function () { call_user_func_array([$this, 'errorHandler'], func_get_args()); }); $result = fwrite($this->smtp_conn, $data); restore_error_handler(); return $result; } /** * Get the latest error. * * @return array */ public function getError() { return $this->error; } /** * Get SMTP extensions available on the server. * * @return array|null */ public function getServerExtList() { return $this->server_caps; } /** * Get metadata about the SMTP server from its HELO/EHLO response. * The method works in three ways, dependent on argument value and current state: * 1. HELO/EHLO has not been sent - returns null and populates $this->error. * 2. HELO has been sent - * $name == 'HELO': returns server name * $name == 'EHLO': returns boolean false * $name == any other string: returns null and populates $this->error * 3. EHLO has been sent - * $name == 'HELO'|'EHLO': returns the server name * $name == any other string: if extension $name exists, returns True * or its options (e.g. AUTH mechanisms supported). Otherwise returns False. * * @param string $name Name of SMTP extension or 'HELO'|'EHLO' * * @return string|bool|null */ public function getServerExt($name) { if (!$this->server_caps) { $this->setError('No HELO/EHLO was sent'); return null; } if (!array_key_exists($name, $this->server_caps)) { if ('HELO' === $name) { return $this->server_caps['EHLO']; } if ('EHLO' === $name || array_key_exists('EHLO', $this->server_caps)) { return false; } $this->setError('HELO handshake was used; No information about server extensions available'); return null; } return $this->server_caps[$name]; } /** * Get the last reply from the server. * * @return string */ public function getLastReply() { return $this->last_reply; } /** * Read the SMTP server's response. * Either before eof or socket timeout occurs on the operation. * With SMTP we can tell if we have more lines to read if the * 4th character is '-' symbol. If it is a space then we don't * need to read anything else. * * @return string */ protected function get_lines() { //If the connection is bad, give up straight away if (!is_resource($this->smtp_conn)) { return ''; } $data = ''; $endtime = 0; stream_set_timeout($this->smtp_conn, $this->Timeout); if ($this->Timelimit > 0) { $endtime = time() + $this->Timelimit; } $selR = [$this->smtp_conn]; $selW = null; while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { //Must pass vars in here as params are by reference //solution for signals inspired by https://github.com/symfony/symfony/pull/6540 set_error_handler(function () { call_user_func_array([$this, 'errorHandler'], func_get_args()); }); $n = stream_select($selR, $selW, $selW, $this->Timelimit); restore_error_handler(); if ($n === false) { $message = $this->getError()['detail']; $this->edebug( 'SMTP -> get_lines(): select failed (' . $message . ')', self::DEBUG_LOWLEVEL ); //stream_select returns false when the `select` system call is interrupted //by an incoming signal, try the select again if (stripos($message, 'interrupted system call') !== false) { $this->edebug( 'SMTP -> get_lines(): retrying stream_select', self::DEBUG_LOWLEVEL ); $this->setError(''); continue; } break; } if (!$n) { $this->edebug( 'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL ); break; } //Deliberate noise suppression - errors are handled afterwards $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); $data .= $str; //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled), //or 4th character is a space or a line break char, we are done reading, break the loop. //String array access is a significant micro-optimisation over strlen if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") { break; } //Timed-out? Log and break $info = stream_get_meta_data($this->smtp_conn); if ($info['timed_out']) { $this->edebug( 'SMTP -> get_lines(): stream timed-out (' . $this->Timeout . ' sec)', self::DEBUG_LOWLEVEL ); break; } //Now check if reads took too long if ($endtime && time() > $endtime) { $this->edebug( 'SMTP -> get_lines(): timelimit reached (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL ); break; } } return $data; } /** * Enable or disable VERP address generation. * * @param bool $enabled */ public function setVerp($enabled = false) { $this->do_verp = $enabled; } /** * Get VERP address generation mode. * * @return bool */ public function getVerp() { return $this->do_verp; } /** * Set error messages and codes. * * @param string $message The error message * @param string $detail Further detail on the error * @param string $smtp_code An associated SMTP error code * @param string $smtp_code_ex Extended SMTP code */ protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') { $this->error = [ 'error' => $message, 'detail' => $detail, 'smtp_code' => $smtp_code, 'smtp_code_ex' => $smtp_code_ex, ]; } /** * Set debug output method. * * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it */ public function setDebugOutput($method = 'echo') { $this->Debugoutput = $method; } /** * Get debug output method. * * @return string */ public function getDebugOutput() { return $this->Debugoutput; } /** * Set debug output level. * * @param int $level */ public function setDebugLevel($level = 0) { $this->do_debug = $level; } /** * Get debug output level. * * @return int */ public function getDebugLevel() { return $this->do_debug; } /** * Set SMTP timeout. * * @param int $timeout The timeout duration in seconds */ public function setTimeout($timeout = 0) { $this->Timeout = $timeout; } /** * Get SMTP timeout. * * @return int */ public function getTimeout() { return $this->Timeout; } /** * Reports an error number and string. * * @param int $errno The error number returned by PHP * @param string $errmsg The error message returned by PHP * @param string $errfile The file the error occurred in * @param int $errline The line number the error occurred on */ protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0) { $notice = 'Connection failed.'; $this->setError( $notice, $errmsg, (string) $errno ); $this->edebug( "$notice Error #$errno: $errmsg [$errfile line $errline]", self::DEBUG_CONNECTION ); } /** * Extract and return the ID of the last SMTP transaction based on * a list of patterns provided in SMTP::$smtp_transaction_id_patterns. * Relies on the host providing the ID in response to a DATA command. * If no reply has been received yet, it will return null. * If no pattern was matched, it will return false. * * @return bool|string|null */ protected function recordLastTransactionID() { $reply = $this->getLastReply(); if (empty($reply)) { $this->last_smtp_transaction_id = null; } else { $this->last_smtp_transaction_id = false; foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { $matches = []; if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) { $this->last_smtp_transaction_id = trim($matches[1]); break; } } } return $this->last_smtp_transaction_id; } /** * Get the queue/transaction ID of the last SMTP transaction * If no reply has been received yet, it will return null. * If no pattern was matched, it will return false. * * @return bool|string|null * * @see recordLastTransactionID() */ public function getLastTransactionID() { return $this->last_smtp_transaction_id; } } <?php /** * HTTP API: WP_HTTP_Requests_Response class * * @package WordPress * @subpackage HTTP * @since 4.6.0 */ /** * Core wrapper object for a WpOrg\Requests\Response for standardization. * * @since 4.6.0 * * @see WP_HTTP_Response */ class WP_HTTP_Requests_Response extends WP_HTTP_Response { /** * Requests Response object. * * @since 4.6.0 * @var \WpOrg\Requests\Response */ protected $response; /** * Filename the response was saved to. * * @since 4.6.0 * @var string|null */ protected $filename; /** * Constructor. * * @since 4.6.0 * * @param \WpOrg\Requests\Response $response HTTP response. * @param string $filename Optional. File name. Default empty. */ public function __construct( WpOrg\Requests\Response $response, $filename = '' ) { $this->response = $response; $this->filename = $filename; } /** * Retrieves the response object for the request. * * @since 4.6.0 * * @return WpOrg\Requests\Response HTTP response. */ public function get_response_object() { return $this->response; } /** * Retrieves headers associated with the response. * * @since 4.6.0 * * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary Map of header name to header value. */ public function get_headers() { // Ensure headers remain case-insensitive. $converted = new WpOrg\Requests\Utility\CaseInsensitiveDictionary(); foreach ( $this->response->headers->getAll() as $key => $value ) { if ( count( $value ) === 1 ) { $converted[ $key ] = $value[0]; } else { $converted[ $key ] = $value; } } return $converted; } /** * Sets all header values. * * @since 4.6.0 * * @param array $headers Map of header name to header value. */ public function set_headers( $headers ) { $this->response->headers = new WpOrg\Requests\Response\Headers( $headers ); } /** * Sets a single HTTP header. * * @since 4.6.0 * * @param string $key Header name. * @param string $value Header value. * @param bool $replace Optional. Whether to replace an existing header of the same name. * Default true. */ public function header( $key, $value, $replace = true ) { if ( $replace ) { unset( $this->response->headers[ $key ] ); } $this->response->headers[ $key ] = $value; } /** * Retrieves the HTTP return code for the response. * * @since 4.6.0 * * @return int The 3-digit HTTP status code. */ public function get_status() { return $this->response->status_code; } /** * Sets the 3-digit HTTP status code. * * @since 4.6.0 * * @param int $code HTTP status. */ public function set_status( $code ) { $this->response->status_code = absint( $code ); } /** * Retrieves the response data. * * @since 4.6.0 * * @return string Response data. */ public function get_data() { return $this->response->body; } /** * Sets the response data. * * @since 4.6.0 * * @param string $data Response data. */ public function set_data( $data ) { $this->response->body = $data; } /** * Retrieves cookies from the response. * * @since 4.6.0 * * @return WP_HTTP_Cookie[] List of cookie objects. */ public function get_cookies() { $cookies = array(); foreach ( $this->response->cookies as $cookie ) { $cookies[] = new WP_Http_Cookie( array( 'name' => $cookie->name, 'value' => urldecode( $cookie->value ), 'expires' => isset( $cookie->attributes['expires'] ) ? $cookie->attributes['expires'] : null, 'path' => isset( $cookie->attributes['path'] ) ? $cookie->attributes['path'] : null, 'domain' => isset( $cookie->attributes['domain'] ) ? $cookie->attributes['domain'] : null, 'host_only' => isset( $cookie->flags['host-only'] ) ? $cookie->flags['host-only'] : null, ) ); } return $cookies; } /** * Converts the object to a WP_Http response array. * * @since 4.6.0 * * @return array WP_Http response array, per WP_Http::request(). */ public function to_array() { return array( 'headers' => $this->get_headers(), 'body' => $this->get_data(), 'response' => array( 'code' => $this->get_status(), 'message' => get_status_header_desc( $this->get_status() ), ), 'cookies' => $this->get_cookies(), 'filename' => $this->filename, ); } } <?php /** * WordPress List utility class * * @package WordPress * @since 4.7.0 */ /** * List utility. * * Utility class to handle operations on an array of objects or arrays. * * @since 4.7.0 */ #[AllowDynamicProperties] class WP_List_Util { /** * The input array. * * @since 4.7.0 * @var array */ private $input = array(); /** * The output array. * * @since 4.7.0 * @var array */ private $output = array(); /** * Temporary arguments for sorting. * * @since 4.7.0 * @var string[] */ private $orderby = array(); /** * Constructor. * * Sets the input array. * * @since 4.7.0 * * @param array $input Array to perform operations on. */ public function __construct( $input ) { $this->output = $input; $this->input = $input; } /** * Returns the original input array. * * @since 4.7.0 * * @return array The input array. */ public function get_input() { return $this->input; } /** * Returns the output array. * * @since 4.7.0 * * @return array The output array. */ public function get_output() { return $this->output; } /** * Filters the list, based on a set of key => value arguments. * * Retrieves the objects from the list that match the given arguments. * Key represents property name, and value represents property value. * * If an object has more properties than those specified in arguments, * that will not disqualify it. When using the 'AND' operator, * any missing properties will disqualify it. * * @since 4.7.0 * * @param array $args Optional. An array of key => value arguments to match * against each object. Default empty array. * @param string $operator Optional. The logical operation to perform. 'AND' means * all elements from the array must match. 'OR' means only * one element needs to match. 'NOT' means no elements may * match. Default 'AND'. * @return array Array of found values. */ public function filter( $args = array(), $operator = 'AND' ) { if ( empty( $args ) ) { return $this->output; } $operator = strtoupper( $operator ); if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) { $this->output = array(); return $this->output; } $count = count( $args ); $filtered = array(); foreach ( $this->output as $key => $obj ) { $matched = 0; foreach ( $args as $m_key => $m_value ) { if ( is_array( $obj ) ) { // Treat object as an array. if ( array_key_exists( $m_key, $obj ) && ( $m_value == $obj[ $m_key ] ) ) { ++$matched; } } elseif ( is_object( $obj ) ) { // Treat object as an object. if ( isset( $obj->{$m_key} ) && ( $m_value == $obj->{$m_key} ) ) { ++$matched; } } } if ( ( 'AND' === $operator && $matched === $count ) || ( 'OR' === $operator && $matched > 0 ) || ( 'NOT' === $operator && 0 === $matched ) ) { $filtered[ $key ] = $obj; } } $this->output = $filtered; return $this->output; } /** * Plucks a certain field out of each element in the input array. * * This has the same functionality and prototype of * array_column() (PHP 5.5) but also supports objects. * * @since 4.7.0 * * @param int|string $field Field to fetch from the object or array. * @param int|string $index_key Optional. Field from the element to use as keys for the new array. * Default null. * @return array Array of found values. If `$index_key` is set, an array of found values with keys * corresponding to `$index_key`. If `$index_key` is null, array keys from the original * `$list` will be preserved in the results. */ public function pluck( $field, $index_key = null ) { $newlist = array(); if ( ! $index_key ) { /* * This is simple. Could at some point wrap array_column() * if we knew we had an array of arrays. */ foreach ( $this->output as $key => $value ) { if ( is_object( $value ) ) { $newlist[ $key ] = $value->$field; } elseif ( is_array( $value ) ) { $newlist[ $key ] = $value[ $field ]; } else { _doing_it_wrong( __METHOD__, __( 'Values for the input array must be either objects or arrays.' ), '6.2.0' ); } } $this->output = $newlist; return $this->output; } /* * When index_key is not set for a particular item, push the value * to the end of the stack. This is how array_column() behaves. */ foreach ( $this->output as $value ) { if ( is_object( $value ) ) { if ( isset( $value->$index_key ) ) { $newlist[ $value->$index_key ] = $value->$field; } else { $newlist[] = $value->$field; } } elseif ( is_array( $value ) ) { if ( isset( $value[ $index_key ] ) ) { $newlist[ $value[ $index_key ] ] = $value[ $field ]; } else { $newlist[] = $value[ $field ]; } } else { _doing_it_wrong( __METHOD__, __( 'Values for the input array must be either objects or arrays.' ), '6.2.0' ); } } $this->output = $newlist; return $this->output; } /** * Sorts the input array based on one or more orderby arguments. * * @since 4.7.0 * * @param string|array $orderby Optional. Either the field name to order by or an array * of multiple orderby fields as `$orderby => $order`. * Default empty array. * @param string $order Optional. Either 'ASC' or 'DESC'. Only used if `$orderby` * is a string. Default 'ASC'. * @param bool $preserve_keys Optional. Whether to preserve keys. Default false. * @return array The sorted array. */ public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false ) { if ( empty( $orderby ) ) { return $this->output; } if ( is_string( $orderby ) ) { $orderby = array( $orderby => $order ); } foreach ( $orderby as $field => $direction ) { $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC'; } $this->orderby = $orderby; if ( $preserve_keys ) { uasort( $this->output, array( $this, 'sort_callback' ) ); } else { usort( $this->output, array( $this, 'sort_callback' ) ); } $this->orderby = array(); return $this->output; } /** * Callback to sort an array by specific fields. * * @since 4.7.0 * * @see WP_List_Util::sort() * * @param object|array $a One object to compare. * @param object|array $b The other object to compare. * @return int 0 if both objects equal. -1 if second object should come first, 1 otherwise. */ private function sort_callback( $a, $b ) { if ( empty( $this->orderby ) ) { return 0; } $a = (array) $a; $b = (array) $b; foreach ( $this->orderby as $field => $direction ) { if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) { continue; } if ( $a[ $field ] == $b[ $field ] ) { continue; } $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 ); if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) { return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1]; } return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1]; } return 0; } } <?php /** * Diff API: WP_Text_Diff_Renderer_inline class * * @package WordPress * @subpackage Diff * @since 4.7.0 */ /** * Better word splitting than the PEAR package provides. * * @since 2.6.0 * @uses Text_Diff_Renderer_inline Extends */ #[AllowDynamicProperties] class WP_Text_Diff_Renderer_inline extends Text_Diff_Renderer_inline { /** * @ignore * @since 2.6.0 * * @param string $string * @param string $newlineEscape * @return string */ public function _splitOnWords( $string, $newlineEscape = "\n" ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound,WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase $string = str_replace( "\0", '', $string ); $words = preg_split( '/([^\w])/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); $words = str_replace( "\n", $newlineEscape, $words ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase return $words; } } <?php /** * Class 'WP_URL_Pattern_Prefixer'. * * @package WordPress * @subpackage Speculative Loading * @since 6.8.0 */ /** * Class for prefixing URL patterns. * * This class is intended primarily for use as part of the speculative loading feature. * * @since 6.8.0 * @access private */ class WP_URL_Pattern_Prefixer { /** * Map of `$context_string => $base_path` pairs. * * @since 6.8.0 * @var array<string, string> */ private $contexts; /** * Constructor. * * @since 6.8.0 * * @param array<string, string> $contexts Optional. Map of `$context_string => $base_path` pairs. Default is the * contexts returned by the * {@see WP_URL_Pattern_Prefixer::get_default_contexts()} method. */ public function __construct( array $contexts = array() ) { if ( count( $contexts ) > 0 ) { $this->contexts = array_map( static function ( string $str ): string { return self::escape_pattern_string( trailingslashit( $str ) ); }, $contexts ); } else { $this->contexts = self::get_default_contexts(); } } /** * Prefixes the given URL path pattern with the base path for the given context. * * This ensures that these path patterns work correctly on WordPress subdirectory sites, for example in a multisite * network, or when WordPress itself is installed in a subdirectory of the hostname. * * The given URL path pattern is only prefixed if it does not already include the expected prefix. * * @since 6.8.0 * * @param string $path_pattern URL pattern starting with the path segment. * @param string $context Optional. Context to use for prefixing the path pattern. Default 'home'. * @return string URL pattern, prefixed as necessary. */ public function prefix_path_pattern( string $path_pattern, string $context = 'home' ): string { // If context path does not exist, the context is invalid. if ( ! isset( $this->contexts[ $context ] ) ) { _doing_it_wrong( __FUNCTION__, esc_html( sprintf( /* translators: %s: context string */ __( 'Invalid URL pattern context %s.' ), $context ) ), '6.8.0' ); return $path_pattern; } /* * In the event that the context path contains a :, ? or # (which can cause the URL pattern parser to switch to * another state, though only the latter two should be percent encoded anyway), it additionally needs to be * enclosed in grouping braces. The final forward slash (trailingslashit ensures there is one) affects the * meaning of the * wildcard, so is left outside the braces. */ $context_path = $this->contexts[ $context ]; $escaped_context_path = $context_path; if ( strcspn( $context_path, ':?#' ) !== strlen( $context_path ) ) { $escaped_context_path = '{' . substr( $context_path, 0, -1 ) . '}/'; } /* * If the path already starts with the context path (including '/'), remove it first * since it is about to be added back. */ if ( str_starts_with( $path_pattern, $context_path ) ) { $path_pattern = substr( $path_pattern, strlen( $context_path ) ); } return $escaped_context_path . ltrim( $path_pattern, '/' ); } /** * Returns the default contexts used by the class. * * @since 6.8.0 * * @return array<string, string> Map of `$context_string => $base_path` pairs. */ public static function get_default_contexts(): array { return array( 'home' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( home_url( '/' ), PHP_URL_PATH ) ) ), 'site' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( site_url( '/' ), PHP_URL_PATH ) ) ), 'uploads' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( wp_upload_dir( null, false )['baseurl'], PHP_URL_PATH ) ) ), 'content' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( content_url(), PHP_URL_PATH ) ) ), 'plugins' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( plugins_url(), PHP_URL_PATH ) ) ), 'template' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( get_stylesheet_directory_uri(), PHP_URL_PATH ) ) ), 'stylesheet' => self::escape_pattern_string( trailingslashit( (string) wp_parse_url( get_template_directory_uri(), PHP_URL_PATH ) ) ), ); } /** * Escapes a string for use in a URL pattern component. * * @since 6.8.0 * @see https://urlpattern.spec.whatwg.org/#escape-a-pattern-string * * @param string $str String to be escaped. * @return string String with backslashes added where required. */ private static function escape_pattern_string( string $str ): string { return addcslashes( $str, '+*?:{}()\\' ); } } <?php /** * I18N: WP_Translation_File_MO class. * * @package WordPress * @subpackage I18N * @since 6.5.0 */ /** * Class WP_Translation_File_MO. * * @since 6.5.0 */ class WP_Translation_File_MO extends WP_Translation_File { /** * Endian value. * * V for little endian, N for big endian, or false. * * Used for unpack(). * * @since 6.5.0 * @var false|'V'|'N' */ protected $uint32 = false; /** * The magic number of the GNU message catalog format. * * @since 6.5.0 * @var int */ const MAGIC_MARKER = 0x950412de; /** * Detects endian and validates file. * * @since 6.5.0 * * @param string $header File contents. * @return false|'V'|'N' V for little endian, N for big endian, or false on failure. */ protected function detect_endian_and_validate_file( string $header ) { $big = unpack( 'N', $header ); if ( false === $big ) { return false; } $big = reset( $big ); if ( false === $big ) { return false; } $little = unpack( 'V', $header ); if ( false === $little ) { return false; } $little = reset( $little ); if ( false === $little ) { return false; } // Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678. if ( (int) self::MAGIC_MARKER === $big ) { return 'N'; } // Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678. if ( (int) self::MAGIC_MARKER === $little ) { return 'V'; } $this->error = 'Magic marker does not exist'; return false; } /** * Parses the file. * * @since 6.5.0 * * @return bool True on success, false otherwise. */ protected function parse_file(): bool { $this->parsed = true; $file_contents = file_get_contents( $this->file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents if ( false === $file_contents ) { return false; } $file_length = strlen( $file_contents ); if ( $file_length < 24 ) { $this->error = 'Invalid data'; return false; } $this->uint32 = $this->detect_endian_and_validate_file( substr( $file_contents, 0, 4 ) ); if ( false === $this->uint32 ) { return false; } $offsets = substr( $file_contents, 4, 24 ); if ( false === $offsets ) { return false; } $offsets = unpack( "{$this->uint32}rev/{$this->uint32}total/{$this->uint32}originals_addr/{$this->uint32}translations_addr/{$this->uint32}hash_length/{$this->uint32}hash_addr", $offsets ); if ( false === $offsets ) { return false; } $offsets['originals_length'] = $offsets['translations_addr'] - $offsets['originals_addr']; $offsets['translations_length'] = $offsets['hash_addr'] - $offsets['translations_addr']; if ( $offsets['rev'] > 0 ) { $this->error = 'Unsupported revision'; return false; } if ( $offsets['translations_addr'] > $file_length || $offsets['originals_addr'] > $file_length ) { $this->error = 'Invalid data'; return false; } // Load the Originals. $original_data = str_split( substr( $file_contents, $offsets['originals_addr'], $offsets['originals_length'] ), 8 ); $translations_data = str_split( substr( $file_contents, $offsets['translations_addr'], $offsets['translations_length'] ), 8 ); foreach ( array_keys( $original_data ) as $i ) { $o = unpack( "{$this->uint32}length/{$this->uint32}pos", $original_data[ $i ] ); $t = unpack( "{$this->uint32}length/{$this->uint32}pos", $translations_data[ $i ] ); if ( false === $o || false === $t ) { continue; } $original = substr( $file_contents, $o['pos'], $o['length'] ); $translation = substr( $file_contents, $t['pos'], $t['length'] ); // GlotPress bug. $translation = rtrim( $translation, "\0" ); // Metadata about the MO file is stored in the first translation entry. if ( '' === $original ) { foreach ( explode( "\n", $translation ) as $meta_line ) { if ( '' === $meta_line || ! str_contains( $meta_line, ':' ) ) { continue; } list( $name, $value ) = array_map( 'trim', explode( ':', $meta_line, 2 ) ); $this->headers[ strtolower( $name ) ] = $value; } } else { /* * In MO files, the key normally contains both singular and plural versions. * However, this just adds the singular string for lookup, * which caters for cases where both __( 'Product' ) and _n( 'Product', 'Products' ) * are used and the translation is expected to be the same for both. */ $parts = explode( "\0", (string) $original ); $this->entries[ $parts[0] ] = $translation; } } return true; } /** * Exports translation contents as a string. * * @since 6.5.0 * * @return string Translation file contents. */ public function export(): string { // Prefix the headers as the first key. $headers_string = ''; foreach ( $this->headers as $header => $value ) { $headers_string .= "{$header}: $value\n"; } $entries = array_merge( array( '' => $headers_string ), $this->entries ); $entry_count = count( $entries ); if ( false === $this->uint32 ) { $this->uint32 = 'V'; } $bytes_for_entries = $entry_count * 4 * 2; // Pair of 32bit ints per entry. $originals_addr = 28; /* header */ $translations_addr = $originals_addr + $bytes_for_entries; $hash_addr = $translations_addr + $bytes_for_entries; $entry_offsets = $hash_addr; $file_header = pack( $this->uint32 . '*', // Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678. (int) self::MAGIC_MARKER, 0, /* rev */ $entry_count, $originals_addr, $translations_addr, 0, /* hash_length */ $hash_addr ); $o_entries = ''; $t_entries = ''; $o_addr = ''; $t_addr = ''; foreach ( array_keys( $entries ) as $original ) { $o_addr .= pack( $this->uint32 . '*', strlen( $original ), $entry_offsets ); $entry_offsets += strlen( $original ) + 1; $o_entries .= $original . "\0"; } foreach ( $entries as $translations ) { $t_addr .= pack( $this->uint32 . '*', strlen( $translations ), $entry_offsets ); $entry_offsets += strlen( $translations ) + 1; $t_entries .= $translations . "\0"; } return $file_header . $o_addr . $t_addr . $o_entries . $t_entries; } } <?php /** * I18N: WP_Translations class. * * @package WordPress * @subpackage I18N * @since 6.5.0 */ /** * Class WP_Translations. * * @since 6.5.0 * * @property-read array<string, string> $headers * @property-read array<string, string[]> $entries */ class WP_Translations { /** * Text domain. * * @since 6.5.0 * @var string */ protected $textdomain = 'default'; /** * Translation controller instance. * * @since 6.5.0 * @var WP_Translation_Controller */ protected $controller; /** * Constructor. * * @since 6.5.0 * * @param WP_Translation_Controller $controller I18N controller. * @param string $textdomain Optional. Text domain. Default 'default'. */ public function __construct( WP_Translation_Controller $controller, string $textdomain = 'default' ) { $this->controller = $controller; $this->textdomain = $textdomain; } /** * Magic getter for backward compatibility. * * @since 6.5.0 * * @param string $name Property name. * @return mixed */ public function __get( string $name ) { if ( 'entries' === $name ) { $entries = $this->controller->get_entries( $this->textdomain ); $result = array(); foreach ( $entries as $original => $translations ) { $result[] = $this->make_entry( $original, $translations ); } return $result; } if ( 'headers' === $name ) { return $this->controller->get_headers( $this->textdomain ); } return null; } /** * Builds a Translation_Entry from original string and translation strings. * * @see MO::make_entry() * * @since 6.5.0 * * @param string $original Original string to translate from MO file. Might contain * 0x04 as context separator or 0x00 as singular/plural separator. * @param string $translations Translation strings from MO file. * @return Translation_Entry Entry instance. */ private function make_entry( $original, $translations ): Translation_Entry { $entry = new Translation_Entry(); // Look for context, separated by \4. $parts = explode( "\4", $original ); if ( isset( $parts[1] ) ) { $original = $parts[1]; $entry->context = $parts[0]; } $entry->singular = $original; $entry->translations = explode( "\0", $translations ); $entry->is_plural = count( $entry->translations ) > 1; return $entry; } /** * Translates a plural string. * * @since 6.5.0 * * @param string|null $singular Singular string. * @param string|null $plural Plural string. * @param int|float $count Count. Should be an integer, but some plugins pass floats. * @param string|null $context Context. * @return string|null Translation if it exists, or the unchanged singular string. */ public function translate_plural( $singular, $plural, $count = 1, $context = '' ) { if ( null === $singular || null === $plural ) { return $singular; } $translation = $this->controller->translate_plural( array( $singular, $plural ), (int) $count, (string) $context, $this->textdomain ); if ( false !== $translation ) { return $translation; } // Fall back to the original with English grammar rules. return ( 1 === $count ? $singular : $plural ); } /** * Translates a singular string. * * @since 6.5.0 * * @param string|null $singular Singular string. * @param string|null $context Context. * @return string|null Translation if it exists, or the unchanged singular string */ public function translate( $singular, $context = '' ) { if ( null === $singular ) { return null; } $translation = $this->controller->translate( $singular, (string) $context, $this->textdomain ); if ( false !== $translation ) { return $translation; } // Fall back to the original. return $singular; } } <?php /** * I18N: WP_Translation_Controller class. * * @package WordPress * @subpackage I18N * @since 6.5.0 */ /** * Class WP_Translation_Controller. * * @since 6.5.0 */ final class WP_Translation_Controller { /** * Current locale. * * @since 6.5.0 * @var string */ protected $current_locale = 'en_US'; /** * Map of loaded translations per locale and text domain. * * [ Locale => [ Textdomain => [ ..., ... ] ] ] * * @since 6.5.0 * @var array<string, array<string, WP_Translation_File[]>> */ protected $loaded_translations = array(); /** * List of loaded translation files. * * [ Filename => [ Locale => [ Textdomain => WP_Translation_File ] ] ] * * @since 6.5.0 * @var array<string, array<string, array<string, WP_Translation_File|false>>> */ protected $loaded_files = array(); /** * Container for the main instance of the class. * * @since 6.5.0 * @var WP_Translation_Controller|null */ private static $instance = null; /** * Utility method to retrieve the main instance of the class. * * The instance will be created if it does not exist yet. * * @since 6.5.0 * * @return WP_Translation_Controller */ public static function get_instance(): WP_Translation_Controller { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Returns the current locale. * * @since 6.5.0 * * @return string Locale. */ public function get_locale(): string { return $this->current_locale; } /** * Sets the current locale. * * @since 6.5.0 * * @param string $locale Locale. */ public function set_locale( string $locale ) { $this->current_locale = $locale; } /** * Loads a translation file for a given text domain. * * @since 6.5.0 * * @param string $translation_file Translation file. * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Default current locale. * @return bool True on success, false otherwise. */ public function load_file( string $translation_file, string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } $translation_file = realpath( $translation_file ); if ( false === $translation_file ) { return false; } if ( isset( $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] ) && false !== $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] ) { return null === $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ]->error(); } if ( isset( $this->loaded_files[ $translation_file ][ $locale ] ) && array() !== $this->loaded_files[ $translation_file ][ $locale ] ) { $moe = reset( $this->loaded_files[ $translation_file ][ $locale ] ); } else { $moe = WP_Translation_File::create( $translation_file ); if ( false === $moe || null !== $moe->error() ) { $moe = false; } } $this->loaded_files[ $translation_file ][ $locale ][ $textdomain ] = $moe; if ( ! $moe instanceof WP_Translation_File ) { return false; } if ( ! isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { $this->loaded_translations[ $locale ][ $textdomain ] = array(); } $this->loaded_translations[ $locale ][ $textdomain ][] = $moe; return true; } /** * Unloads a translation file for a given text domain. * * @since 6.5.0 * * @param WP_Translation_File|string $file Translation file instance or file name. * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Defaults to all locales. * @return bool True on success, false otherwise. */ public function unload_file( $file, string $textdomain = 'default', ?string $locale = null ): bool { if ( is_string( $file ) ) { $file = realpath( $file ); } if ( null !== $locale ) { if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $i => $moe ) { if ( $file === $moe || $file === $moe->get_file() ) { unset( $this->loaded_translations[ $locale ][ $textdomain ][ $i ] ); unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); return true; } } } return true; } foreach ( $this->loaded_translations as $l => $domains ) { if ( ! isset( $domains[ $textdomain ] ) ) { continue; } foreach ( $domains[ $textdomain ] as $i => $moe ) { if ( $file === $moe || $file === $moe->get_file() ) { unset( $this->loaded_translations[ $l ][ $textdomain ][ $i ] ); unset( $this->loaded_files[ $moe->get_file() ][ $l ][ $textdomain ] ); return true; } } } return false; } /** * Unloads all translation files for a given text domain. * * @since 6.5.0 * * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Defaults to all locales. * @return bool True on success, false otherwise. */ public function unload_textdomain( string $textdomain = 'default', ?string $locale = null ): bool { $unloaded = false; if ( null !== $locale ) { if ( isset( $this->loaded_translations[ $locale ][ $textdomain ] ) ) { $unloaded = true; foreach ( $this->loaded_translations[ $locale ][ $textdomain ] as $moe ) { unset( $this->loaded_files[ $moe->get_file() ][ $locale ][ $textdomain ] ); } } unset( $this->loaded_translations[ $locale ][ $textdomain ] ); return $unloaded; } foreach ( $this->loaded_translations as $l => $domains ) { if ( ! isset( $domains[ $textdomain ] ) ) { continue; } $unloaded = true; foreach ( $domains[ $textdomain ] as $moe ) { unset( $this->loaded_files[ $moe->get_file() ][ $l ][ $textdomain ] ); } unset( $this->loaded_translations[ $l ][ $textdomain ] ); } return $unloaded; } /** * Determines whether translations are loaded for a given text domain. * * @since 6.5.0 * * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Default current locale. * @return bool True if there are any loaded translations, false otherwise. */ public function is_textdomain_loaded( string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } return isset( $this->loaded_translations[ $locale ][ $textdomain ] ) && array() !== $this->loaded_translations[ $locale ][ $textdomain ]; } /** * Translates a singular string. * * @since 6.5.0 * * @param string $text Text to translate. * @param string $context Optional. Context for the string. Default empty string. * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Default current locale. * @return string|false Translation on success, false otherwise. */ public function translate( string $text, string $context = '', string $textdomain = 'default', ?string $locale = null ) { if ( '' !== $context ) { $context .= "\4"; } $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { return false; } return $translation['entries'][0]; } /** * Translates plurals. * * Checks both singular+plural combinations as well as just singulars, * in case the translation file does not store the plural. * * @since 6.5.0 * * @param array $plurals { * Pair of singular and plural translations. * * @type string $0 Singular translation. * @type string $1 Plural translation. * } * @param int $number Number of items. * @param string $context Optional. Context for the string. Default empty string. * @param string $textdomain Optional. Text domain. Default 'default'. * @param string|null $locale Optional. Locale. Default current locale. * @return string|false Translation on success, false otherwise. */ public function translate_plural( array $plurals, int $number, string $context = '', string $textdomain = 'default', ?string $locale = null ) { if ( '' !== $context ) { $context .= "\4"; } $text = implode( "\0", $plurals ); $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { $text = $plurals[0]; $translation = $this->locate_translation( "{$context}{$text}", $textdomain, $locale ); if ( false === $translation ) { return false; } } /** @var WP_Translation_File $source */ $source = $translation['source']; $num = $source->get_plural_form( $number ); // See \Translations::translate_plural(). return $translation['entries'][ $num ] ?? $translation['entries'][0]; } /** * Returns all existing headers for a given text domain. * * @since 6.5.0 * * @param string $textdomain Optional. Text domain. Default 'default'. * @return array<string, string> Headers. */ public function get_headers( string $textdomain = 'default' ): array { if ( array() === $this->loaded_translations ) { return array(); } $headers = array(); foreach ( $this->get_files( $textdomain ) as $moe ) { foreach ( $moe->headers() as $header => $value ) { $headers[ $this->normalize_header( $header ) ] = $value; } } return $headers; } /** * Normalizes header names to be capitalized. * * @since 6.5.0 * * @param string $header Header name. * @return string Normalized header name. */ protected function normalize_header( string $header ): string { $parts = explode( '-', $header ); $parts = array_map( 'ucfirst', $parts ); return implode( '-', $parts ); } /** * Returns all entries for a given text domain. * * @since 6.5.0 * * @param string $textdomain Optional. Text domain. Default 'default'. * @return array<string, string> Entries. */ public function get_entries( string $textdomain = 'default' ): array { if ( array() === $this->loaded_translations ) { return array(); } $entries = array(); foreach ( $this->get_files( $textdomain ) as $moe ) { $entries = array_merge( $entries, $moe->entries() ); } return $entries; } /** * Locates translation for a given string and text domain. * * @since 6.5.0 * * @param string $singular Singular translation. * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Default current locale. * @return array{source: WP_Translation_File, entries: string[]}|false { * Translations on success, false otherwise. * * @type WP_Translation_File $source Translation file instance. * @type string[] $entries Array of translation entries. * } */ protected function locate_translation( string $singular, string $textdomain = 'default', ?string $locale = null ) { if ( array() === $this->loaded_translations ) { return false; } // Find the translation in all loaded files for this text domain. foreach ( $this->get_files( $textdomain, $locale ) as $moe ) { $translation = $moe->translate( $singular ); if ( false !== $translation ) { return array( 'entries' => explode( "\0", $translation ), 'source' => $moe, ); } if ( null !== $moe->error() ) { // Unload this file, something is wrong. $this->unload_file( $moe, $textdomain, $locale ); } } // Nothing could be found. return false; } /** * Returns all translation files for a given text domain. * * @since 6.5.0 * * @param string $textdomain Optional. Text domain. Default 'default'. * @param string $locale Optional. Locale. Default current locale. * @return WP_Translation_File[] List of translation files. */ protected function get_files( string $textdomain = 'default', ?string $locale = null ): array { if ( null === $locale ) { $locale = $this->current_locale; } return $this->loaded_translations[ $locale ][ $textdomain ] ?? array(); } /** * Returns a boolean to indicate whether a translation exists for a given string with optional text domain and locale. * * @since 6.7.0 * * @param string $singular Singular translation to check. * @param string $textdomain Optional. Text domain. Default 'default'. * @param ?string $locale Optional. Locale. Default current locale. * @return bool True if the translation exists, false otherwise. */ public function has_translation( string $singular, string $textdomain = 'default', ?string $locale = null ): bool { if ( null === $locale ) { $locale = $this->current_locale; } return false !== $this->locate_translation( $singular, $textdomain, $locale ); } } <?php /** * I18N: WP_Translation_File class. * * @package WordPress * @subpackage I18N * @since 6.5.0 */ /** * Class WP_Translation_File. * * @since 6.5.0 */ abstract class WP_Translation_File { /** * List of headers. * * @since 6.5.0 * @var array<string, string> */ protected $headers = array(); /** * Whether file has been parsed. * * @since 6.5.0 * @var bool */ protected $parsed = false; /** * Error information. * * @since 6.5.0 * @var string|null Error message or null if no error. */ protected $error; /** * File name. * * @since 6.5.0 * @var string */ protected $file = ''; /** * Translation entries. * * @since 6.5.0 * @var array<string, string> */ protected $entries = array(); /** * Plural forms function. * * @since 6.5.0 * @var callable|null Plural forms. */ protected $plural_forms = null; /** * Constructor. * * @since 6.5.0 * * @param string $file File to load. */ protected function __construct( string $file ) { $this->file = $file; } /** * Creates a new WP_Translation_File instance for a given file. * * @since 6.5.0 * * @param string $file File name. * @param string|null $filetype Optional. File type. Default inferred from file name. * @return false|WP_Translation_File */ public static function create( string $file, ?string $filetype = null ) { if ( ! is_readable( $file ) ) { return false; } if ( null === $filetype ) { $pos = strrpos( $file, '.' ); if ( false !== $pos ) { $filetype = substr( $file, $pos + 1 ); } } switch ( $filetype ) { case 'mo': return new WP_Translation_File_MO( $file ); case 'php': return new WP_Translation_File_PHP( $file ); default: return false; } } /** * Creates a new WP_Translation_File instance for a given file. * * @since 6.5.0 * * @param string $file Source file name. * @param string $filetype Desired target file type. * @return string|false Transformed translation file contents on success, false otherwise. */ public static function transform( string $file, string $filetype ) { $source = self::create( $file ); if ( false === $source ) { return false; } switch ( $filetype ) { case 'mo': $destination = new WP_Translation_File_MO( '' ); break; case 'php': $destination = new WP_Translation_File_PHP( '' ); break; default: return false; } $success = $destination->import( $source ); if ( ! $success ) { return false; } return $destination->export(); } /** * Returns all headers. * * @since 6.5.0 * * @return array<string, string> Headers. */ public function headers(): array { if ( ! $this->parsed ) { $this->parse_file(); } return $this->headers; } /** * Returns all entries. * * @since 6.5.0 * * @return array<string, string[]> Entries. */ public function entries(): array { if ( ! $this->parsed ) { $this->parse_file(); } return $this->entries; } /** * Returns the current error information. * * @since 6.5.0 * * @return string|null Error message or null if no error. */ public function error() { return $this->error; } /** * Returns the file name. * * @since 6.5.0 * * @return string File name. */ public function get_file(): string { return $this->file; } /** * Translates a given string. * * @since 6.5.0 * * @param string $text String to translate. * @return false|string Translation(s) on success, false otherwise. */ public function translate( string $text ) { if ( ! $this->parsed ) { $this->parse_file(); } return $this->entries[ $text ] ?? false; } /** * Returns the plural form for a given number. * * @since 6.5.0 * * @param int $number Count. * @return int Plural form. */ public function get_plural_form( int $number ): int { if ( ! $this->parsed ) { $this->parse_file(); } if ( null === $this->plural_forms && isset( $this->headers['plural-forms'] ) ) { $expression = $this->get_plural_expression_from_header( $this->headers['plural-forms'] ); $this->plural_forms = $this->make_plural_form_function( $expression ); } if ( is_callable( $this->plural_forms ) ) { /** * Plural form. * * @var int $result Plural form. */ $result = call_user_func( $this->plural_forms, $number ); return $result; } // Default plural form matches English, only "One" is considered singular. return ( 1 === $number ? 0 : 1 ); } /** * Returns the plural forms expression as a tuple. * * @since 6.5.0 * * @param string $header Plural-Forms header string. * @return string Plural forms expression. */ protected function get_plural_expression_from_header( string $header ): string { if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) { return trim( $matches[2] ); } return 'n != 1'; } /** * Makes a function, which will return the right translation index, according to the * plural forms header. * * @since 6.5.0 * * @param string $expression Plural form expression. * @return callable(int $num): int Plural forms function. */ protected function make_plural_form_function( string $expression ): callable { try { $handler = new Plural_Forms( rtrim( $expression, ';' ) ); return array( $handler, 'get' ); } catch ( Exception $e ) { // Fall back to default plural-form function. return $this->make_plural_form_function( 'n != 1' ); } } /** * Imports translations from another file. * * @since 6.5.0 * * @param WP_Translation_File $source Source file. * @return bool True on success, false otherwise. */ protected function import( WP_Translation_File $source ): bool { if ( null !== $source->error() ) { return false; } $this->headers = $source->headers(); $this->entries = $source->entries(); $this->error = $source->error(); return null === $this->error; } /** * Parses the file. * * @since 6.5.0 */ abstract protected function parse_file(); /** * Exports translation contents as a string. * * @since 6.5.0 * * @return string Translation file contents. */ abstract public function export(); } <?php /** * I18N: WP_Translation_File_PHP class. * * @package WordPress * @subpackage I18N * @since 6.5.0 */ /** * Class WP_Translation_File_PHP. * * @since 6.5.0 */ class WP_Translation_File_PHP extends WP_Translation_File { /** * Parses the file. * * @since 6.5.0 */ protected function parse_file() { $this->parsed = true; $result = include $this->file; if ( ! $result || ! is_array( $result ) ) { $this->error = 'Invalid data'; return; } if ( isset( $result['messages'] ) && is_array( $result['messages'] ) ) { foreach ( $result['messages'] as $original => $translation ) { $this->entries[ (string) $original ] = $translation; } unset( $result['messages'] ); } $this->headers = array_change_key_case( $result ); } /** * Exports translation contents as a string. * * @since 6.5.0 * * @return string Translation file contents. */ public function export(): string { $data = array_merge( $this->headers, array( 'messages' => $this->entries ) ); return '<?php' . PHP_EOL . 'return ' . $this->var_export( $data ) . ';' . PHP_EOL; } /** * Outputs or returns a parsable string representation of a variable. * * Like {@see var_export()} but "minified", using short array syntax * and no newlines. * * @since 6.5.0 * * @param mixed $value The variable you want to export. * @return string The variable representation. */ private function var_export( $value ): string { if ( ! is_array( $value ) ) { return var_export( $value, true ); } $entries = array(); $is_list = array_is_list( $value ); foreach ( $value as $key => $val ) { $entries[] = $is_list ? $this->var_export( $val ) : var_export( $key, true ) . '=>' . $this->var_export( $val ); } return '[' . implode( ',', $entries ) . ']'; } } <?php /** * Customize API: WP_Customize_Media_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Media Control class. * * @since 4.2.0 * * @see WP_Customize_Control */ class WP_Customize_Media_Control extends WP_Customize_Control { /** * Control type. * * @since 4.2.0 * @var string */ public $type = 'media'; /** * Media control mime type. * * @since 4.2.0 * @var string */ public $mime_type = ''; /** * Button labels. * * @since 4.2.0 * @var array */ public $button_labels = array(); /** * Constructor. * * @since 4.1.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id Control ID. * @param array $args Optional. Arguments to override class property defaults. * See WP_Customize_Control::__construct() for information * on accepted arguments. Default empty array. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); $this->button_labels = wp_parse_args( $this->button_labels, $this->get_default_button_labels() ); } /** * Enqueue control related scripts/styles. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. */ public function enqueue() { wp_enqueue_media(); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['label'] = html_entity_decode( $this->label, ENT_QUOTES, get_bloginfo( 'charset' ) ); $this->json['mime_type'] = $this->mime_type; $this->json['button_labels'] = $this->button_labels; $this->json['canUpload'] = current_user_can( 'upload_files' ); $value = $this->value(); if ( is_object( $this->setting ) ) { if ( $this->setting->default ) { /* * Fake an attachment model - needs all fields used by template. * Note that the default value must be a URL, NOT an attachment ID. */ $ext = substr( $this->setting->default, -3 ); $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; $default_attachment = array( 'id' => 1, 'url' => $this->setting->default, 'type' => $type, 'icon' => wp_mime_type_icon( $type, '.svg' ), 'title' => wp_basename( $this->setting->default ), ); if ( 'image' === $type ) { $default_attachment['sizes'] = array( 'full' => array( 'url' => $this->setting->default ), ); } $this->json['defaultAttachment'] = $default_attachment; } if ( $value && $this->setting->default && $value === $this->setting->default ) { // Set the default as the attachment. $this->json['attachment'] = $this->json['defaultAttachment']; } elseif ( $value ) { $this->json['attachment'] = wp_prepare_attachment_for_js( $value ); } } } /** * Don't render any content for this control from PHP. * * @since 3.4.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. * * @see WP_Customize_Media_Control::content_template() */ public function render_content() {} /** * Render a JS template for the content of the media control. * * @since 4.1.0 * @since 4.2.0 Moved from WP_Customize_Upload_Control. */ public function content_template() { ?> <# var descriptionId = _.uniqueId( 'customize-media-control-description-' ); var describedByAttr = data.description ? ' aria-describedby="' + descriptionId + '" ' : ''; #> <# if ( data.label ) { #> <span class="customize-control-title">{{ data.label }}</span> <# } #> <div class="customize-control-notifications-container"></div> <# if ( data.description ) { #> <span id="{{ descriptionId }}" class="description customize-control-description">{{{ data.description }}}</span> <# } #> <# if ( data.attachment && data.attachment.id ) { #> <div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}"> <div class="thumbnail thumbnail-{{ data.attachment.type }}"> <# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #> <img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" alt="" /> <# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #> <img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" alt="" /> <# } else if ( 'audio' === data.attachment.type ) { #> <# if ( data.attachment.image && data.attachment.image.src && data.attachment.image.src !== data.attachment.icon ) { #> <img src="{{ data.attachment.image.src }}" class="thumbnail" draggable="false" alt="" /> <# } else { #> <img src="{{ data.attachment.icon }}" class="attachment-thumb type-icon" draggable="false" alt="" /> <# } #> <p class="attachment-meta attachment-meta-title">“{{ data.attachment.title }}”</p> <# if ( data.attachment.album || data.attachment.meta.album ) { #> <p class="attachment-meta"><em>{{ data.attachment.album || data.attachment.meta.album }}</em></p> <# } #> <# if ( data.attachment.artist || data.attachment.meta.artist ) { #> <p class="attachment-meta">{{ data.attachment.artist || data.attachment.meta.artist }}</p> <# } #> <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none"> <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}" /> </audio> <# } else if ( 'video' === data.attachment.type ) { #> <div class="wp-media-wrapper wp-video"> <video controls="controls" class="wp-video-shortcode" preload="metadata" <# if ( data.attachment.image && data.attachment.image.src !== data.attachment.icon ) { #>poster="{{ data.attachment.image.src }}"<# } #>> <source type="{{ data.attachment.mime }}" src="{{ data.attachment.url }}" /> </video> </div> <# } else { #> <img class="attachment-thumb type-icon icon" src="{{ data.attachment.icon }}" draggable="false" alt="" /> <p class="attachment-title">{{ data.attachment.title }}</p> <# } #> </div> <div class="actions"> <# if ( data.canUpload ) { #> <button type="button" class="button remove-button">{{ data.button_labels.remove }}</button> <button type="button" class="button upload-button control-focus" {{{ describedByAttr }}}>{{ data.button_labels.change }}</button> <# } #> </div> </div> <# } else { #> <div class="attachment-media-view"> <# if ( data.canUpload ) { #> <button type="button" class="upload-button button-add-media" {{{ describedByAttr }}}>{{ data.button_labels.select }}</button> <# } #> <div class="actions"> <# if ( data.defaultAttachment ) { #> <button type="button" class="button default-button">{{ data.button_labels['default'] }}</button> <# } #> </div> </div> <# } #> <?php } /** * Get default button labels. * * Provides an array of the default button labels based on the mime type of the current control. * * @since 4.9.0 * * @return string[] An associative array of default button labels keyed by the button name. */ public function get_default_button_labels() { // Get just the mime type and strip the mime subtype if present. $mime_type = ! empty( $this->mime_type ) ? strtok( ltrim( $this->mime_type, '/' ), '/' ) : 'default'; switch ( $mime_type ) { case 'video': return array( 'select' => __( 'Select video' ), 'change' => __( 'Change video' ), 'default' => __( 'Default' ), 'remove' => __( 'Remove' ), 'placeholder' => __( 'No video selected' ), 'frame_title' => __( 'Select video' ), 'frame_button' => __( 'Choose video' ), ); case 'audio': return array( 'select' => __( 'Select audio' ), 'change' => __( 'Change audio' ), 'default' => __( 'Default' ), 'remove' => __( 'Remove' ), 'placeholder' => __( 'No audio selected' ), 'frame_title' => __( 'Select audio' ), 'frame_button' => __( 'Choose audio' ), ); case 'image': return array( 'select' => __( 'Select image' ), 'site_icon' => __( 'Select Site Icon' ), 'change' => __( 'Change image' ), 'default' => __( 'Default' ), 'remove' => __( 'Remove' ), 'placeholder' => __( 'No image selected' ), 'frame_title' => __( 'Select image' ), 'frame_button' => __( 'Choose image' ), ); default: return array( 'select' => __( 'Select file' ), 'change' => __( 'Change file' ), 'default' => __( 'Default' ), 'remove' => __( 'Remove' ), 'placeholder' => __( 'No file selected' ), 'frame_title' => __( 'Select file' ), 'frame_button' => __( 'Choose file' ), ); } // End switch(). } } [09-Oct-2025 09:40:06 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php on line 17 [09-Oct-2025 09:40:07 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php on line 17 [09-Oct-2025 09:40:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php on line 17 [09-Oct-2025 09:40:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php on line 17 [09-Oct-2025 09:40:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php on line 17 [09-Oct-2025 09:40:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php on line 17 [09-Oct-2025 09:40:11 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php on line 17 [09-Oct-2025 09:40:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php on line 17 [09-Oct-2025 09:40:13 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php on line 17 [09-Oct-2025 09:40:14 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php on line 17 [09-Oct-2025 09:40:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php on line 17 [09-Oct-2025 09:40:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php on line 17 [09-Oct-2025 09:40:18 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php on line 19 [09-Oct-2025 09:40:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php on line 19 [09-Oct-2025 09:40:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php on line 17 [09-Oct-2025 09:40:20 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php on line 17 [09-Oct-2025 09:40:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php on line 19 [09-Oct-2025 09:40:22 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php on line 19 [09-Oct-2025 09:40:23 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php on line 17 [09-Oct-2025 09:40:24 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php on line 17 [09-Oct-2025 09:40:25 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php on line 19 [09-Oct-2025 09:40:25 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php on line 19 [09-Oct-2025 09:40:26 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Upload_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php on line 17 [09-Oct-2025 09:40:27 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Upload_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php on line 17 [09-Oct-2025 09:40:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php on line 17 [09-Oct-2025 09:40:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php on line 17 [09-Oct-2025 09:40:30 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php on line 17 [09-Oct-2025 09:40:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php on line 17 [09-Oct-2025 09:40:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php on line 17 [09-Oct-2025 09:40:32 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php on line 17 [09-Oct-2025 09:40:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php on line 17 [09-Oct-2025 09:40:34 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php on line 17 [09-Oct-2025 09:40:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php on line 20 [09-Oct-2025 09:40:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php on line 20 [09-Oct-2025 09:40:37 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php on line 19 [09-Oct-2025 09:40:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php on line 19 [09-Oct-2025 09:40:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php on line 17 [09-Oct-2025 09:40:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php on line 17 [09-Oct-2025 09:40:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php on line 17 [09-Oct-2025 09:40:42 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php on line 17 [09-Oct-2025 09:40:43 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php on line 19 [09-Oct-2025 09:40:44 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php on line 19 [09-Oct-2025 09:40:44 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php:21 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php on line 21 [09-Oct-2025 09:40:45 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php:21 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php on line 21 [09-Oct-2025 09:40:46 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php on line 19 [09-Oct-2025 09:40:47 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php on line 19 [09-Oct-2025 09:40:48 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php on line 11 [09-Oct-2025 09:40:49 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php on line 11 [09-Oct-2025 09:40:50 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php on line 11 [09-Oct-2025 09:40:50 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php on line 11 [09-Oct-2025 09:40:55 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php on line 17 [09-Oct-2025 09:40:56 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php on line 17 [09-Oct-2025 09:40:57 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Cropped_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php on line 19 [09-Oct-2025 09:40:58 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Cropped_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php on line 19 [09-Oct-2025 09:41:00 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php on line 17 [09-Oct-2025 09:41:01 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php on line 17 [09-Oct-2025 09:41:02 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php on line 17 [09-Oct-2025 09:41:03 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php on line 17 [09-Oct-2025 09:41:04 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php on line 19 [09-Oct-2025 09:41:05 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php on line 19 [09-Oct-2025 09:41:06 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Media_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php on line 17 [09-Oct-2025 09:41:06 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Media_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php on line 17 [09-Oct-2025 09:41:07 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php on line 18 [09-Oct-2025 09:41:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php on line 18 [09-Oct-2025 09:41:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php on line 17 [09-Oct-2025 09:41:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php on line 17 [09-Oct-2025 09:41:11 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php on line 17 [09-Oct-2025 09:41:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php on line 17 [09-Oct-2025 09:54:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php on line 17 [09-Oct-2025 09:54:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php on line 17 [09-Oct-2025 09:54:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php on line 17 [09-Oct-2025 09:54:18 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php on line 17 [09-Oct-2025 09:54:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php on line 17 [09-Oct-2025 09:54:20 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php on line 17 [09-Oct-2025 09:54:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php on line 17 [09-Oct-2025 09:54:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php on line 17 [09-Oct-2025 09:54:22 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php on line 17 [09-Oct-2025 09:54:23 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php on line 17 [09-Oct-2025 09:54:24 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php on line 17 [09-Oct-2025 09:54:25 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php on line 17 [09-Oct-2025 09:54:26 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php on line 19 [09-Oct-2025 09:54:27 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php on line 19 [09-Oct-2025 09:54:27 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php on line 17 [09-Oct-2025 09:54:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php on line 17 [09-Oct-2025 09:54:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php on line 19 [09-Oct-2025 09:54:30 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php on line 19 [09-Oct-2025 09:54:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php on line 17 [09-Oct-2025 09:54:32 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php on line 17 [09-Oct-2025 09:54:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php on line 19 [09-Oct-2025 09:54:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php on line 19 [09-Oct-2025 09:54:34 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Upload_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php on line 17 [09-Oct-2025 09:54:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Upload_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php on line 17 [09-Oct-2025 09:54:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php on line 17 [09-Oct-2025 09:54:37 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php on line 17 [09-Oct-2025 09:54:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php on line 17 [09-Oct-2025 09:54:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php on line 17 [09-Oct-2025 09:54:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php on line 17 [09-Oct-2025 09:54:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php on line 17 [09-Oct-2025 09:54:41 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php on line 17 [09-Oct-2025 09:54:42 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php on line 17 [09-Oct-2025 09:54:43 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php on line 20 [09-Oct-2025 09:54:44 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php on line 20 [09-Oct-2025 09:54:45 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php on line 19 [09-Oct-2025 09:54:46 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php on line 19 [09-Oct-2025 09:54:47 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php on line 17 [09-Oct-2025 09:54:48 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php on line 17 [09-Oct-2025 09:54:49 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php on line 17 [09-Oct-2025 09:54:50 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php on line 17 [09-Oct-2025 09:54:50 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php on line 19 [09-Oct-2025 09:54:51 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php on line 19 [09-Oct-2025 09:54:52 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php:21 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php on line 21 [09-Oct-2025 09:54:53 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php:21 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php on line 21 [09-Oct-2025 09:54:54 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php on line 19 [09-Oct-2025 09:54:55 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php on line 19 [09-Oct-2025 09:54:55 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php on line 11 [09-Oct-2025 09:54:56 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php on line 11 [09-Oct-2025 09:54:57 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php on line 11 [09-Oct-2025 09:54:58 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php on line 11 [09-Oct-2025 09:55:02 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php on line 17 [09-Oct-2025 09:55:03 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php on line 17 [09-Oct-2025 09:55:04 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Cropped_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php on line 19 [09-Oct-2025 09:55:05 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Cropped_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php on line 19 [09-Oct-2025 09:55:06 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php on line 17 [09-Oct-2025 09:55:07 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php on line 17 [09-Oct-2025 09:55:07 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php on line 17 [09-Oct-2025 09:55:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php on line 17 [09-Oct-2025 09:55:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php on line 19 [09-Oct-2025 09:55:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php on line 19 [09-Oct-2025 09:55:11 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Media_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php on line 17 [09-Oct-2025 09:55:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Media_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php on line 17 [09-Oct-2025 09:55:13 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php on line 18 [09-Oct-2025 09:55:13 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php on line 18 [09-Oct-2025 09:55:14 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php on line 17 [09-Oct-2025 09:55:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php on line 17 [09-Oct-2025 09:55:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php on line 17 [09-Oct-2025 09:55:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php on line 17 [09-Oct-2025 10:05:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-control.php on line 17 [09-Oct-2025 10:05:14 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-image-setting.php on line 17 [09-Oct-2025 10:05:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-background-position-control.php on line 17 [09-Oct-2025 10:05:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-code-editor-control.php on line 17 [09-Oct-2025 10:05:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-color-control.php on line 17 [09-Oct-2025 10:05:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-cropped-image-control.php on line 17 [09-Oct-2025 10:05:23 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-custom-css-setting.php on line 19 [09-Oct-2025 10:05:24 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-date-time-control.php on line 17 [09-Oct-2025 10:05:26 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-filter-setting.php on line 19 [09-Oct-2025 10:05:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-control.php on line 17 [09-Oct-2025 10:05:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-header-image-setting.php on line 19 [09-Oct-2025 10:05:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Upload_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-image-control.php on line 17 [09-Oct-2025 10:05:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-media-control.php on line 17 [09-Oct-2025 10:05:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php on line 17 [09-Oct-2025 10:05:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-control.php on line 17 [09-Oct-2025 10:05:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-control.php on line 17 [09-Oct-2025 10:05:42 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php on line 20 [09-Oct-2025 10:05:43 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-location-control.php on line 19 [09-Oct-2025 10:05:45 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-locations-control.php on line 17 [09-Oct-2025 10:05:47 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-name-control.php on line 17 [09-Oct-2025 10:05:49 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-section.php on line 19 [09-Oct-2025 10:05:50 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Setting" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php:21 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menu-setting.php on line 21 [09-Oct-2025 10:05:52 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-nav-menus-panel.php on line 19 [09-Oct-2025 10:05:54 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-control.php on line 11 [09-Oct-2025 10:05:55 UTC] PHP Fatal error: Uncaught Error: Call to undefined function _deprecated_file() in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php:11 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-new-menu-section.php on line 11 [09-Oct-2025 10:06:00 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-sidebar-section.php on line 17 [09-Oct-2025 10:06:02 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Cropped_Image_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-site-icon-control.php on line 19 [09-Oct-2025 10:06:04 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-theme-control.php on line 17 [09-Oct-2025 10:06:06 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Panel" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-panel.php on line 17 [09-Oct-2025 10:06:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Section" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-themes-section.php on line 19 [09-Oct-2025 10:06:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Media_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-customize-upload-control.php on line 17 [09-Oct-2025 10:06:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-sidebar-block-editor-control.php on line 18 [09-Oct-2025 10:06:13 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-area-customize-control.php on line 17 [09-Oct-2025 10:06:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_Customize_Control" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/customize/class-wp-widget-form-customize-control.php on line 17 <?php /** * Customize API: WP_Customize_Nav_Menu_Location_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Menu Location Control Class. * * This custom control is only needed for JS. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Location_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'nav_menu_location'; /** * Location ID. * * @since 4.3.0 * @var string */ public $location_id = ''; /** * Refresh the parameters passed to JavaScript via JSON. * * @since 4.3.0 * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['locationId'] = $this->location_id; } /** * Render content just like a normal select control. * * @since 4.3.0 * @since 4.9.0 Added a button to create menus. */ public function render_content() { if ( empty( $this->choices ) ) { return; } $value_hidden_class = ''; $no_value_hidden_class = ''; if ( $this->value() ) { $value_hidden_class = ' hidden'; } else { $no_value_hidden_class = ' hidden'; } ?> <label> <?php if ( ! empty( $this->label ) ) : ?> <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> <?php endif; ?> <?php if ( ! empty( $this->description ) ) : ?> <span class="description customize-control-description"><?php echo $this->description; ?></span> <?php endif; ?> <select <?php $this->link(); ?>> <?php foreach ( $this->choices as $value => $label ) : echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . esc_html( $label ) . '</option>'; endforeach; ?> </select> </label> <button type="button" class="button-link create-menu<?php echo $value_hidden_class; ?>" data-location-id="<?php echo esc_attr( $this->location_id ); ?>" aria-label="<?php esc_attr_e( 'Create a menu for this location' ); ?>"><?php _e( '+ Create New Menu' ); ?></button> <button type="button" class="button-link edit-menu<?php echo $no_value_hidden_class; ?>" aria-label="<?php esc_attr_e( 'Edit selected menu' ); ?>"><?php _e( 'Edit Menu' ); ?></button> <?php } } <?php /** * Customize API: WP_Customize_Cropped_Image_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Cropped Image Control class. * * @since 4.3.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'cropped_image'; /** * Suggested width for cropped image. * * @since 4.3.0 * @var int */ public $width = 150; /** * Suggested height for cropped image. * * @since 4.3.0 * @var int */ public $height = 150; /** * Whether the width is flexible. * * @since 4.3.0 * @var bool */ public $flex_width = false; /** * Whether the height is flexible. * * @since 4.3.0 * @var bool */ public $flex_height = false; /** * Enqueue control related scripts/styles. * * @since 4.3.0 */ public function enqueue() { wp_enqueue_script( 'customize-views' ); parent::enqueue(); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 4.3.0 * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['width'] = absint( $this->width ); $this->json['height'] = absint( $this->height ); $this->json['flex_width'] = absint( $this->flex_width ); $this->json['flex_height'] = absint( $this->flex_height ); } } <?php /** * Customize API: WP_Customize_Filter_Setting class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * A setting that is used to filter a value, but will not save the results. * * Results should be properly handled using another setting or callback. * * @since 3.4.0 * * @see WP_Customize_Setting */ class WP_Customize_Filter_Setting extends WP_Customize_Setting { /** * Saves the value of the setting, using the related API. * * @since 3.4.0 * * @param mixed $value The value to update. */ public function update( $value ) {} } <?php /** * Customize API: WP_Customize_Custom_CSS_Setting class * * This handles validation, sanitization and saving of the value. * * @package WordPress * @subpackage Customize * @since 4.7.0 */ /** * Custom Setting to handle WP Custom CSS. * * @since 4.7.0 * * @see WP_Customize_Setting */ final class WP_Customize_Custom_CSS_Setting extends WP_Customize_Setting { /** * The setting type. * * @since 4.7.0 * @var string */ public $type = 'custom_css'; /** * Setting Transport * * @since 4.7.0 * @var string */ public $transport = 'postMessage'; /** * Capability required to edit this setting. * * @since 4.7.0 * @var string */ public $capability = 'edit_css'; /** * Stylesheet * * @since 4.7.0 * @var string */ public $stylesheet = ''; /** * WP_Customize_Custom_CSS_Setting constructor. * * @since 4.7.0 * * @throws Exception If the setting ID does not match the pattern `custom_css[$stylesheet]`. * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id A specific ID of the setting. * Can be a theme mod or option name. * @param array $args Setting arguments. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); if ( 'custom_css' !== $this->id_data['base'] ) { throw new Exception( 'Expected custom_css id_base.' ); } if ( 1 !== count( $this->id_data['keys'] ) || empty( $this->id_data['keys'][0] ) ) { throw new Exception( 'Expected single stylesheet key.' ); } $this->stylesheet = $this->id_data['keys'][0]; } /** * Add filter to preview post value. * * @since 4.7.9 * * @return bool False when preview short-circuits due no change needing to be previewed. */ public function preview() { if ( $this->is_previewed ) { return false; } $this->is_previewed = true; add_filter( 'wp_get_custom_css', array( $this, 'filter_previewed_wp_get_custom_css' ), 9, 2 ); return true; } /** * Filters `wp_get_custom_css` for applying the customized value. * * This is used in the preview when `wp_get_custom_css()` is called for rendering the styles. * * @since 4.7.0 * * @see wp_get_custom_css() * * @param string $css Original CSS. * @param string $stylesheet Current stylesheet. * @return string CSS. */ public function filter_previewed_wp_get_custom_css( $css, $stylesheet ) { if ( $stylesheet === $this->stylesheet ) { $customized_value = $this->post_value( null ); if ( ! is_null( $customized_value ) ) { $css = $customized_value; } } return $css; } /** * Fetch the value of the setting. Will return the previewed value when `preview()` is called. * * @since 4.7.0 * * @see WP_Customize_Setting::value() * * @return string */ public function value() { if ( $this->is_previewed ) { $post_value = $this->post_value( null ); if ( null !== $post_value ) { return $post_value; } } $id_base = $this->id_data['base']; $value = ''; $post = wp_get_custom_css_post( $this->stylesheet ); if ( $post ) { $value = $post->post_content; } if ( empty( $value ) ) { $value = $this->default; } /** This filter is documented in wp-includes/class-wp-customize-setting.php */ $value = apply_filters( "customize_value_{$id_base}", $value, $this ); return $value; } /** * Validate a received value for being valid CSS. * * Checks for imbalanced braces, brackets, and comments. * Notifications are rendered when the customizer state is saved. * * @since 4.7.0 * @since 4.9.0 Checking for balanced characters has been moved client-side via linting in code editor. * @since 5.9.0 Renamed `$css` to `$value` for PHP 8 named parameter support. * * @param string $value CSS to validate. * @return true|WP_Error True if the input was validated, otherwise WP_Error. */ public function validate( $value ) { // Restores the more descriptive, specific name for use within this method. $css = $value; $validity = new WP_Error(); if ( preg_match( '#</?\w+#', $css ) ) { $validity->add( 'illegal_markup', __( 'Markup is not allowed in CSS.' ) ); } if ( ! $validity->has_errors() ) { $validity = parent::validate( $css ); } return $validity; } /** * Store the CSS setting value in the custom_css custom post type for the stylesheet. * * @since 4.7.0 * @since 5.9.0 Renamed `$css` to `$value` for PHP 8 named parameter support. * * @param string $value CSS to update. * @return int|false The post ID or false if the value could not be saved. */ public function update( $value ) { // Restores the more descriptive, specific name for use within this method. $css = $value; if ( empty( $css ) ) { $css = ''; } $r = wp_update_custom_css_post( $css, array( 'stylesheet' => $this->stylesheet, ) ); if ( $r instanceof WP_Error ) { return false; } $post_id = $r->ID; // Cache post ID in theme mod for performance to avoid additional DB query. if ( $this->manager->get_stylesheet() === $this->stylesheet ) { set_theme_mod( 'custom_css_post_id', $post_id ); } return $post_id; } } <?php /** * Customize API: WP_Customize_Date_Time_Control class * * @package WordPress * @subpackage Customize * @since 4.9.0 */ /** * Customize Date Time Control class. * * @since 4.9.0 * * @see WP_Customize_Control */ class WP_Customize_Date_Time_Control extends WP_Customize_Control { /** * Customize control type. * * @since 4.9.0 * @var string */ public $type = 'date_time'; /** * Minimum Year. * * @since 4.9.0 * @var int */ public $min_year = 1000; /** * Maximum Year. * * @since 4.9.0 * @var int */ public $max_year = 9999; /** * Allow past date, if set to false user can only select future date. * * @since 4.9.0 * @var bool */ public $allow_past_date = true; /** * Whether hours, minutes, and meridian should be shown. * * @since 4.9.0 * @var bool */ public $include_time = true; /** * If set to false the control will appear in 24 hour format, * the value will still be saved in Y-m-d H:i:s format. * * @since 4.9.0 * @var bool */ public $twelve_hour_format = true; /** * Don't render the control's content - it's rendered with a JS template. * * @since 4.9.0 */ public function render_content() {} /** * Export data to JS. * * @since 4.9.0 * @return array */ public function json() { $data = parent::json(); $data['maxYear'] = (int) $this->max_year; $data['minYear'] = (int) $this->min_year; $data['allowPastDate'] = (bool) $this->allow_past_date; $data['twelveHourFormat'] = (bool) $this->twelve_hour_format; $data['includeTime'] = (bool) $this->include_time; return $data; } /** * Renders a JS template for the content of date time control. * * @since 4.9.0 */ public function content_template() { $data = array_merge( $this->json(), $this->get_month_choices() ); $timezone_info = $this->get_timezone_info(); $date_format = get_option( 'date_format' ); $date_format = preg_replace( '/(?<!\\\\)[Yyo]/', '%1$s', $date_format ); $date_format = preg_replace( '/(?<!\\\\)[FmMn]/', '%2$s', $date_format ); $date_format = preg_replace( '/(?<!\\\\)[jd]/', '%3$s', $date_format ); // Fallback to ISO date format if year, month, or day are missing from the date format. if ( 1 !== substr_count( $date_format, '%1$s' ) || 1 !== substr_count( $date_format, '%2$s' ) || 1 !== substr_count( $date_format, '%3$s' ) ) { $date_format = '%1$s-%2$s-%3$s'; } ?> <# _.defaults( data, <?php echo wp_json_encode( $data ); ?> ); #> <# var idPrefix = _.uniqueId( 'el' ) + '-'; #> <# if ( data.label ) { #> <span class="customize-control-title"> {{ data.label }} </span> <# } #> <div class="customize-control-notifications-container"></div> <# if ( data.description ) { #> <span class="description customize-control-description">{{ data.description }}</span> <# } #> <div class="date-time-fields {{ data.includeTime ? 'includes-time' : '' }}"> <fieldset class="day-row"> <legend class="title-day {{ ! data.includeTime ? 'screen-reader-text' : '' }}"><?php esc_html_e( 'Date' ); ?></legend> <div class="day-fields clear"> <?php ob_start(); ?> <label for="{{ idPrefix }}date-time-month" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Month' ); ?> </label> <select id="{{ idPrefix }}date-time-month" class="date-input month" data-component="month"> <# _.each( data.month_choices, function( choice ) { if ( _.isObject( choice ) && ! _.isUndefined( choice.text ) && ! _.isUndefined( choice.value ) ) { text = choice.text; value = choice.value; } #> <option value="{{ value }}" > {{ text }} </option> <# } ); #> </select> <?php $month_field = trim( ob_get_clean() ); ?> <?php ob_start(); ?> <label for="{{ idPrefix }}date-time-day" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Day' ); ?> </label> <input id="{{ idPrefix }}date-time-day" type="number" size="2" autocomplete="off" class="date-input day tiny-text" data-component="day" min="1" max="31" /> <?php $day_field = trim( ob_get_clean() ); ?> <?php ob_start(); ?> <label for="{{ idPrefix }}date-time-year" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Year' ); ?> </label> <input id="{{ idPrefix }}date-time-year" type="number" size="4" autocomplete="off" class="date-input year tiny-text" data-component="year" min="{{ data.minYear }}" max="{{ data.maxYear }}"> <?php $year_field = trim( ob_get_clean() ); ?> <?php printf( $date_format, $year_field, $month_field, $day_field ); ?> </div> </fieldset> <# if ( data.includeTime ) { #> <fieldset class="time-row clear"> <legend class="title-time"><?php esc_html_e( 'Time' ); ?></legend> <div class="time-fields clear"> <label for="{{ idPrefix }}date-time-hour" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Hour' ); ?> </label> <# var maxHour = data.twelveHourFormat ? 12 : 23; #> <# var minHour = data.twelveHourFormat ? 1 : 0; #> <input id="{{ idPrefix }}date-time-hour" type="number" size="2" autocomplete="off" class="date-input hour tiny-text" data-component="hour" min="{{ minHour }}" max="{{ maxHour }}"> : <label for="{{ idPrefix }}date-time-minute" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Minute' ); ?> </label> <input id="{{ idPrefix }}date-time-minute" type="number" size="2" autocomplete="off" class="date-input minute tiny-text" data-component="minute" min="0" max="59"> <# if ( data.twelveHourFormat ) { #> <label for="{{ idPrefix }}date-time-meridian" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ esc_html_e( 'Meridian' ); ?> </label> <select id="{{ idPrefix }}date-time-meridian" class="date-input meridian" data-component="meridian"> <option value="am"><?php esc_html_e( 'AM' ); ?></option> <option value="pm"><?php esc_html_e( 'PM' ); ?></option> </select> <# } #> <p><?php echo $timezone_info['description']; ?></p> </div> </fieldset> <# } #> </div> <?php } /** * Generate options for the month Select. * * Based on touch_time(). * * @since 4.9.0 * * @see touch_time() * * @global WP_Locale $wp_locale WordPress date and time locale object. * * @return array */ public function get_month_choices() { global $wp_locale; $months = array(); for ( $i = 1; $i < 13; $i++ ) { $month_text = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) ); /* translators: 1: Month number (01, 02, etc.), 2: Month abbreviation. */ $months[ $i ]['text'] = sprintf( __( '%1$s-%2$s' ), $i, $month_text ); $months[ $i ]['value'] = $i; } return array( 'month_choices' => $months, ); } /** * Get timezone info. * * @since 4.9.0 * * @return array { * Timezone info. All properties are optional. * * @type string $abbr Timezone abbreviation. Examples: PST or CEST. * @type string $description Human-readable timezone description as HTML. * } */ public function get_timezone_info() { $tz_string = get_option( 'timezone_string' ); $timezone_info = array(); if ( $tz_string ) { try { $tz = new DateTimeZone( $tz_string ); } catch ( Exception $e ) { $tz = ''; } if ( $tz ) { $now = new DateTime( 'now', $tz ); $formatted_gmt_offset = $this->format_gmt_offset( $tz->getOffset( $now ) / HOUR_IN_SECONDS ); $tz_name = str_replace( '_', ' ', $tz->getName() ); $timezone_info['abbr'] = $now->format( 'T' ); $timezone_info['description'] = sprintf( /* translators: 1: Timezone name, 2: Timezone abbreviation, 3: UTC abbreviation and offset, 4: UTC offset. */ __( 'Your timezone is set to %1$s (%2$s), currently %3$s (Coordinated Universal Time %4$s).' ), $tz_name, '<abbr>' . $timezone_info['abbr'] . '</abbr>', '<abbr>UTC</abbr>' . $formatted_gmt_offset, $formatted_gmt_offset ); } else { $timezone_info['description'] = ''; } } else { $formatted_gmt_offset = $this->format_gmt_offset( (int) get_option( 'gmt_offset', 0 ) ); $timezone_info['description'] = sprintf( /* translators: 1: UTC abbreviation and offset, 2: UTC offset. */ __( 'Your timezone is set to %1$s (Coordinated Universal Time %2$s).' ), '<abbr>UTC</abbr>' . $formatted_gmt_offset, $formatted_gmt_offset ); } return $timezone_info; } /** * Format GMT Offset. * * @since 4.9.0 * * @see wp_timezone_choice() * * @param float $offset Offset in hours. * @return string Formatted offset. */ public function format_gmt_offset( $offset ) { if ( 0 <= $offset ) { $formatted_offset = '+' . (string) $offset; } else { $formatted_offset = (string) $offset; } $formatted_offset = str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), $formatted_offset ); return $formatted_offset; } } <?php /** * Customize API: WP_Customize_Header_Image_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Header Image Control class. * * @since 3.4.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control { /** * Customize control type. * * @since 4.2.0 * @var string */ public $type = 'header'; /** * Uploaded header images. * * @since 3.9.0 * @var string */ public $uploaded_headers; /** * Default header images. * * @since 3.9.0 * @var string */ public $default_headers; /** * Constructor. * * @since 3.4.0 * * @param WP_Customize_Manager $manager Customizer bootstrap instance. */ public function __construct( $manager ) { parent::__construct( $manager, 'header_image', array( 'label' => __( 'Header Image' ), 'settings' => array( 'default' => 'header_image', 'data' => 'header_image_data', ), 'section' => 'header_image', 'removed' => 'remove-header', 'get_url' => 'get_header_image', ) ); } /** */ public function enqueue() { wp_enqueue_media(); wp_enqueue_script( 'customize-views' ); $this->prepare_control(); wp_localize_script( 'customize-views', '_wpCustomizeHeader', array( 'data' => array( 'width' => absint( get_theme_support( 'custom-header', 'width' ) ), 'height' => absint( get_theme_support( 'custom-header', 'height' ) ), 'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ), 'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ), 'currentImgSrc' => $this->get_current_image_src(), ), 'nonces' => array( 'add' => wp_create_nonce( 'header-add' ), 'remove' => wp_create_nonce( 'header-remove' ), ), 'uploads' => $this->uploaded_headers, 'defaults' => $this->default_headers, ) ); parent::enqueue(); } /** * @global Custom_Image_Header $custom_image_header */ public function prepare_control() { global $custom_image_header; if ( empty( $custom_image_header ) ) { return; } add_action( 'customize_controls_print_footer_scripts', array( $this, 'print_header_image_template' ) ); // Process default headers and uploaded headers. $custom_image_header->process_default_headers(); $this->default_headers = $custom_image_header->get_default_header_images(); $this->uploaded_headers = $custom_image_header->get_uploaded_header_images(); } /** */ public function print_header_image_template() { ?> <script type="text/template" id="tmpl-header-choice"> <# if (data.random) { #> <button type="button" class="button display-options random"> <span class="dashicons dashicons-randomize dice"></span> <# if ( data.type === 'uploaded' ) { #> <?php _e( 'Randomize uploaded headers' ); ?> <# } else if ( data.type === 'default' ) { #> <?php _e( 'Randomize suggested headers' ); ?> <# } #> </button> <# } else { #> <button type="button" class="choice thumbnail" data-customize-image-value="{{data.header.url}}" data-customize-header-image-data="{{JSON.stringify(data.header)}}"> <span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Set image' ); ?> </span> <img src="{{data.header.thumbnail_url}}" alt="{{data.header.alt_text || data.header.description}}" /> </button> <# if ( data.type === 'uploaded' ) { #> <button type="button" class="dashicons dashicons-no close"> <span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Remove image' ); ?> </span> </button> <# } #> <# } #> </script> <script type="text/template" id="tmpl-header-current"> <# if (data.choice) { #> <# if (data.random) { #> <div class="placeholder"> <span class="dashicons dashicons-randomize dice"></span> <# if ( data.type === 'uploaded' ) { #> <?php _e( 'Randomizing uploaded headers' ); ?> <# } else if ( data.type === 'default' ) { #> <?php _e( 'Randomizing suggested headers' ); ?> <# } #> </div> <# } else { #> <img src="{{data.header.thumbnail_url}}" alt="{{data.header.alt_text || data.header.description}}" /> <# } #> <# } else { #> <div class="placeholder"> <?php _e( 'No image set' ); ?> </div> <# } #> </script> <?php } /** * @return string|void */ public function get_current_image_src() { $src = $this->value(); if ( isset( $this->get_url ) ) { $src = call_user_func( $this->get_url, $src ); return $src; } } /** */ public function render_content() { $visibility = $this->get_current_image_src() ? '' : ' style="display:none" '; $width = absint( get_theme_support( 'custom-header', 'width' ) ); $height = absint( get_theme_support( 'custom-header', 'height' ) ); ?> <div class="customize-control-content"> <?php if ( current_theme_supports( 'custom-header', 'video' ) ) { echo '<span class="customize-control-title">' . $this->label . '</span>'; } ?> <div class="customize-control-notifications-container"></div> <p class="customizer-section-intro customize-control-description"> <?php if ( current_theme_supports( 'custom-header', 'video' ) ) { _e( 'Click “Add Image” to upload an image file from your computer. Your theme works best with an image that matches the size of your video — you’ll be able to crop your image once you upload it for a perfect fit.' ); } elseif ( $width && $height ) { printf( /* translators: %s: Header size in pixels. */ __( 'Click “Add Image” to upload an image file from your computer. Your theme works best with an image with a header size of %s pixels — you’ll be able to crop your image once you upload it for a perfect fit.' ), sprintf( '<strong>%s × %s</strong>', $width, $height ) ); } elseif ( $width ) { printf( /* translators: %s: Header width in pixels. */ __( 'Click “Add Image” to upload an image file from your computer. Your theme works best with an image with a header width of %s pixels — you’ll be able to crop your image once you upload it for a perfect fit.' ), sprintf( '<strong>%s</strong>', $width ) ); } else { printf( /* translators: %s: Header height in pixels. */ __( 'Click “Add Image” to upload an image file from your computer. Your theme works best with an image with a header height of %s pixels — you’ll be able to crop your image once you upload it for a perfect fit.' ), sprintf( '<strong>%s</strong>', $height ) ); } ?> </p> <div class="current"> <label for="header_image-button"> <span class="customize-control-title"> <?php _e( 'Current header' ); ?> </span> </label> <div class="container"> </div> </div> <div class="actions"> <?php if ( current_user_can( 'upload_files' ) ) : ?> <button type="button"<?php echo $visibility; ?> class="button remove" aria-label="<?php esc_attr_e( 'Hide header image' ); ?>"><?php _e( 'Hide image' ); ?></button> <button type="button" class="button new" id="header_image-button" aria-label="<?php esc_attr_e( 'Add Header Image' ); ?>"><?php _e( 'Add Image' ); ?></button> <?php endif; ?> </div> <div class="choices"> <span class="customize-control-title header-previously-uploaded"> <?php _ex( 'Previously uploaded', 'custom headers' ); ?> </span> <div class="uploaded"> <div class="list"> </div> </div> <span class="customize-control-title header-default"> <?php _ex( 'Suggested', 'custom headers' ); ?> </span> <div class="default"> <div class="list"> </div> </div> </div> </div> <?php } } <?php /** * Customize API: WP_Sidebar_Block_Editor_Control class. * * @package WordPress * @subpackage Customize * @since 5.8.0 */ /** * Core class used to implement the widgets block editor control in the * customizer. * * @since 5.8.0 * * @see WP_Customize_Control */ class WP_Sidebar_Block_Editor_Control extends WP_Customize_Control { /** * The control type. * * @since 5.8.0 * * @var string */ public $type = 'sidebar_block_editor'; /** * Render the widgets block editor container. * * @since 5.8.0 */ public function render_content() { // Render an empty control. The JavaScript in // @wordpress/customize-widgets will do the rest. } } <?php /** * Customize API: WP_Widget_Form_Customize_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Widget Form Customize Control class. * * @since 3.9.0 * * @see WP_Customize_Control */ class WP_Widget_Form_Customize_Control extends WP_Customize_Control { /** * Customize control type. * * @since 3.9.0 * @var string */ public $type = 'widget_form'; /** * Widget ID. * * @since 3.9.0 * @var string */ public $widget_id; /** * Widget ID base. * * @since 3.9.0 * @var string */ public $widget_id_base; /** * Sidebar ID. * * @since 3.9.0 * @var string */ public $sidebar_id; /** * Widget status. * * @since 3.9.0 * @var bool True if new, false otherwise. Default false. */ public $is_new = false; /** * Widget width. * * @since 3.9.0 * @var int */ public $width; /** * Widget height. * * @since 3.9.0 * @var int */ public $height; /** * Widget mode. * * @since 3.9.0 * @var bool True if wide, false otherwise. Default false. */ public $is_wide = false; /** * Gather control params for exporting to JavaScript. * * @since 3.9.0 * * @global array $wp_registered_widgets */ public function to_json() { global $wp_registered_widgets; parent::to_json(); $exported_properties = array( 'widget_id', 'widget_id_base', 'sidebar_id', 'width', 'height', 'is_wide' ); foreach ( $exported_properties as $key ) { $this->json[ $key ] = $this->$key; } // Get the widget_control and widget_content. require_once ABSPATH . 'wp-admin/includes/widgets.php'; $widget = $wp_registered_widgets[ $this->widget_id ]; if ( ! isset( $widget['params'][0] ) ) { $widget['params'][0] = array(); } $args = array( 'widget_id' => $widget['id'], 'widget_name' => $widget['name'], ); $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => $args, 1 => $widget['params'][0], ) ); $widget_control_parts = $this->manager->widgets->get_widget_control_parts( $args ); $this->json['widget_control'] = $widget_control_parts['control']; $this->json['widget_content'] = $widget_control_parts['content']; } /** * Override render_content to be no-op since content is exported via to_json for deferred embedding. * * @since 3.9.0 */ public function render_content() {} /** * Whether the current widget is rendered on the page. * * @since 4.0.0 * * @return bool Whether the widget is rendered. */ public function active_callback() { return $this->manager->widgets->is_widget_rendered( $this->widget_id ); } } <?php /** * Customize API: WP_Customize_Code_Editor_Control class * * @package WordPress * @subpackage Customize * @since 4.9.0 */ /** * Customize Code Editor Control class. * * @since 4.9.0 * * @see WP_Customize_Control */ class WP_Customize_Code_Editor_Control extends WP_Customize_Control { /** * Customize control type. * * @since 4.9.0 * @var string */ public $type = 'code_editor'; /** * Type of code that is being edited. * * @since 4.9.0 * @var string */ public $code_type = ''; /** * Code editor settings. * * @see wp_enqueue_code_editor() * @since 4.9.0 * @var array|false */ public $editor_settings = array(); /** * Enqueue control related scripts/styles. * * @since 4.9.0 */ public function enqueue() { $this->editor_settings = wp_enqueue_code_editor( array_merge( array( 'type' => $this->code_type, 'codemirror' => array( 'indentUnit' => 2, 'tabSize' => 2, ), ), $this->editor_settings ) ); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 4.9.0 * * @see WP_Customize_Control::json() * * @return array Array of parameters passed to the JavaScript. */ public function json() { $json = parent::json(); $json['editor_settings'] = $this->editor_settings; $json['input_attrs'] = $this->input_attrs; return $json; } /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 4.9.0 */ public function render_content() {} /** * Render a JS template for control display. * * @since 4.9.0 */ public function content_template() { ?> <# var elementIdPrefix = 'el' + String( Math.random() ); #> <# if ( data.label ) { #> <label for="{{ elementIdPrefix }}_editor" class="customize-control-title"> {{ data.label }} </label> <# } #> <# if ( data.description ) { #> <span class="description customize-control-description">{{{ data.description }}}</span> <# } #> <div class="customize-control-notifications-container"></div> <textarea id="{{ elementIdPrefix }}_editor" <# _.each( _.extend( { 'class': 'code' }, data.input_attrs ), function( value, key ) { #> {{{ key }}}="{{ value }}" <# }); #> ></textarea> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menu_Item_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize control to represent the name field for a given menu. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Item_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'nav_menu_item'; /** * The nav menu item setting. * * @since 4.3.0 * @var WP_Customize_Nav_Menu_Item_Setting */ public $setting; /** * Constructor. * * @since 4.3.0 * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id The control ID. * @param array $args Optional. Arguments to override class property defaults. * See WP_Customize_Control::__construct() for information * on accepted arguments. Default empty array. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); } /** * Don't render the control's content - it's rendered with a JS template. * * @since 4.3.0 */ public function render_content() {} /** * JS/Underscore template for the control UI. * * @since 4.3.0 */ public function content_template() { ?> <div class="menu-item-bar"> <div class="menu-item-handle"> <span class="item-type" aria-hidden="true">{{ data.item_type_label }}</span> <span class="item-title" aria-hidden="true"> <span class="spinner"></span> <span class="menu-item-title<# if ( ! data.title && ! data.original_title ) { #> no-title<# } #>">{{ data.title || data.original_title || wp.customize.Menus.data.l10n.untitled }}</span> <# if ( 0 === data.depth ) { #> <span class="is-submenu" style="display: none;"><?php _e( 'sub item' ); ?></span> <# } else { #> <span class="is-submenu"><?php _e( 'sub item' ); ?></span> <# } #> </span> <span class="item-controls"> <button type="button" class="button-link item-edit" aria-expanded="false"><span class="screen-reader-text"> <# if ( 0 === data.depth ) { #> <?php /* translators: 1: Title of a menu item, 2: Type of a menu item. 3: Item index, 4: Total items. */ printf( __( 'Edit %1$s (%2$s, %3$d of %4$d)' ), '{{ data.title || data.original_title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}', '', '' ); ?> <# } else if ( 1 === data.depth ) { #> <?php /* translators: 1: Title of a menu item, 2: Type of a menu item, 3, Item index, 4, Total items, 5: Item parent. */ printf( __( 'Edit %1$s (%2$s, sub-item %3$d of %4$d under %5$s)' ), '{{ data.title || data.original_title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}', '', '', '' ); ?> <# } else { #> <?php /* translators: 1: Title of a menu item, 2: Type of a menu item, 3, Item index, 4, Total items, 5: Item parent, 6: Item depth. */ printf( __( 'Edit %1$s (%2$s, sub-item %3$d of %4$d under %5$s, level %6$s)' ), '{{ data.title || data.original_title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}', '', '', '', '{{data.depth}}' ); ?> <# } #> </span><span class="toggle-indicator" aria-hidden="true"></span></button> <button type="button" class="button-link item-delete submitdelete deletion"><span class="screen-reader-text"> <?php /* translators: 1: Title of a menu item, 2: Type of a menu item. */ printf( __( 'Remove Menu Item: %1$s (%2$s)' ), '{{ data.title || data.original_title || wp.customize.Menus.data.l10n.untitled }}', '{{ data.item_type_label }}' ); ?> </span></button> </span> </div> </div> <div class="menu-item-settings" id="menu-item-settings-{{ data.menu_item_id }}"> <# if ( 'custom' === data.item_type ) { #> <p class="field-url description description-thin"> <label for="edit-menu-item-url-{{ data.menu_item_id }}"> <?php _e( 'URL' ); ?><br /> <input class="widefat code edit-menu-item-url" type="text" id="edit-menu-item-url-{{ data.menu_item_id }}" name="menu-item-url" /> </label> </p> <# } #> <p class="description description-thin"> <label for="edit-menu-item-title-{{ data.menu_item_id }}"> <?php _e( 'Navigation Label' ); ?><br /> <input type="text" id="edit-menu-item-title-{{ data.menu_item_id }}" placeholder="{{ data.original_title }}" class="widefat edit-menu-item-title" name="menu-item-title" /> </label> </p> <p class="field-link-target description description-thin"> <label for="edit-menu-item-target-{{ data.menu_item_id }}"> <input type="checkbox" id="edit-menu-item-target-{{ data.menu_item_id }}" class="edit-menu-item-target" value="_blank" name="menu-item-target" /> <?php _e( 'Open link in a new tab' ); ?> </label> </p> <p class="field-title-attribute field-attr-title description description-thin"> <label for="edit-menu-item-attr-title-{{ data.menu_item_id }}"> <?php _e( 'Title Attribute' ); ?><br /> <input type="text" id="edit-menu-item-attr-title-{{ data.menu_item_id }}" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title" /> </label> </p> <p class="field-css-classes description description-thin"> <label for="edit-menu-item-classes-{{ data.menu_item_id }}"> <?php _e( 'CSS Classes' ); ?><br /> <input type="text" id="edit-menu-item-classes-{{ data.menu_item_id }}" class="widefat code edit-menu-item-classes" name="menu-item-classes" /> </label> </p> <p class="field-xfn description description-thin"> <label for="edit-menu-item-xfn-{{ data.menu_item_id }}"> <?php _e( 'Link Relationship (XFN)' ); ?><br /> <input type="text" id="edit-menu-item-xfn-{{ data.menu_item_id }}" class="widefat code edit-menu-item-xfn" name="menu-item-xfn" /> </label> </p> <p class="field-description description description-thin"> <label for="edit-menu-item-description-{{ data.menu_item_id }}"> <?php _e( 'Description' ); ?><br /> <textarea id="edit-menu-item-description-{{ data.menu_item_id }}" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description">{{ data.description }}</textarea> <span class="description"><?php _e( 'The description will be displayed in the menu if the active theme supports it.' ); ?></span> </label> </p> <?php /** * Fires at the end of the form field template for nav menu items in the customizer. * * Additional fields can be rendered here and managed in JavaScript. * * @since 5.4.0 */ do_action( 'wp_nav_menu_item_custom_fields_customize_template' ); ?> <div class="menu-item-actions description-thin submitbox"> <# if ( ( 'post_type' === data.item_type || 'taxonomy' === data.item_type ) && '' !== data.original_title ) { #> <p class="link-to-original"> <?php /* translators: Nav menu item original title. %s: Original title. */ printf( __( 'Original: %s' ), '<a class="original-link" href="{{ data.url }}">{{ data.original_title }}</a>' ); ?> </p> <# } #> <button type="button" class="button-link button-link-delete item-delete submitdelete deletion"><?php _e( 'Remove' ); ?></button> <span class="spinner"></span> </div> <input type="hidden" name="menu-item-db-id[{{ data.menu_item_id }}]" class="menu-item-data-db-id" value="{{ data.menu_item_id }}" /> <input type="hidden" name="menu-item-parent-id[{{ data.menu_item_id }}]" class="menu-item-data-parent-id" value="{{ data.parent }}" /> </div><!-- .menu-item-settings--> <ul class="menu-item-transport"></ul> <?php } /** * Return parameters for this control. * * @since 4.3.0 * * @return array Exported parameters. */ public function json() { $exported = parent::json(); $exported['menu_item_id'] = $this->setting->post_id; return $exported; } } <?php /** * Customize API: WP_Customize_Background_Position_Control class * * @package WordPress * @subpackage Customize * @since 4.7.0 */ /** * Customize Background Position Control class. * * @since 4.7.0 * * @see WP_Customize_Control */ class WP_Customize_Background_Position_Control extends WP_Customize_Control { /** * Type. * * @since 4.7.0 * @var string */ public $type = 'background_position'; /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 4.7.0 */ public function render_content() {} /** * Render a JS template for the content of the position control. * * @since 4.7.0 */ public function content_template() { $options = array( array( 'left top' => array( 'label' => __( 'Top Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt', ), 'center top' => array( 'label' => __( 'Top' ), 'icon' => 'dashicons dashicons-arrow-up-alt', ), 'right top' => array( 'label' => __( 'Top Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt', ), ), array( 'left center' => array( 'label' => __( 'Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt', ), 'center center' => array( 'label' => __( 'Center' ), 'icon' => 'background-position-center-icon', ), 'right center' => array( 'label' => __( 'Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt', ), ), array( 'left bottom' => array( 'label' => __( 'Bottom Left' ), 'icon' => 'dashicons dashicons-arrow-left-alt', ), 'center bottom' => array( 'label' => __( 'Bottom' ), 'icon' => 'dashicons dashicons-arrow-down-alt', ), 'right bottom' => array( 'label' => __( 'Bottom Right' ), 'icon' => 'dashicons dashicons-arrow-right-alt', ), ), ); ?> <# if ( data.label ) { #> <span class="customize-control-title">{{{ data.label }}}</span> <# } #> <# if ( data.description ) { #> <span class="description customize-control-description">{{{ data.description }}}</span> <# } #> <div class="customize-control-content"> <fieldset> <legend class="screen-reader-text"><span> <?php /* translators: Hidden accessibility text. */ _e( 'Image Position' ); ?> </span></legend> <div class="background-position-control"> <?php foreach ( $options as $group ) : ?> <div class="button-group"> <?php foreach ( $group as $value => $input ) : ?> <label> <input class="ui-helper-hidden-accessible" name="background-position" type="radio" value="<?php echo esc_attr( $value ); ?>"> <span class="button display-options position"><span class="<?php echo esc_attr( $input['icon'] ); ?>" aria-hidden="true"></span></span> <span class="screen-reader-text"><?php echo $input['label']; ?></span> </label> <?php endforeach; ?> </div> <?php endforeach; ?> </div> </fieldset> </div> <?php } } <?php /** * Customize API: WP_Customize_Color_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Color Control class. * * @since 3.4.0 * * @see WP_Customize_Control */ class WP_Customize_Color_Control extends WP_Customize_Control { /** * Type. * * @var string */ public $type = 'color'; /** * Statuses. * * @var array */ public $statuses; /** * Mode. * * @since 4.7.0 * @var string */ public $mode = 'full'; /** * Constructor. * * @since 3.4.0 * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id Control ID. * @param array $args Optional. Arguments to override class property defaults. * See WP_Customize_Control::__construct() for information * on accepted arguments. Default empty array. */ public function __construct( $manager, $id, $args = array() ) { $this->statuses = array( '' => __( 'Default' ) ); parent::__construct( $manager, $id, $args ); } /** * Enqueue scripts/styles for the color picker. * * @since 3.4.0 */ public function enqueue() { wp_enqueue_script( 'wp-color-picker' ); wp_enqueue_style( 'wp-color-picker' ); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 * @uses WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['statuses'] = $this->statuses; $this->json['defaultValue'] = $this->setting->default; $this->json['mode'] = $this->mode; } /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 3.4.0 */ public function render_content() {} /** * Render a JS template for the content of the color picker control. * * @since 4.1.0 */ public function content_template() { ?> <# var defaultValue = '#RRGGBB', defaultValueAttr = '', isHueSlider = data.mode === 'hue'; if ( data.defaultValue && _.isString( data.defaultValue ) && ! isHueSlider ) { if ( '#' !== data.defaultValue.substring( 0, 1 ) ) { defaultValue = '#' + data.defaultValue; } else { defaultValue = data.defaultValue; } defaultValueAttr = ' data-default-color=' + defaultValue; // Quotes added automatically. } #> <# if ( data.label ) { #> <span class="customize-control-title">{{{ data.label }}}</span> <# } #> <# if ( data.description ) { #> <span class="description customize-control-description">{{{ data.description }}}</span> <# } #> <div class="customize-control-content"> <label><span class="screen-reader-text">{{{ data.label }}}</span> <# if ( isHueSlider ) { #> <input class="color-picker-hue" type="text" data-type="hue" /> <# } else { #> <input class="color-picker-hex" type="text" maxlength="7" placeholder="{{ defaultValue }}" {{ defaultValueAttr }} /> <# } #> </label> </div> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menu_Item_Setting class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Setting to represent a nav_menu. * * Subclass of WP_Customize_Setting to represent a nav_menu taxonomy term, and * the IDs for the nav_menu_items associated with the nav menu. * * @since 4.3.0 * * @see WP_Customize_Setting */ class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting { const ID_PATTERN = '/^nav_menu_item\[(?P<id>-?\d+)\]$/'; const POST_TYPE = 'nav_menu_item'; const TYPE = 'nav_menu_item'; /** * Setting type. * * @since 4.3.0 * @var string */ public $type = self::TYPE; /** * Default setting value. * * @since 4.3.0 * @var array * * @see wp_setup_nav_menu_item() */ public $default = array( // The $menu_item_data for wp_update_nav_menu_item(). 'object_id' => 0, 'object' => '', // Taxonomy name. 'menu_item_parent' => 0, // A.K.A. menu-item-parent-id; note that post_parent is different, and not included. 'position' => 0, // A.K.A. menu_order. 'type' => 'custom', // Note that type_label is not included here. 'title' => '', 'url' => '', 'target' => '', 'attr_title' => '', 'description' => '', 'classes' => '', 'xfn' => '', 'status' => 'publish', 'nav_menu_term_id' => 0, // This will be supplied as the $menu_id arg for wp_update_nav_menu_item(). '_invalid' => false, ); /** * Default transport. * * @since 4.3.0 * @since 4.5.0 Default changed to 'refresh' * @var string */ public $transport = 'refresh'; /** * The post ID represented by this setting instance. This is the db_id. * * A negative value represents a placeholder ID for a new menu not yet saved. * * @since 4.3.0 * @var int */ public $post_id; /** * Storage of pre-setup menu item to prevent wasted calls to wp_setup_nav_menu_item(). * * @since 4.3.0 * @var array|null */ protected $value; /** * Previous (placeholder) post ID used before creating a new menu item. * * This value will be exported to JS via the customize_save_response filter * so that JavaScript can update the settings to refer to the newly-assigned * post ID. This value is always negative to indicate it does not refer to * a real post. * * @since 4.3.0 * @var int * * @see WP_Customize_Nav_Menu_Item_Setting::update() * @see WP_Customize_Nav_Menu_Item_Setting::amend_customize_save_response() */ public $previous_post_id; /** * When previewing or updating a menu item, this stores the previous nav_menu_term_id * which ensures that we can apply the proper filters. * * @since 4.3.0 * @var int */ public $original_nav_menu_term_id; /** * Whether or not update() was called. * * @since 4.3.0 * @var bool */ protected $is_updated = false; /** * Status for calling the update method, used in customize_save_response filter. * * See {@see 'customize_save_response'}. * * When status is inserted, the placeholder post ID is stored in $previous_post_id. * When status is error, the error is stored in $update_error. * * @since 4.3.0 * @var string updated|inserted|deleted|error * * @see WP_Customize_Nav_Menu_Item_Setting::update() * @see WP_Customize_Nav_Menu_Item_Setting::amend_customize_save_response() */ public $update_status; /** * Any error object returned by wp_update_nav_menu_item() when setting is updated. * * @since 4.3.0 * @var WP_Error * * @see WP_Customize_Nav_Menu_Item_Setting::update() * @see WP_Customize_Nav_Menu_Item_Setting::amend_customize_save_response() */ public $update_error; /** * Constructor. * * Any supplied $args override class property defaults. * * @since 4.3.0 * * @throws Exception If $id is not valid for this setting type. * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id A specific ID of the setting. * Can be a theme mod or option name. * @param array $args Optional. Setting arguments. */ public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { if ( empty( $manager->nav_menus ) ) { throw new Exception( 'Expected WP_Customize_Manager::$nav_menus to be set.' ); } if ( ! preg_match( self::ID_PATTERN, $id, $matches ) ) { throw new Exception( "Illegal widget setting ID: $id" ); } $this->post_id = (int) $matches['id']; add_action( 'wp_update_nav_menu_item', array( $this, 'flush_cached_value' ), 10, 2 ); parent::__construct( $manager, $id, $args ); // Ensure that an initially-supplied value is valid. if ( isset( $this->value ) ) { $this->populate_value(); foreach ( array_diff( array_keys( $this->default ), array_keys( $this->value ) ) as $missing ) { throw new Exception( "Supplied nav_menu_item value missing property: $missing" ); } } } /** * Clear the cached value when this nav menu item is updated. * * @since 4.3.0 * * @param int $menu_id The term ID for the menu. * @param int $menu_item_id The post ID for the menu item. */ public function flush_cached_value( $menu_id, $menu_item_id ) { unset( $menu_id ); if ( $menu_item_id === $this->post_id ) { $this->value = null; } } /** * Get the instance data for a given nav_menu_item setting. * * @since 4.3.0 * * @see wp_setup_nav_menu_item() * * @return array|false Instance data array, or false if the item is marked for deletion. */ public function value() { $type_label = null; if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) { $undefined = new stdClass(); // Symbol. $post_value = $this->post_value( $undefined ); if ( $undefined === $post_value ) { $value = $this->_original_value; } else { $value = $post_value; } } elseif ( isset( $this->value ) ) { $value = $this->value; } else { $value = false; // Note that an ID of less than one indicates a nav_menu not yet inserted. if ( $this->post_id > 0 ) { $post = get_post( $this->post_id ); if ( $post && self::POST_TYPE === $post->post_type ) { $is_title_empty = empty( $post->post_title ); $value = (array) wp_setup_nav_menu_item( $post ); if ( isset( $value['type_label'] ) ) { $type_label = $value['type_label']; } if ( $is_title_empty ) { $value['title'] = ''; } } } if ( ! is_array( $value ) ) { $value = $this->default; } // Cache the value for future calls to avoid having to re-call wp_setup_nav_menu_item(). $this->value = $value; $this->populate_value(); $value = $this->value; } // These properties are read-only and are part of the setting for use in the Customizer UI. if ( is_array( $value ) ) { $value_obj = (object) $value; $value['type_label'] = isset( $type_label ) ? $type_label : $this->get_type_label( $value_obj ); $value['original_title'] = $this->get_original_title( $value_obj ); } return $value; } /** * Prepares the value for editing on the client. * * @since 6.8.3 * * @return array|false Value prepared for the client. */ public function js_value() { $value = parent::js_value(); if ( is_array( $value ) && isset( $value['original_title'] ) ) { // Decode entities for the sake of displaying the original title as a placeholder. $value['original_title'] = html_entity_decode( $value['original_title'], ENT_QUOTES, get_bloginfo( 'charset' ) ); } return $value; } /** * Get original title. * * @since 4.7.0 * * @param object $item Nav menu item. * @return string The original title, without entity decoding. */ protected function get_original_title( $item ) { $original_title = ''; if ( 'post_type' === $item->type && ! empty( $item->object_id ) ) { $original_object = get_post( $item->object_id ); if ( $original_object ) { /** This filter is documented in wp-includes/post-template.php */ $original_title = apply_filters( 'the_title', $original_object->post_title, $original_object->ID ); if ( '' === $original_title ) { /* translators: %d: ID of a post. */ $original_title = sprintf( __( '#%d (no title)' ), $original_object->ID ); } } } elseif ( 'taxonomy' === $item->type && ! empty( $item->object_id ) ) { $original_term_title = get_term_field( 'name', $item->object_id, $item->object, 'raw' ); if ( ! is_wp_error( $original_term_title ) ) { $original_title = $original_term_title; } } elseif ( 'post_type_archive' === $item->type ) { $original_object = get_post_type_object( $item->object ); if ( $original_object ) { $original_title = $original_object->labels->archives; } } return $original_title; } /** * Get type label. * * @since 4.7.0 * * @param object $item Nav menu item. * @return string The type label. */ protected function get_type_label( $item ) { if ( 'post_type' === $item->type ) { $object = get_post_type_object( $item->object ); if ( $object ) { $type_label = $object->labels->singular_name; } else { $type_label = $item->object; } } elseif ( 'taxonomy' === $item->type ) { $object = get_taxonomy( $item->object ); if ( $object ) { $type_label = $object->labels->singular_name; } else { $type_label = $item->object; } } elseif ( 'post_type_archive' === $item->type ) { $type_label = __( 'Post Type Archive' ); } else { $type_label = __( 'Custom Link' ); } return $type_label; } /** * Ensure that the value is fully populated with the necessary properties. * * Translates some properties added by wp_setup_nav_menu_item() and removes others. * * @since 4.3.0 * * @see WP_Customize_Nav_Menu_Item_Setting::value() */ protected function populate_value() { if ( ! is_array( $this->value ) ) { return; } if ( isset( $this->value['menu_order'] ) ) { $this->value['position'] = $this->value['menu_order']; unset( $this->value['menu_order'] ); } if ( isset( $this->value['post_status'] ) ) { $this->value['status'] = $this->value['post_status']; unset( $this->value['post_status'] ); } if ( ! isset( $this->value['nav_menu_term_id'] ) && $this->post_id > 0 ) { $menus = wp_get_post_terms( $this->post_id, WP_Customize_Nav_Menu_Setting::TAXONOMY, array( 'fields' => 'ids', ) ); if ( ! empty( $menus ) ) { $this->value['nav_menu_term_id'] = array_shift( $menus ); } else { $this->value['nav_menu_term_id'] = 0; } } foreach ( array( 'object_id', 'menu_item_parent', 'nav_menu_term_id' ) as $key ) { if ( ! is_int( $this->value[ $key ] ) ) { $this->value[ $key ] = (int) $this->value[ $key ]; } } foreach ( array( 'classes', 'xfn' ) as $key ) { if ( is_array( $this->value[ $key ] ) ) { $this->value[ $key ] = implode( ' ', $this->value[ $key ] ); } } if ( ! isset( $this->value['title'] ) ) { $this->value['title'] = ''; } if ( ! isset( $this->value['_invalid'] ) ) { $this->value['_invalid'] = false; $is_known_invalid = ( ( ( 'post_type' === $this->value['type'] || 'post_type_archive' === $this->value['type'] ) && ! post_type_exists( $this->value['object'] ) ) || ( 'taxonomy' === $this->value['type'] && ! taxonomy_exists( $this->value['object'] ) ) ); if ( $is_known_invalid ) { $this->value['_invalid'] = true; } } // Remove remaining properties available on a setup nav_menu_item post object which aren't relevant to the setting value. $irrelevant_properties = array( 'ID', 'comment_count', 'comment_status', 'db_id', 'filter', 'guid', 'ping_status', 'pinged', 'post_author', 'post_content', 'post_content_filtered', 'post_date', 'post_date_gmt', 'post_excerpt', 'post_mime_type', 'post_modified', 'post_modified_gmt', 'post_name', 'post_parent', 'post_password', 'post_title', 'post_type', 'to_ping', ); foreach ( $irrelevant_properties as $property ) { unset( $this->value[ $property ] ); } } /** * Handle previewing the setting. * * @since 4.3.0 * @since 4.4.0 Added boolean return value. * * @see WP_Customize_Manager::post_value() * * @return bool False if method short-circuited due to no-op. */ public function preview() { if ( $this->is_previewed ) { return false; } $undefined = new stdClass(); $is_placeholder = ( $this->post_id < 0 ); $is_dirty = ( $undefined !== $this->post_value( $undefined ) ); if ( ! $is_placeholder && ! $is_dirty ) { return false; } $this->is_previewed = true; $this->_original_value = $this->value(); $this->original_nav_menu_term_id = $this->_original_value['nav_menu_term_id']; $this->_previewed_blog_id = get_current_blog_id(); add_filter( 'wp_get_nav_menu_items', array( $this, 'filter_wp_get_nav_menu_items' ), 10, 3 ); $sort_callback = array( __CLASS__, 'sort_wp_get_nav_menu_items' ); if ( ! has_filter( 'wp_get_nav_menu_items', $sort_callback ) ) { add_filter( 'wp_get_nav_menu_items', array( __CLASS__, 'sort_wp_get_nav_menu_items' ), 1000, 3 ); } // @todo Add get_post_metadata filters for plugins to add their data. return true; } /** * Filters the wp_get_nav_menu_items() result to supply the previewed menu items. * * @since 4.3.0 * * @see wp_get_nav_menu_items() * * @param WP_Post[] $items An array of menu item post objects. * @param WP_Term $menu The menu object. * @param array $args An array of arguments used to retrieve menu item objects. * @return WP_Post[] Array of menu item objects. */ public function filter_wp_get_nav_menu_items( $items, $menu, $args ) { $this_item = $this->value(); $current_nav_menu_term_id = null; if ( isset( $this_item['nav_menu_term_id'] ) ) { $current_nav_menu_term_id = $this_item['nav_menu_term_id']; unset( $this_item['nav_menu_term_id'] ); } $should_filter = ( $menu->term_id === $this->original_nav_menu_term_id || $menu->term_id === $current_nav_menu_term_id ); if ( ! $should_filter ) { return $items; } // Handle deleted menu item, or menu item moved to another menu. $should_remove = ( false === $this_item || ( isset( $this_item['_invalid'] ) && true === $this_item['_invalid'] ) || ( $this->original_nav_menu_term_id === $menu->term_id && $current_nav_menu_term_id !== $this->original_nav_menu_term_id ) ); if ( $should_remove ) { $filtered_items = array(); foreach ( $items as $item ) { if ( $item->db_id !== $this->post_id ) { $filtered_items[] = $item; } } return $filtered_items; } $mutated = false; $should_update = ( is_array( $this_item ) && $current_nav_menu_term_id === $menu->term_id ); if ( $should_update ) { foreach ( $items as $item ) { if ( $item->db_id === $this->post_id ) { foreach ( get_object_vars( $this->value_as_wp_post_nav_menu_item() ) as $key => $value ) { $item->$key = $value; } $mutated = true; } } // Not found so we have to append it.. if ( ! $mutated ) { $items[] = $this->value_as_wp_post_nav_menu_item(); } } return $items; } /** * Re-apply the tail logic also applied on $items by wp_get_nav_menu_items(). * * @since 4.3.0 * * @see wp_get_nav_menu_items() * * @param WP_Post[] $items An array of menu item post objects. * @param WP_Term $menu The menu object. * @param array $args An array of arguments used to retrieve menu item objects. * @return WP_Post[] Array of menu item objects. */ public static function sort_wp_get_nav_menu_items( $items, $menu, $args ) { // @todo We should probably re-apply some constraints imposed by $args. unset( $args['include'] ); // Remove invalid items only in front end. if ( ! is_admin() ) { $items = array_filter( $items, '_is_valid_nav_menu_item' ); } if ( ARRAY_A === $args['output'] ) { $items = wp_list_sort( $items, array( $args['output_key'] => 'ASC', ) ); $i = 1; foreach ( $items as $k => $item ) { $items[ $k ]->{$args['output_key']} = $i++; } } return $items; } /** * Get the value emulated into a WP_Post and set up as a nav_menu_item. * * @since 4.3.0 * * @return WP_Post With wp_setup_nav_menu_item() applied. */ public function value_as_wp_post_nav_menu_item() { $item = (object) $this->value(); unset( $item->nav_menu_term_id ); $item->post_status = $item->status; unset( $item->status ); $item->post_type = 'nav_menu_item'; $item->menu_order = $item->position; unset( $item->position ); if ( empty( $item->title ) && ! empty( $item->original_title ) ) { $item->title = $item->original_title; // This is NOT entity-decoded. It comes from self::get_original_title(). } if ( $item->title ) { $item->post_title = $item->title; } // 'classes' should be an array, as in wp_setup_nav_menu_item(). if ( isset( $item->classes ) && is_scalar( $item->classes ) ) { $item->classes = explode( ' ', $item->classes ); } $item->ID = $this->post_id; $item->db_id = $this->post_id; $post = new WP_Post( (object) $item ); if ( empty( $post->post_author ) ) { $post->post_author = get_current_user_id(); } if ( ! isset( $post->type_label ) ) { $post->type_label = $this->get_type_label( $post ); } // Ensure nav menu item URL is set according to linked object. if ( 'post_type' === $post->type && ! empty( $post->object_id ) ) { $post->url = get_permalink( $post->object_id ); } elseif ( 'taxonomy' === $post->type && ! empty( $post->object ) && ! empty( $post->object_id ) ) { $post->url = get_term_link( (int) $post->object_id, $post->object ); } elseif ( 'post_type_archive' === $post->type && ! empty( $post->object ) ) { $post->url = get_post_type_archive_link( $post->object ); } if ( is_wp_error( $post->url ) ) { $post->url = ''; } /** This filter is documented in wp-includes/nav-menu.php */ $post->attr_title = apply_filters( 'nav_menu_attr_title', $post->attr_title ); /** This filter is documented in wp-includes/nav-menu.php */ $post->description = apply_filters( 'nav_menu_description', wp_trim_words( $post->description, 200 ) ); /** This filter is documented in wp-includes/nav-menu.php */ $post = apply_filters( 'wp_setup_nav_menu_item', $post ); return $post; } /** * Sanitize an input. * * Note that parent::sanitize() erroneously does wp_unslash() on $value, but * we remove that in this override. * * @since 4.3.0 * @since 5.9.0 Renamed `$menu_item_value` to `$value` for PHP 8 named parameter support. * * @param array|false $value The menu item value to sanitize. * @return array|false|null|WP_Error Null or WP_Error if an input isn't valid. False if it is marked for deletion. * Otherwise the sanitized value. */ public function sanitize( $value ) { // Restores the more descriptive, specific name for use within this method. $menu_item_value = $value; // Menu is marked for deletion. if ( false === $menu_item_value ) { return $menu_item_value; } // Invalid. if ( ! is_array( $menu_item_value ) ) { return null; } $default = array( 'object_id' => 0, 'object' => '', 'menu_item_parent' => 0, 'position' => 0, 'type' => 'custom', 'title' => '', 'url' => '', 'target' => '', 'attr_title' => '', 'description' => '', 'classes' => '', 'xfn' => '', 'status' => 'publish', 'original_title' => '', 'nav_menu_term_id' => 0, '_invalid' => false, ); $menu_item_value = array_merge( $default, $menu_item_value ); $menu_item_value = wp_array_slice_assoc( $menu_item_value, array_keys( $default ) ); $menu_item_value['position'] = (int) $menu_item_value['position']; foreach ( array( 'object_id', 'menu_item_parent', 'nav_menu_term_id' ) as $key ) { // Note we need to allow negative-integer IDs for previewed objects not inserted yet. $menu_item_value[ $key ] = (int) $menu_item_value[ $key ]; } foreach ( array( 'type', 'object', 'target' ) as $key ) { $menu_item_value[ $key ] = sanitize_key( $menu_item_value[ $key ] ); } foreach ( array( 'xfn', 'classes' ) as $key ) { $value = $menu_item_value[ $key ]; if ( ! is_array( $value ) ) { $value = explode( ' ', $value ); } $menu_item_value[ $key ] = implode( ' ', array_map( 'sanitize_html_class', $value ) ); } // Apply the same filters as when calling wp_insert_post(). /** This filter is documented in wp-includes/post.php */ $menu_item_value['title'] = wp_unslash( apply_filters( 'title_save_pre', wp_slash( $menu_item_value['title'] ) ) ); /** This filter is documented in wp-includes/post.php */ $menu_item_value['attr_title'] = wp_unslash( apply_filters( 'excerpt_save_pre', wp_slash( $menu_item_value['attr_title'] ) ) ); /** This filter is documented in wp-includes/post.php */ $menu_item_value['description'] = wp_unslash( apply_filters( 'content_save_pre', wp_slash( $menu_item_value['description'] ) ) ); if ( '' !== $menu_item_value['url'] ) { $menu_item_value['url'] = sanitize_url( $menu_item_value['url'] ); if ( '' === $menu_item_value['url'] ) { return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) ); // Fail sanitization if URL is invalid. } } if ( 'publish' !== $menu_item_value['status'] ) { $menu_item_value['status'] = 'draft'; } $menu_item_value['_invalid'] = (bool) $menu_item_value['_invalid']; /** This filter is documented in wp-includes/class-wp-customize-setting.php */ return apply_filters( "customize_sanitize_{$this->id}", $menu_item_value, $this ); } /** * Creates/updates the nav_menu_item post for this setting. * * Any created menu items will have their assigned post IDs exported to the client * via the {@see 'customize_save_response'} filter. Likewise, any errors will be * exported to the client via the customize_save_response() filter. * * To delete a menu, the client can send false as the value. * * @since 4.3.0 * * @see wp_update_nav_menu_item() * * @param array|false $value The menu item array to update. If false, then the menu item will be deleted * entirely. See WP_Customize_Nav_Menu_Item_Setting::$default for what the value * should consist of. * @return null|void */ protected function update( $value ) { if ( $this->is_updated ) { return; } $this->is_updated = true; $is_placeholder = ( $this->post_id < 0 ); $is_delete = ( false === $value ); // Update the cached value. $this->value = $value; add_filter( 'customize_save_response', array( $this, 'amend_customize_save_response' ) ); if ( $is_delete ) { // If the current setting post is a placeholder, a delete request is a no-op. if ( $is_placeholder ) { $this->update_status = 'deleted'; } else { $r = wp_delete_post( $this->post_id, true ); if ( false === $r ) { $this->update_error = new WP_Error( 'delete_failure' ); $this->update_status = 'error'; } else { $this->update_status = 'deleted'; } // @todo send back the IDs for all associated nav menu items deleted, so these settings (and controls) can be removed from Customizer? } } else { // Handle saving menu items for menus that are being newly-created. if ( $value['nav_menu_term_id'] < 0 ) { $nav_menu_setting_id = sprintf( 'nav_menu[%s]', $value['nav_menu_term_id'] ); $nav_menu_setting = $this->manager->get_setting( $nav_menu_setting_id ); if ( ! $nav_menu_setting || ! ( $nav_menu_setting instanceof WP_Customize_Nav_Menu_Setting ) ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'unexpected_nav_menu_setting' ); return; } if ( false === $nav_menu_setting->save() ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'nav_menu_setting_failure' ); return; } if ( (int) $value['nav_menu_term_id'] !== $nav_menu_setting->previous_term_id ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'unexpected_previous_term_id' ); return; } $value['nav_menu_term_id'] = $nav_menu_setting->term_id; } // Handle saving a nav menu item that is a child of a nav menu item being newly-created. if ( $value['menu_item_parent'] < 0 ) { $parent_nav_menu_item_setting_id = sprintf( 'nav_menu_item[%s]', $value['menu_item_parent'] ); $parent_nav_menu_item_setting = $this->manager->get_setting( $parent_nav_menu_item_setting_id ); if ( ! $parent_nav_menu_item_setting || ! ( $parent_nav_menu_item_setting instanceof WP_Customize_Nav_Menu_Item_Setting ) ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'unexpected_nav_menu_item_setting' ); return; } if ( false === $parent_nav_menu_item_setting->save() ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'nav_menu_item_setting_failure' ); return; } if ( (int) $value['menu_item_parent'] !== $parent_nav_menu_item_setting->previous_post_id ) { $this->update_status = 'error'; $this->update_error = new WP_Error( 'unexpected_previous_post_id' ); return; } $value['menu_item_parent'] = $parent_nav_menu_item_setting->post_id; } // Insert or update menu. $menu_item_data = array( 'menu-item-object-id' => $value['object_id'], 'menu-item-object' => $value['object'], 'menu-item-parent-id' => $value['menu_item_parent'], 'menu-item-position' => $value['position'], 'menu-item-type' => $value['type'], 'menu-item-title' => $value['title'], 'menu-item-url' => $value['url'], 'menu-item-description' => $value['description'], 'menu-item-attr-title' => $value['attr_title'], 'menu-item-target' => $value['target'], 'menu-item-classes' => $value['classes'], 'menu-item-xfn' => $value['xfn'], 'menu-item-status' => $value['status'], ); $r = wp_update_nav_menu_item( $value['nav_menu_term_id'], $is_placeholder ? 0 : $this->post_id, wp_slash( $menu_item_data ) ); if ( is_wp_error( $r ) ) { $this->update_status = 'error'; $this->update_error = $r; } else { if ( $is_placeholder ) { $this->previous_post_id = $this->post_id; $this->post_id = $r; $this->update_status = 'inserted'; } else { $this->update_status = 'updated'; } } } } /** * Export data for the JS client. * * @since 4.3.0 * * @see WP_Customize_Nav_Menu_Item_Setting::update() * * @param array $data Additional information passed back to the 'saved' event on `wp.customize`. * @return array Save response data. */ public function amend_customize_save_response( $data ) { if ( ! isset( $data['nav_menu_item_updates'] ) ) { $data['nav_menu_item_updates'] = array(); } $data['nav_menu_item_updates'][] = array( 'post_id' => $this->post_id, 'previous_post_id' => $this->previous_post_id, 'error' => $this->update_error ? $this->update_error->get_error_code() : null, 'status' => $this->update_status, ); return $data; } } <?php /** * Customize API: WP_Widget_Area_Customize_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Widget Area Customize Control class. * * @since 3.9.0 * * @see WP_Customize_Control */ class WP_Widget_Area_Customize_Control extends WP_Customize_Control { /** * Customize control type. * * @since 3.9.0 * @var string */ public $type = 'sidebar_widgets'; /** * Sidebar ID. * * @since 3.9.0 * @var int|string */ public $sidebar_id; /** * Refreshes the parameters passed to the JavaScript via JSON. * * @since 3.9.0 */ public function to_json() { parent::to_json(); $exported_properties = array( 'sidebar_id' ); foreach ( $exported_properties as $key ) { $this->json[ $key ] = $this->$key; } } /** * Renders the control's content. * * @since 3.9.0 */ public function render_content() { $id = 'reorder-widgets-desc-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id ); ?> <button type="button" class="button add-new-widget" aria-expanded="false" aria-controls="available-widgets"> <?php _e( 'Add a Widget' ); ?> </button> <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder widgets' ); ?>" aria-describedby="<?php echo esc_attr( $id ); ?>"> <span class="reorder"><?php _e( 'Reorder' ); ?></span> <span class="reorder-done"><?php _e( 'Done' ); ?></span> </button> <p class="screen-reader-text" id="<?php echo esc_attr( $id ); ?>"> <?php /* translators: Hidden accessibility text. */ _e( 'When in reorder mode, additional controls to reorder widgets will be available in the widgets list above.' ); ?> </p> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menu_Locations_Control class * * @package WordPress * @subpackage Customize * @since 4.9.0 */ /** * Customize Nav Menu Locations Control Class. * * @since 4.9.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Locations_Control extends WP_Customize_Control { /** * Control type. * * @since 4.9.0 * @var string */ public $type = 'nav_menu_locations'; /** * Don't render the control's content - it uses a JS template instead. * * @since 4.9.0 */ public function render_content() {} /** * JS/Underscore template for the control UI. * * @since 4.9.0 */ public function content_template() { if ( current_theme_supports( 'menus' ) ) : ?> <# var elementId; #> <ul class="menu-location-settings"> <li class="customize-control assigned-menu-locations-title"> <span class="customize-control-title">{{ wp.customize.Menus.data.l10n.locationsTitle }}</span> <# if ( data.isCreating ) { #> <p> <?php echo _x( 'Where do you want this menu to appear?', 'menu locations' ); ?> <?php printf( /* translators: 1: Documentation URL, 2: Additional link attributes, 3: Accessibility text. */ _x( '(If you plan to use a menu <a href="%1$s" %2$s>widget%3$s</a>, skip this step.)', 'menu locations' ), __( 'https://wordpress.org/documentation/article/manage-wordpress-widgets/' ), ' class="external-link" target="_blank"', sprintf( '<span class="screen-reader-text"> %s</span>', /* translators: Hidden accessibility text. */ __( '(opens in a new tab)' ) ) ); ?> </p> <# } else { #> <p><?php echo _x( 'Here’s where this menu appears. If you would like to change that, pick another location.', 'menu locations' ); ?></p> <# } #> </li> <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?> <# elementId = _.uniqueId( 'customize-nav-menu-control-location-' ); #> <li class="customize-control customize-control-checkbox assigned-menu-location"> <span class="customize-inside-control-row"> <input id="{{ elementId }}" type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" /> <label for="{{ elementId }}"> <?php echo $description; ?> <span class="theme-location-set"> <?php printf( /* translators: %s: Menu name. */ _x( '(Current: %s)', 'menu location' ), '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>' ); ?> </span> </label> </span> </li> <?php endforeach; ?> </ul> <?php endif; } } <?php /** * Customize API: WP_Customize_Upload_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Upload Control Class. * * @since 3.4.0 * * @see WP_Customize_Media_Control */ class WP_Customize_Upload_Control extends WP_Customize_Media_Control { /** * Control type. * * @since 3.4.0 * @var string */ public $type = 'upload'; /** * Media control mime type. * * @since 4.1.0 * @var string */ public $mime_type = ''; /** * Button labels. * * @since 4.1.0 * @var array */ public $button_labels = array(); public $removed = ''; // Unused. public $context; // Unused. public $extensions = array(); // Unused. /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 3.4.0 * * @uses WP_Customize_Media_Control::to_json() */ public function to_json() { parent::to_json(); $value = $this->value(); if ( $value ) { // Get the attachment model for the existing file. $attachment_id = attachment_url_to_postid( $value ); if ( $attachment_id ) { $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id ); } } } } <?php /** * Customize API: WP_Customize_Nav_Menu_Section class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Menu Section Class * * Custom section only needed in JS. * * @since 4.3.0 * * @see WP_Customize_Section */ class WP_Customize_Nav_Menu_Section extends WP_Customize_Section { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'nav_menu'; /** * Get section parameters for JS. * * @since 4.3.0 * @return array Exported parameters. */ public function json() { $exported = parent::json(); $exported['menu_id'] = (int) preg_replace( '/^nav_menu\[(-?\d+)\]/', '$1', $this->id ); return $exported; } } <?php /** * Customize API: WP_Customize_Header_Image_Setting class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * A setting that is used to filter a value, but will not save the results. * * Results should be properly handled using another setting or callback. * * @since 3.4.0 * * @see WP_Customize_Setting */ final class WP_Customize_Header_Image_Setting extends WP_Customize_Setting { /** * Unique string identifier for the setting. * * @since 3.4.0 * @var string */ public $id = 'header_image_data'; /** * @since 3.4.0 * * @global Custom_Image_Header $custom_image_header * * @param mixed $value The value to update. */ public function update( $value ) { global $custom_image_header; // If _custom_header_background_just_in_time() fails to initialize $custom_image_header when not is_admin(). if ( empty( $custom_image_header ) ) { require_once ABSPATH . 'wp-admin/includes/class-custom-image-header.php'; $args = get_theme_support( 'custom-header' ); $admin_head_callback = isset( $args[0]['admin-head-callback'] ) ? $args[0]['admin-head-callback'] : null; $admin_preview_callback = isset( $args[0]['admin-preview-callback'] ) ? $args[0]['admin-preview-callback'] : null; $custom_image_header = new Custom_Image_Header( $admin_head_callback, $admin_preview_callback ); } /* * If the value doesn't exist (removed or random), * use the header_image value. */ if ( ! $value ) { $value = $this->manager->get_setting( 'header_image' )->post_value(); } if ( is_array( $value ) && isset( $value['choice'] ) ) { $custom_image_header->set_header_image( $value['choice'] ); } else { $custom_image_header->set_header_image( $value ); } } } <?php /** * Customize API: WP_Customize_Site_Icon_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Site Icon control class. * * Used only for custom functionality in JavaScript. * * @since 4.3.0 * * @see WP_Customize_Cropped_Image_Control */ class WP_Customize_Site_Icon_Control extends WP_Customize_Cropped_Image_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'site_icon'; /** * Constructor. * * @since 4.3.0 * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id Control ID. * @param array $args Optional. Arguments to override class property defaults. * See WP_Customize_Control::__construct() for information * on accepted arguments. Default empty array. */ public function __construct( $manager, $id, $args = array() ) { parent::__construct( $manager, $id, $args ); add_action( 'customize_controls_print_styles', 'wp_site_icon', 99 ); } /** * Renders a JS template for the content of the site icon control. * * @since 4.5.0 */ public function content_template() { ?> <# if ( data.label ) { #> <span class="customize-control-title">{{ data.label }}</span> <# } #> <# if ( data.attachment && data.attachment.id ) { #> <div class="attachment-media-view"> <# if ( data.attachment.sizes ) { #> <style> :root{ --site-icon-url: url( '{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}' ); } </style> <div class="site-icon-preview customizer"> <div class="direction-wrap"> <img src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" class="app-icon-preview" alt="{{ data.attachment.alt ? wp.i18n.sprintf( <?php /* translators: %s: The selected image alt text. */ echo wp_json_encode( __( 'App icon preview: Current image: %s' ) ) ?> , data.attachment.alt ) : wp.i18n.sprintf( <?php /* translators: %s: The selected image filename. */ echo wp_json_encode( __( 'App icon preview: The current image has no alternative text. The file name is: %s' ) ); ?> , data.attachment.filename ) }}" /> <div class="site-icon-preview-browser"> <svg role="img" aria-hidden="true" fill="none" xmlns="http://www.w3.org/2000/svg" class="browser-buttons"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 20a6 6 0 1 1 12 0 6 6 0 0 1-12 0Zm18 0a6 6 0 1 1 12 0 6 6 0 0 1-12 0Zm24-6a6 6 0 1 0 0 12 6 6 0 0 0 0-12Z" /></svg> <div class="site-icon-preview-tab"> <img src="{{ data.attachment.sizes.full ? data.attachment.sizes.full.url : data.attachment.url }}" class="browser-icon-preview" alt="{{ data.attachment.alt ? wp.i18n.sprintf( <?php /* translators: %s: The selected image alt text. */ echo wp_json_encode( __( 'Browser icon preview: Current image: %s' ) ); ?> , data.attachment.alt ) : wp.i18n.sprintf( <?php /* translators: %s: The selected image filename. */ echo wp_json_encode( __( 'Browser icon preview: The current image has no alternative text. The file name is: %s' ) ); ?> , data.attachment.filename ) }}" /> <div class="site-icon-preview-site-title" aria-hidden="true"><# print( '<?php echo esc_js( get_bloginfo( 'name' ) ); ?>' ) #></div> <svg role="img" aria-hidden="true" fill="none" xmlns="http://www.w3.org/2000/svg" class="close-button"> <path d="M12 13.0607L15.7123 16.773L16.773 15.7123L13.0607 12L16.773 8.28772L15.7123 7.22706L12 10.9394L8.28771 7.22705L7.22705 8.28771L10.9394 12L7.22706 15.7123L8.28772 16.773L12 13.0607Z" /> </svg> </div> </div> </div> </div> </div> <# } #> <div class="actions"> <# if ( data.canUpload ) { #> <button type="button" class="button remove-button"><?php echo $this->button_labels['remove']; ?></button> <button type="button" class="button upload-button"><?php echo $this->button_labels['change']; ?></button> <# } #> </div> </div> <# } else { #> <div class="attachment-media-view"> <# if ( data.canUpload ) { #> <button type="button" class="upload-button button-add-media"><?php echo $this->button_labels['site_icon']; ?></button> <# } #> <div class="actions"> <# if ( data.defaultAttachment ) { #> <button type="button" class="button default-button"><?php echo $this->button_labels['default']; ?></button> <# } #> </div> </div> <# } #> <# if ( data.description ) { #> <span class="description customize-control-description">{{{ data.description }}}</span> <# } #> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menu_Auto_Add_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize control to represent the auto_add field for a given menu. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Auto_Add_Control extends WP_Customize_Control { /** * Type of control, used by JS. * * @since 4.3.0 * @var string */ public $type = 'nav_menu_auto_add'; /** * No-op since we're using JS template. * * @since 4.3.0 */ protected function render_content() {} /** * Render the Underscore template for this control. * * @since 4.3.0 */ protected function content_template() { ?> <# var elementId = _.uniqueId( 'customize-nav-menu-auto-add-control-' ); #> <span class="customize-control-title"><?php _e( 'Menu Options' ); ?></span> <span class="customize-inside-control-row"> <input id="{{ elementId }}" type="checkbox" class="auto_add" /> <label for="{{ elementId }}"> <?php _e( 'Automatically add new top-level pages to this menu' ); ?> </label> </span> <?php } } <?php /** * Customize API: WP_Customize_Image_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Image Control class. * * @since 3.4.0 * * @see WP_Customize_Upload_Control */ class WP_Customize_Image_Control extends WP_Customize_Upload_Control { /** * Control type. * * @since 3.4.0 * @var string */ public $type = 'image'; /** * Media control mime type. * * @since 4.1.0 * @var string */ public $mime_type = 'image'; /** * @since 3.4.2 * @deprecated 4.1.0 */ public function prepare_control() {} /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $id * @param string $label * @param mixed $callback */ public function add_tab( $id, $label, $callback ) { _deprecated_function( __METHOD__, '4.1.0' ); } /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $id */ public function remove_tab( $id ) { _deprecated_function( __METHOD__, '4.1.0' ); } /** * @since 3.4.0 * @deprecated 4.1.0 * * @param string $url * @param string $thumbnail_url */ public function print_tab_image( $url, $thumbnail_url = null ) { _deprecated_function( __METHOD__, '4.1.0' ); } } <?php /** * Customize API: WP_Customize_Themes_Panel class * * @package WordPress * @subpackage Customize * @since 4.9.0 */ /** * Customize Themes Panel Class * * @since 4.9.0 * * @see WP_Customize_Panel */ class WP_Customize_Themes_Panel extends WP_Customize_Panel { /** * Panel type. * * @since 4.9.0 * @var string */ public $type = 'themes'; /** * An Underscore (JS) template for rendering this panel's container. * * The themes panel renders a custom panel heading with the active theme and a switch themes button. * * @see WP_Customize_Panel::print_template() * * @since 4.9.0 */ protected function render_template() { ?> <li id="accordion-section-{{ data.id }}" class="accordion-section control-panel-themes"> <h3 class="accordion-section-title"> <?php if ( $this->manager->is_theme_active() ) { echo '<span class="customize-action">' . __( 'Active theme' ) . '</span> {{ data.title }}'; } else { echo '<span class="customize-action">' . __( 'Previewing theme' ) . '</span> {{ data.title }}'; } ?> <?php if ( current_user_can( 'switch_themes' ) ) : ?> <button type="button" class="button change-theme" aria-label="<?php esc_attr_e( 'Change theme' ); ?>"><?php _ex( 'Change', 'theme' ); ?></button> <?php endif; ?> </h3> <ul class="accordion-sub-container control-panel-content"></ul> </li> <?php } /** * An Underscore (JS) template for this panel's content (but not its container). * * Class variables for this panel class are available in the `data` JS object; * export custom variables by overriding WP_Customize_Panel::json(). * * @since 4.9.0 * * @see WP_Customize_Panel::print_template() */ protected function content_template() { ?> <li class="panel-meta customize-info accordion-section <# if ( ! data.description ) { #> cannot-expand<# } #>"> <button class="customize-panel-back" tabindex="-1" type="button"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Back' ); ?> </span></button> <div class="accordion-section-title"> <span class="preview-notice"> <?php printf( /* translators: %s: Themes panel title in the Customizer. */ __( 'You are browsing %s' ), '<strong class="panel-title">' . __( 'Themes' ) . '</strong>' ); // Separate strings for consistency with other panels. ?> </span> <?php if ( current_user_can( 'install_themes' ) && ! is_multisite() ) : ?> <# if ( data.description ) { #> <button class="customize-help-toggle dashicons dashicons-editor-help" type="button" aria-expanded="false"><span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Help' ); ?> </span></button> <# } #> <?php endif; ?> </div> <?php if ( current_user_can( 'install_themes' ) && ! is_multisite() ) : ?> <# if ( data.description ) { #> <div class="description customize-panel-description"> {{{ data.description }}} </div> <# } #> <?php endif; ?> <div class="customize-control-notifications-container"></div> </li> <li class="customize-themes-full-container-container"> <div class="customize-themes-full-container"> <div class="customize-themes-notifications"></div> </div> </li> <?php } } <?php /** * Customize API: WP_Customize_Partial class * * @package WordPress * @subpackage Customize * @since 4.5.0 */ /** * Core Customizer class for implementing selective refresh partials. * * Representation of a rendered region in the previewed page that gets * selectively refreshed when an associated setting is changed. * This class is analogous of WP_Customize_Control. * * @since 4.5.0 */ #[AllowDynamicProperties] class WP_Customize_Partial { /** * Component. * * @since 4.5.0 * @var WP_Customize_Selective_Refresh */ public $component; /** * Unique identifier for the partial. * * If the partial is used to display a single setting, this would generally * be the same as the associated setting's ID. * * @since 4.5.0 * @var string */ public $id; /** * Parsed ID. * * @since 4.5.0 * @var array { * @type string $base ID base. * @type array $keys Keys for multidimensional. * } */ protected $id_data = array(); /** * Type of this partial. * * @since 4.5.0 * @var string */ public $type = 'default'; /** * The jQuery selector to find the container element for the partial. * * @since 4.5.0 * @var string */ public $selector; /** * IDs for settings tied to the partial. * * @since 4.5.0 * @var string[] */ public $settings; /** * The ID for the setting that this partial is primarily responsible for rendering. * * If not supplied, it will default to the ID of the first setting. * * @since 4.5.0 * @var string */ public $primary_setting; /** * Capability required to edit this partial. * * Normally this is empty and the capability is derived from the capabilities * of the associated `$settings`. * * @since 4.5.0 * @var string */ public $capability; /** * Render callback. * * @since 4.5.0 * * @see WP_Customize_Partial::render() * @var callable Callback is called with one argument, the instance of * WP_Customize_Partial. The callback can either echo the * partial or return the partial as a string, or return false if error. */ public $render_callback; /** * Whether the container element is included in the partial, or if only the contents are rendered. * * @since 4.5.0 * @var bool */ public $container_inclusive = false; /** * Whether to refresh the entire preview in case a partial cannot be refreshed. * * A partial render is considered a failure if the render_callback returns false. * * @since 4.5.0 * @var bool */ public $fallback_refresh = true; /** * Constructor. * * Supplied `$args` override class property defaults. * * If `$args['settings']` is not defined, use the $id as the setting ID. * * @since 4.5.0 * * @param WP_Customize_Selective_Refresh $component Customize Partial Refresh plugin instance. * @param string $id Control ID. * @param array $args { * Optional. Array of properties for the new Partials object. Default empty array. * * @type string $type Type of the partial to be created. * @type string $selector The jQuery selector to find the container element for the partial, that is, * a partial's placement. * @type string[] $settings IDs for settings tied to the partial. If undefined, `$id` will be used. * @type string $primary_setting The ID for the setting that this partial is primarily responsible for * rendering. If not supplied, it will default to the ID of the first setting. * @type string $capability Capability required to edit this partial. * Normally this is empty and the capability is derived from the capabilities * of the associated `$settings`. * @type callable $render_callback Render callback. * Callback is called with one argument, the instance of WP_Customize_Partial. * The callback can either echo the partial or return the partial as a string, * or return false if error. * @type bool $container_inclusive Whether the container element is included in the partial, or if only * the contents are rendered. * @type bool $fallback_refresh Whether to refresh the entire preview in case a partial cannot be refreshed. * A partial render is considered a failure if the render_callback returns * false. * } */ public function __construct( WP_Customize_Selective_Refresh $component, $id, $args = array() ) { $keys = array_keys( get_object_vars( $this ) ); foreach ( $keys as $key ) { if ( isset( $args[ $key ] ) ) { $this->$key = $args[ $key ]; } } $this->component = $component; $this->id = $id; $this->id_data['keys'] = preg_split( '/\[/', str_replace( ']', '', $this->id ) ); $this->id_data['base'] = array_shift( $this->id_data['keys'] ); if ( empty( $this->render_callback ) ) { $this->render_callback = array( $this, 'render_callback' ); } // Process settings. if ( ! isset( $this->settings ) ) { $this->settings = array( $id ); } elseif ( is_string( $this->settings ) ) { $this->settings = array( $this->settings ); } if ( empty( $this->primary_setting ) ) { $this->primary_setting = current( $this->settings ); } } /** * Retrieves parsed ID data for multidimensional setting. * * @since 4.5.0 * * @return array { * ID data for multidimensional partial. * * @type string $base ID base. * @type array $keys Keys for multidimensional array. * } */ final public function id_data() { return $this->id_data; } /** * Renders the template partial involving the associated settings. * * @since 4.5.0 * * @param array $container_context Optional. Array of context data associated with the target container (placement). * Default empty array. * @return string|array|false The rendered partial as a string, raw data array (for client-side JS template), * or false if no render applied. */ final public function render( $container_context = array() ) { $partial = $this; $rendered = false; if ( ! empty( $this->render_callback ) ) { ob_start(); $return_render = call_user_func( $this->render_callback, $this, $container_context ); $ob_render = ob_get_clean(); if ( null !== $return_render && '' !== $ob_render ) { _doing_it_wrong( __FUNCTION__, __( 'Partial render must echo the content or return the content string (or array), but not both.' ), '4.5.0' ); } /* * Note that the string return takes precedence because the $ob_render may just\ * include PHP warnings or notices. */ $rendered = null !== $return_render ? $return_render : $ob_render; } /** * Filters partial rendering. * * @since 4.5.0 * * @param string|array|false $rendered The partial value. Default false. * @param WP_Customize_Partial $partial WP_Customize_Setting instance. * @param array $container_context Optional array of context data associated with * the target container. */ $rendered = apply_filters( 'customize_partial_render', $rendered, $partial, $container_context ); /** * Filters partial rendering for a specific partial. * * The dynamic portion of the hook name, `$partial->ID` refers to the partial ID. * * @since 4.5.0 * * @param string|array|false $rendered The partial value. Default false. * @param WP_Customize_Partial $partial WP_Customize_Setting instance. * @param array $container_context Optional array of context data associated with * the target container. */ $rendered = apply_filters( "customize_partial_render_{$partial->id}", $rendered, $partial, $container_context ); return $rendered; } /** * Default callback used when invoking WP_Customize_Control::render(). * * Note that this method may echo the partial *or* return the partial as * a string or array, but not both. Output buffering is performed when this * is called. Subclasses can override this with their specific logic, or they * may provide an 'render_callback' argument to the constructor. * * This method may return an HTML string for straight DOM injection, or it * may return an array for supporting Partial JS subclasses to render by * applying to client-side templating. * * @since 4.5.0 * * @param WP_Customize_Partial $partial Partial. * @param array $context Context. * @return string|array|false */ public function render_callback( WP_Customize_Partial $partial, $context = array() ) { unset( $partial, $context ); return false; } /** * Retrieves the data to export to the client via JSON. * * @since 4.5.0 * * @return array Array of parameters passed to the JavaScript. */ public function json() { $exports = array( 'settings' => $this->settings, 'primarySetting' => $this->primary_setting, 'selector' => $this->selector, 'type' => $this->type, 'fallbackRefresh' => $this->fallback_refresh, 'containerInclusive' => $this->container_inclusive, ); return $exports; } /** * Checks if the user can refresh this partial. * * Returns false if the user cannot manipulate one of the associated settings, * or if one of the associated settings does not exist. * * @since 4.5.0 * * @return bool False if user can't edit one of the related settings, * or if one of the associated settings does not exist. */ final public function check_capabilities() { if ( ! empty( $this->capability ) && ! current_user_can( $this->capability ) ) { return false; } foreach ( $this->settings as $setting_id ) { $setting = $this->component->manager->get_setting( $setting_id ); if ( ! $setting || ! $setting->check_capabilities() ) { return false; } } return true; } } <?php /** * Customize API: WP_Customize_Selective_Refresh class * * @package WordPress * @subpackage Customize * @since 4.5.0 */ /** * Core Customizer class for implementing selective refresh. * * @since 4.5.0 */ #[AllowDynamicProperties] final class WP_Customize_Selective_Refresh { /** * Query var used in requests to render partials. * * @since 4.5.0 */ const RENDER_QUERY_VAR = 'wp_customize_render_partials'; /** * Customize manager. * * @since 4.5.0 * @var WP_Customize_Manager */ public $manager; /** * Registered instances of WP_Customize_Partial. * * @since 4.5.0 * @var WP_Customize_Partial[] */ protected $partials = array(); /** * Log of errors triggered when partials are rendered. * * @since 4.5.0 * @var array */ protected $triggered_errors = array(); /** * Keep track of the current partial being rendered. * * @since 4.5.0 * @var string|null */ protected $current_partial_id; /** * Plugin bootstrap for Partial Refresh functionality. * * @since 4.5.0 * * @param WP_Customize_Manager $manager Customizer bootstrap instance. */ public function __construct( WP_Customize_Manager $manager ) { $this->manager = $manager; require_once ABSPATH . WPINC . '/customize/class-wp-customize-partial.php'; add_action( 'customize_preview_init', array( $this, 'init_preview' ) ); } /** * Retrieves the registered partials. * * @since 4.5.0 * * @return array Partials. */ public function partials() { return $this->partials; } /** * Adds a partial. * * @since 4.5.0 * * @see WP_Customize_Partial::__construct() * * @param WP_Customize_Partial|string $id Customize Partial object, or Partial ID. * @param array $args Optional. Array of properties for the new Partials object. * See WP_Customize_Partial::__construct() for information * on accepted arguments. Default empty array. * @return WP_Customize_Partial The instance of the partial that was added. */ public function add_partial( $id, $args = array() ) { if ( $id instanceof WP_Customize_Partial ) { $partial = $id; } else { $class = 'WP_Customize_Partial'; /** This filter is documented in wp-includes/customize/class-wp-customize-selective-refresh.php */ $args = apply_filters( 'customize_dynamic_partial_args', $args, $id ); /** This filter is documented in wp-includes/customize/class-wp-customize-selective-refresh.php */ $class = apply_filters( 'customize_dynamic_partial_class', $class, $id, $args ); $partial = new $class( $this, $id, $args ); } $this->partials[ $partial->id ] = $partial; return $partial; } /** * Retrieves a partial. * * @since 4.5.0 * * @param string $id Customize Partial ID. * @return WP_Customize_Partial|null The partial, if set. Otherwise null. */ public function get_partial( $id ) { if ( isset( $this->partials[ $id ] ) ) { return $this->partials[ $id ]; } else { return null; } } /** * Removes a partial. * * @since 4.5.0 * * @param string $id Customize Partial ID. */ public function remove_partial( $id ) { unset( $this->partials[ $id ] ); } /** * Initializes the Customizer preview. * * @since 4.5.0 */ public function init_preview() { add_action( 'template_redirect', array( $this, 'handle_render_partials_request' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_preview_scripts' ) ); } /** * Enqueues preview scripts. * * @since 4.5.0 */ public function enqueue_preview_scripts() { wp_enqueue_script( 'customize-selective-refresh' ); add_action( 'wp_footer', array( $this, 'export_preview_data' ), 1000 ); } /** * Exports data in preview after it has finished rendering so that partials can be added at runtime. * * @since 4.5.0 */ public function export_preview_data() { $partials = array(); foreach ( $this->partials() as $partial ) { if ( $partial->check_capabilities() ) { $partials[ $partial->id ] = $partial->json(); } } $switched_locale = switch_to_user_locale( get_current_user_id() ); $l10n = array( 'shiftClickToEdit' => __( 'Shift-click to edit this element.' ), 'clickEditMenu' => __( 'Click to edit this menu.' ), 'clickEditWidget' => __( 'Click to edit this widget.' ), 'clickEditTitle' => __( 'Click to edit the site title.' ), 'clickEditMisc' => __( 'Click to edit this element.' ), /* translators: %s: document.write() */ 'badDocumentWrite' => sprintf( __( '%s is forbidden' ), 'document.write()' ), ); if ( $switched_locale ) { restore_previous_locale(); } $exports = array( 'partials' => $partials, 'renderQueryVar' => self::RENDER_QUERY_VAR, 'l10n' => $l10n, ); // Export data to JS. wp_print_inline_script_tag( sprintf( 'var _customizePartialRefreshExports = %s;', wp_json_encode( $exports ) ) ); } /** * Registers dynamically-created partials. * * @since 4.5.0 * * @see WP_Customize_Manager::add_dynamic_settings() * * @param string[] $partial_ids Array of the partial IDs to add. * @return WP_Customize_Partial[] Array of added WP_Customize_Partial instances. */ public function add_dynamic_partials( $partial_ids ) { $new_partials = array(); foreach ( $partial_ids as $partial_id ) { // Skip partials already created. $partial = $this->get_partial( $partial_id ); if ( $partial ) { continue; } $partial_args = false; $partial_class = 'WP_Customize_Partial'; /** * Filters a dynamic partial's constructor arguments. * * For a dynamic partial to be registered, this filter must be employed * to override the default false value with an array of args to pass to * the WP_Customize_Partial constructor. * * @since 4.5.0 * * @param false|array $partial_args The arguments to the WP_Customize_Partial constructor. * @param string $partial_id ID for dynamic partial. */ $partial_args = apply_filters( 'customize_dynamic_partial_args', $partial_args, $partial_id ); if ( false === $partial_args ) { continue; } /** * Filters the class used to construct partials. * * Allow non-statically created partials to be constructed with custom WP_Customize_Partial subclass. * * @since 4.5.0 * * @param string $partial_class WP_Customize_Partial or a subclass. * @param string $partial_id ID for dynamic partial. * @param array $partial_args The arguments to the WP_Customize_Partial constructor. */ $partial_class = apply_filters( 'customize_dynamic_partial_class', $partial_class, $partial_id, $partial_args ); $partial = new $partial_class( $this, $partial_id, $partial_args ); $this->add_partial( $partial ); $new_partials[] = $partial; } return $new_partials; } /** * Checks whether the request is for rendering partials. * * Note that this will not consider whether the request is authorized or valid, * just that essentially the route is a match. * * @since 4.5.0 * * @return bool Whether the request is for rendering partials. */ public function is_render_partials_request() { return ! empty( $_POST[ self::RENDER_QUERY_VAR ] ); } /** * Handles PHP errors triggered during rendering the partials. * * These errors will be relayed back to the client in the Ajax response. * * @since 4.5.0 * * @param int $errno Error number. * @param string $errstr Error string. * @param string $errfile Error file. * @param int $errline Error line. * @return true Always true. */ public function handle_error( $errno, $errstr, $errfile = null, $errline = null ) { $this->triggered_errors[] = array( 'partial' => $this->current_partial_id, 'error_number' => $errno, 'error_string' => $errstr, 'error_file' => $errfile, 'error_line' => $errline, ); return true; } /** * Handles the Ajax request to return the rendered partials for the requested placements. * * @since 4.5.0 */ public function handle_render_partials_request() { if ( ! $this->is_render_partials_request() ) { return; } /* * Note that is_customize_preview() returning true will entail that the * user passed the 'customize' capability check and the nonce check, since * WP_Customize_Manager::setup_theme() is where the previewing flag is set. */ if ( ! is_customize_preview() ) { wp_send_json_error( 'expected_customize_preview', 403 ); } elseif ( ! isset( $_POST['partials'] ) ) { wp_send_json_error( 'missing_partials', 400 ); } // Ensure that doing selective refresh on 404 template doesn't result in fallback rendering behavior (full refreshes). status_header( 200 ); $partials = json_decode( wp_unslash( $_POST['partials'] ), true ); if ( ! is_array( $partials ) ) { wp_send_json_error( 'malformed_partials' ); } $this->add_dynamic_partials( array_keys( $partials ) ); /** * Fires immediately before partials are rendered. * * Plugins may do things like call wp_enqueue_scripts() and gather a list of the scripts * and styles which may get enqueued in the response. * * @since 4.5.0 * * @param WP_Customize_Selective_Refresh $refresh Selective refresh component. * @param array $partials Placements' context data for the partials rendered in the request. * The array is keyed by partial ID, with each item being an array of * the placements' context data. */ do_action( 'customize_render_partials_before', $this, $partials ); set_error_handler( array( $this, 'handle_error' ), error_reporting() ); $contents = array(); foreach ( $partials as $partial_id => $container_contexts ) { $this->current_partial_id = $partial_id; if ( ! is_array( $container_contexts ) ) { wp_send_json_error( 'malformed_container_contexts' ); } $partial = $this->get_partial( $partial_id ); if ( ! $partial || ! $partial->check_capabilities() ) { $contents[ $partial_id ] = null; continue; } $contents[ $partial_id ] = array(); // @todo The array should include not only the contents, but also whether the container is included? if ( empty( $container_contexts ) ) { // Since there are no container contexts, render just once. $contents[ $partial_id ][] = $partial->render( null ); } else { foreach ( $container_contexts as $container_context ) { $contents[ $partial_id ][] = $partial->render( $container_context ); } } } $this->current_partial_id = null; restore_error_handler(); /** * Fires immediately after partials are rendered. * * Plugins may do things like call wp_footer() to scrape scripts output and return them * via the {@see 'customize_render_partials_response'} filter. * * @since 4.5.0 * * @param WP_Customize_Selective_Refresh $refresh Selective refresh component. * @param array $partials Placements' context data for the partials rendered in the request. * The array is keyed by partial ID, with each item being an array of * the placements' context data. */ do_action( 'customize_render_partials_after', $this, $partials ); $response = array( 'contents' => $contents, ); if ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) { $response['errors'] = $this->triggered_errors; } $setting_validities = $this->manager->validate_setting_values( $this->manager->unsanitized_post_values() ); $exported_setting_validities = array_map( array( $this->manager, 'prepare_setting_validity_for_js' ), $setting_validities ); $response['setting_validities'] = $exported_setting_validities; /** * Filters the response from rendering the partials. * * Plugins may use this filter to inject `$scripts` and `$styles`, which are dependencies * for the partials being rendered. The response data will be available to the client via * the `render-partials-response` JS event, so the client can then inject the scripts and * styles into the DOM if they have not already been enqueued there. * * If plugins do this, they'll need to take care for any scripts that do `document.write()` * and make sure that these are not injected, or else to override the function to no-op, * or else the page will be destroyed. * * Plugins should be aware that `$scripts` and `$styles` may eventually be included by * default in the response. * * @since 4.5.0 * * @param array $response { * Response. * * @type array $contents Associative array mapping a partial ID its corresponding array of contents * for the containers requested. * @type array $errors List of errors triggered during rendering of partials, if `WP_DEBUG_DISPLAY` * is enabled. * } * @param WP_Customize_Selective_Refresh $refresh Selective refresh component. * @param array $partials Placements' context data for the partials rendered in the request. * The array is keyed by partial ID, with each item being an array of * the placements' context data. */ $response = apply_filters( 'customize_render_partials_response', $response, $this, $partials ); wp_send_json_success( $response ); } } <?php /** * Customize API: WP_Customize_New_Menu_Section class * * @package WordPress * @subpackage Customize * @since 4.4.0 * @deprecated 4.9.0 This file is no longer used as of the menu creation UX introduced in #40104. */ _deprecated_file( basename( __FILE__ ), '4.9.0' ); /** * Customize Menu Section Class * * @since 4.3.0 * @deprecated 4.9.0 This class is no longer used as of the menu creation UX introduced in #40104. * * @see WP_Customize_Section */ class WP_Customize_New_Menu_Section extends WP_Customize_Section { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'new_menu'; /** * Constructor. * * Any supplied $args override class property defaults. * * @since 4.9.0 * @deprecated 4.9.0 * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id A specific ID of the section. * @param array $args Section arguments. */ public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { _deprecated_function( __METHOD__, '4.9.0' ); parent::__construct( $manager, $id, $args ); } /** * Render the section, and the controls that have been added to it. * * @since 4.3.0 * @deprecated 4.9.0 */ protected function render() { _deprecated_function( __METHOD__, '4.9.0' ); ?> <li id="accordion-section-<?php echo esc_attr( $this->id ); ?>" class="accordion-section-new-menu"> <button type="button" class="button add-new-menu-item add-menu-toggle" aria-expanded="false"> <?php echo esc_html( $this->title ); ?> </button> <ul class="new-menu-section-content"></ul> </li> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menus_Panel class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Nav Menus Panel Class * * Needed to add screen options. * * @since 4.3.0 * * @see WP_Customize_Panel */ class WP_Customize_Nav_Menus_Panel extends WP_Customize_Panel { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'nav_menus'; /** * Render screen options for Menus. * * @since 4.3.0 */ public function render_screen_options() { // Adds the screen options. require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; add_filter( 'manage_nav-menus_columns', 'wp_nav_menu_manage_columns' ); // Display screen options. $screen = WP_Screen::get( 'nav-menus.php' ); $screen->render_screen_options( array( 'wrap' => false ) ); } /** * Returns the advanced options for the nav menus page. * * Link title attribute added as it's a relatively advanced concept for new users. * * @since 4.3.0 * @deprecated 4.5.0 Deprecated in favor of wp_nav_menu_manage_columns(). */ public function wp_nav_menu_manage_columns() { _deprecated_function( __METHOD__, '4.5.0', 'wp_nav_menu_manage_columns' ); require_once ABSPATH . 'wp-admin/includes/nav-menu.php'; return wp_nav_menu_manage_columns(); } /** * An Underscore (JS) template for this panel's content (but not its container). * * Class variables for this panel class are available in the `data` JS object; * export custom variables by overriding WP_Customize_Panel::json(). * * @since 4.3.0 * * @see WP_Customize_Panel::print_template() */ protected function content_template() { ?> <li class="panel-meta customize-info accordion-section <# if ( ! data.description ) { #> cannot-expand<# } #>"> <button type="button" class="customize-panel-back" tabindex="-1"> <span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Back' ); ?> </span> </button> <div class="accordion-section-title"> <span class="preview-notice"> <?php /* translators: %s: The site/panel title in the Customizer. */ printf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' ); ?> </span> <button type="button" class="customize-help-toggle dashicons dashicons-editor-help" aria-expanded="false"> <span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Help' ); ?> </span> </button> <button type="button" class="customize-screen-options-toggle" aria-expanded="false"> <span class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'Menu Options' ); ?> </span> </button> </div> <# if ( data.description ) { #> <div class="description customize-panel-description">{{{ data.description }}}</div> <# } #> <div id="screen-options-wrap"> <?php $this->render_screen_options(); ?> </div> </li> <?php // NOTE: The following is a workaround for an inability to treat (and thus label) a list of sections as a whole. ?> <li class="customize-control-title customize-section-title-nav_menus-heading"><?php _e( 'Menus' ); ?></li> <?php } } <?php /** * Customize API: WP_Customize_Nav_Menu_Setting class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Setting to represent a nav_menu. * * Subclass of WP_Customize_Setting to represent a nav_menu taxonomy term, and * the IDs for the nav_menu_items associated with the nav menu. * * @since 4.3.0 * * @see wp_get_nav_menu_object() * @see WP_Customize_Setting */ class WP_Customize_Nav_Menu_Setting extends WP_Customize_Setting { const ID_PATTERN = '/^nav_menu\[(?P<id>-?\d+)\]$/'; const TAXONOMY = 'nav_menu'; const TYPE = 'nav_menu'; /** * Setting type. * * @since 4.3.0 * @var string */ public $type = self::TYPE; /** * Default setting value. * * @since 4.3.0 * @var array * * @see wp_get_nav_menu_object() */ public $default = array( 'name' => '', 'description' => '', 'parent' => 0, 'auto_add' => false, ); /** * Default transport. * * @since 4.3.0 * @var string */ public $transport = 'postMessage'; /** * The term ID represented by this setting instance. * * A negative value represents a placeholder ID for a new menu not yet saved. * * @since 4.3.0 * @var int */ public $term_id; /** * Previous (placeholder) term ID used before creating a new menu. * * This value will be exported to JS via the {@see 'customize_save_response'} filter * so that JavaScript can update the settings to refer to the newly-assigned * term ID. This value is always negative to indicate it does not refer to * a real term. * * @since 4.3.0 * @var int * * @see WP_Customize_Nav_Menu_Setting::update() * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response() */ public $previous_term_id; /** * Whether or not update() was called. * * @since 4.3.0 * @var bool */ protected $is_updated = false; /** * Status for calling the update method, used in customize_save_response filter. * * See {@see 'customize_save_response'}. * * When status is inserted, the placeholder term ID is stored in `$previous_term_id`. * When status is error, the error is stored in `$update_error`. * * @since 4.3.0 * @var string updated|inserted|deleted|error * * @see WP_Customize_Nav_Menu_Setting::update() * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response() */ public $update_status; /** * Any error object returned by wp_update_nav_menu_object() when setting is updated. * * @since 4.3.0 * @var WP_Error * * @see WP_Customize_Nav_Menu_Setting::update() * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response() */ public $update_error; /** * Constructor. * * Any supplied $args override class property defaults. * * @since 4.3.0 * * @throws Exception If $id is not valid for this setting type. * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id A specific ID of the setting. * Can be a theme mod or option name. * @param array $args Optional. Setting arguments. */ public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { if ( empty( $manager->nav_menus ) ) { throw new Exception( 'Expected WP_Customize_Manager::$nav_menus to be set.' ); } if ( ! preg_match( self::ID_PATTERN, $id, $matches ) ) { throw new Exception( "Illegal widget setting ID: $id" ); } $this->term_id = (int) $matches['id']; parent::__construct( $manager, $id, $args ); } /** * Get the instance data for a given widget setting. * * @since 4.3.0 * * @see wp_get_nav_menu_object() * * @return array Instance data. */ public function value() { if ( $this->is_previewed && get_current_blog_id() === $this->_previewed_blog_id ) { $undefined = new stdClass(); // Symbol. $post_value = $this->post_value( $undefined ); if ( $undefined === $post_value ) { $value = $this->_original_value; } else { $value = $post_value; } } else { $value = false; // Note that a term_id of less than one indicates a nav_menu not yet inserted. if ( $this->term_id > 0 ) { $term = wp_get_nav_menu_object( $this->term_id ); if ( $term ) { $value = wp_array_slice_assoc( (array) $term, array_keys( $this->default ) ); $nav_menu_options = (array) get_option( 'nav_menu_options', array() ); $value['auto_add'] = false; if ( isset( $nav_menu_options['auto_add'] ) && is_array( $nav_menu_options['auto_add'] ) ) { $value['auto_add'] = in_array( $term->term_id, $nav_menu_options['auto_add'], true ); } } } if ( ! is_array( $value ) ) { $value = $this->default; } } return $value; } /** * Handle previewing the setting. * * @since 4.3.0 * @since 4.4.0 Added boolean return value * * @see WP_Customize_Manager::post_value() * * @return bool False if method short-circuited due to no-op. */ public function preview() { if ( $this->is_previewed ) { return false; } $undefined = new stdClass(); $is_placeholder = ( $this->term_id < 0 ); $is_dirty = ( $undefined !== $this->post_value( $undefined ) ); if ( ! $is_placeholder && ! $is_dirty ) { return false; } $this->is_previewed = true; $this->_original_value = $this->value(); $this->_previewed_blog_id = get_current_blog_id(); add_filter( 'wp_get_nav_menus', array( $this, 'filter_wp_get_nav_menus' ), 10, 2 ); add_filter( 'wp_get_nav_menu_object', array( $this, 'filter_wp_get_nav_menu_object' ), 10, 2 ); add_filter( 'default_option_nav_menu_options', array( $this, 'filter_nav_menu_options' ) ); add_filter( 'option_nav_menu_options', array( $this, 'filter_nav_menu_options' ) ); return true; } /** * Filters the wp_get_nav_menus() result to ensure the inserted menu object is included, and the deleted one is removed. * * @since 4.3.0 * * @see wp_get_nav_menus() * * @param WP_Term[] $menus An array of menu objects. * @param array $args An array of arguments used to retrieve menu objects. * @return WP_Term[] Array of menu objects. */ public function filter_wp_get_nav_menus( $menus, $args ) { if ( get_current_blog_id() !== $this->_previewed_blog_id ) { return $menus; } $setting_value = $this->value(); $is_delete = ( false === $setting_value ); $index = -1; // Find the existing menu item's position in the list. foreach ( $menus as $i => $menu ) { if ( (int) $this->term_id === (int) $menu->term_id || (int) $this->previous_term_id === (int) $menu->term_id ) { $index = $i; break; } } if ( $is_delete ) { // Handle deleted menu by removing it from the list. if ( -1 !== $index ) { array_splice( $menus, $index, 1 ); } } else { // Handle menus being updated or inserted. $menu_obj = (object) array_merge( array( 'term_id' => $this->term_id, 'term_taxonomy_id' => $this->term_id, 'slug' => sanitize_title( $setting_value['name'] ), 'count' => 0, 'term_group' => 0, 'taxonomy' => self::TAXONOMY, 'filter' => 'raw', ), $setting_value ); array_splice( $menus, $index, ( -1 === $index ? 0 : 1 ), array( $menu_obj ) ); } // Make sure the menu objects get re-sorted after an update/insert. if ( ! $is_delete && ! empty( $args['orderby'] ) ) { $menus = wp_list_sort( $menus, array( $args['orderby'] => 'ASC', ) ); } // @todo Add support for $args['hide_empty'] === true. return $menus; } /** * Temporary non-closure passing of orderby value to function. * * @since 4.3.0 * @var string * * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus() * @see WP_Customize_Nav_Menu_Setting::_sort_menus_by_orderby() */ protected $_current_menus_sort_orderby; /** * Sort menu objects by the class-supplied orderby property. * * This is a workaround for a lack of closures. * * @since 4.3.0 * @deprecated 4.7.0 Use wp_list_sort() * * @param object $menu1 * @param object $menu2 * @return int * * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus() */ protected function _sort_menus_by_orderby( $menu1, $menu2 ) { _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' ); $key = $this->_current_menus_sort_orderby; return strcmp( $menu1->$key, $menu2->$key ); } /** * Filters the wp_get_nav_menu_object() result to supply the previewed menu object. * * Requesting a nav_menu object by anything but ID is not supported. * * @since 4.3.0 * * @see wp_get_nav_menu_object() * * @param object|null $menu_obj Object returned by wp_get_nav_menu_object(). * @param string $menu_id ID of the nav_menu term. Requests by slug or name will be ignored. * @return object|null */ public function filter_wp_get_nav_menu_object( $menu_obj, $menu_id ) { $ok = ( get_current_blog_id() === $this->_previewed_blog_id && is_int( $menu_id ) && $menu_id === $this->term_id ); if ( ! $ok ) { return $menu_obj; } $setting_value = $this->value(); // Handle deleted menus. if ( false === $setting_value ) { return false; } // Handle sanitization failure by preventing short-circuiting. if ( null === $setting_value ) { return $menu_obj; } $menu_obj = (object) array_merge( array( 'term_id' => $this->term_id, 'term_taxonomy_id' => $this->term_id, 'slug' => sanitize_title( $setting_value['name'] ), 'count' => 0, 'term_group' => 0, 'taxonomy' => self::TAXONOMY, 'filter' => 'raw', ), $setting_value ); return $menu_obj; } /** * Filters the nav_menu_options option to include this menu's auto_add preference. * * @since 4.3.0 * * @param array $nav_menu_options Nav menu options including auto_add. * @return array (Maybe) modified nav menu options. */ public function filter_nav_menu_options( $nav_menu_options ) { if ( get_current_blog_id() !== $this->_previewed_blog_id ) { return $nav_menu_options; } $menu = $this->value(); $nav_menu_options = $this->filter_nav_menu_options_value( $nav_menu_options, $this->term_id, false === $menu ? false : $menu['auto_add'] ); return $nav_menu_options; } /** * Sanitize an input. * * Note that parent::sanitize() erroneously does wp_unslash() on $value, but * we remove that in this override. * * @since 4.3.0 * * @param array $value The menu value to sanitize. * @return array|false|null Null if an input isn't valid. False if it is marked for deletion. * Otherwise the sanitized value. */ public function sanitize( $value ) { // Menu is marked for deletion. if ( false === $value ) { return $value; } // Invalid. if ( ! is_array( $value ) ) { return null; } $default = array( 'name' => '', 'description' => '', 'parent' => 0, 'auto_add' => false, ); $value = array_merge( $default, $value ); $value = wp_array_slice_assoc( $value, array_keys( $default ) ); $value['name'] = trim( esc_html( $value['name'] ) ); // This sanitization code is used in wp-admin/nav-menus.php. $value['description'] = sanitize_text_field( $value['description'] ); $value['parent'] = max( 0, (int) $value['parent'] ); $value['auto_add'] = ! empty( $value['auto_add'] ); if ( '' === $value['name'] ) { $value['name'] = _x( '(unnamed)', 'Missing menu name.' ); } /** This filter is documented in wp-includes/class-wp-customize-setting.php */ return apply_filters( "customize_sanitize_{$this->id}", $value, $this ); } /** * Storage for data to be sent back to client in customize_save_response filter. * * See {@see 'customize_save_response'}. * * @since 4.3.0 * @var array * * @see WP_Customize_Nav_Menu_Setting::amend_customize_save_response() */ protected $_widget_nav_menu_updates = array(); /** * Create/update the nav_menu term for this setting. * * Any created menus will have their assigned term IDs exported to the client * via the {@see 'customize_save_response'} filter. Likewise, any errors will be exported * to the client via the customize_save_response() filter. * * To delete a menu, the client can send false as the value. * * @since 4.3.0 * * @see wp_update_nav_menu_object() * * @param array|false $value { * The value to update. Note that slug cannot be updated via wp_update_nav_menu_object(). * If false, then the menu will be deleted entirely. * * @type string $name The name of the menu to save. * @type string $description The term description. Default empty string. * @type int $parent The id of the parent term. Default 0. * @type bool $auto_add Whether pages will auto_add to this menu. Default false. * } * @return null|void */ protected function update( $value ) { if ( $this->is_updated ) { return; } $this->is_updated = true; $is_placeholder = ( $this->term_id < 0 ); $is_delete = ( false === $value ); add_filter( 'customize_save_response', array( $this, 'amend_customize_save_response' ) ); $auto_add = null; if ( $is_delete ) { // If the current setting term is a placeholder, a delete request is a no-op. if ( $is_placeholder ) { $this->update_status = 'deleted'; } else { $r = wp_delete_nav_menu( $this->term_id ); if ( is_wp_error( $r ) ) { $this->update_status = 'error'; $this->update_error = $r; } else { $this->update_status = 'deleted'; $auto_add = false; } } } else { // Insert or update menu. $menu_data = wp_array_slice_assoc( $value, array( 'description', 'parent' ) ); $menu_data['menu-name'] = $value['name']; $menu_id = $is_placeholder ? 0 : $this->term_id; $r = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) ); $original_name = $menu_data['menu-name']; $name_conflict_suffix = 1; while ( is_wp_error( $r ) && 'menu_exists' === $r->get_error_code() ) { $name_conflict_suffix += 1; /* translators: 1: Original menu name, 2: Duplicate count. */ $menu_data['menu-name'] = sprintf( __( '%1$s (%2$d)' ), $original_name, $name_conflict_suffix ); $r = wp_update_nav_menu_object( $menu_id, wp_slash( $menu_data ) ); } if ( is_wp_error( $r ) ) { $this->update_status = 'error'; $this->update_error = $r; } else { if ( $is_placeholder ) { $this->previous_term_id = $this->term_id; $this->term_id = $r; $this->update_status = 'inserted'; } else { $this->update_status = 'updated'; } $auto_add = $value['auto_add']; } } if ( null !== $auto_add ) { $nav_menu_options = $this->filter_nav_menu_options_value( (array) get_option( 'nav_menu_options', array() ), $this->term_id, $auto_add ); update_option( 'nav_menu_options', $nav_menu_options ); } if ( 'inserted' === $this->update_status ) { // Make sure that new menus assigned to nav menu locations use their new IDs. foreach ( $this->manager->settings() as $setting ) { if ( ! preg_match( '/^nav_menu_locations\[/', $setting->id ) ) { continue; } $post_value = $setting->post_value( null ); if ( ! is_null( $post_value ) && (int) $post_value === $this->previous_term_id ) { $this->manager->set_post_value( $setting->id, $this->term_id ); $setting->save(); } } // Make sure that any nav_menu widgets referencing the placeholder nav menu get updated and sent back to client. foreach ( array_keys( $this->manager->unsanitized_post_values() ) as $setting_id ) { $nav_menu_widget_setting = $this->manager->get_setting( $setting_id ); if ( ! $nav_menu_widget_setting || ! preg_match( '/^widget_nav_menu\[/', $nav_menu_widget_setting->id ) ) { continue; } $widget_instance = $nav_menu_widget_setting->post_value(); // Note that this calls WP_Customize_Widgets::sanitize_widget_instance(). if ( empty( $widget_instance['nav_menu'] ) || (int) $widget_instance['nav_menu'] !== $this->previous_term_id ) { continue; } $widget_instance['nav_menu'] = $this->term_id; $updated_widget_instance = $this->manager->widgets->sanitize_widget_js_instance( $widget_instance ); $this->manager->set_post_value( $nav_menu_widget_setting->id, $updated_widget_instance ); $nav_menu_widget_setting->save(); $this->_widget_nav_menu_updates[ $nav_menu_widget_setting->id ] = $updated_widget_instance; } } } /** * Updates a nav_menu_options array. * * @since 4.3.0 * * @see WP_Customize_Nav_Menu_Setting::filter_nav_menu_options() * @see WP_Customize_Nav_Menu_Setting::update() * * @param array $nav_menu_options Array as returned by get_option( 'nav_menu_options' ). * @param int $menu_id The term ID for the given menu. * @param bool $auto_add Whether to auto-add or not. * @return array (Maybe) modified nav_menu_options array. */ protected function filter_nav_menu_options_value( $nav_menu_options, $menu_id, $auto_add ) { $nav_menu_options = (array) $nav_menu_options; if ( ! isset( $nav_menu_options['auto_add'] ) ) { $nav_menu_options['auto_add'] = array(); } $i = array_search( $menu_id, $nav_menu_options['auto_add'], true ); if ( $auto_add && false === $i ) { array_push( $nav_menu_options['auto_add'], $this->term_id ); } elseif ( ! $auto_add && false !== $i ) { array_splice( $nav_menu_options['auto_add'], $i, 1 ); } return $nav_menu_options; } /** * Export data for the JS client. * * @since 4.3.0 * * @see WP_Customize_Nav_Menu_Setting::update() * * @param array $data Additional information passed back to the 'saved' event on `wp.customize`. * @return array Export data. */ public function amend_customize_save_response( $data ) { if ( ! isset( $data['nav_menu_updates'] ) ) { $data['nav_menu_updates'] = array(); } if ( ! isset( $data['widget_nav_menu_updates'] ) ) { $data['widget_nav_menu_updates'] = array(); } $data['nav_menu_updates'][] = array( 'term_id' => $this->term_id, 'previous_term_id' => $this->previous_term_id, 'error' => $this->update_error ? $this->update_error->get_error_code() : null, 'status' => $this->update_status, 'saved_value' => 'deleted' === $this->update_status ? null : $this->value(), ); $data['widget_nav_menu_updates'] = array_merge( $data['widget_nav_menu_updates'], $this->_widget_nav_menu_updates ); $this->_widget_nav_menu_updates = array(); return $data; } } <?php /** * Customize API: WP_Customize_Nav_Menu_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Nav Menu Control Class. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'nav_menu'; /** * Don't render the control's content - it uses a JS template instead. * * @since 4.3.0 */ public function render_content() {} /** * JS/Underscore template for the control UI. * * @since 4.3.0 */ public function content_template() { $add_items = __( 'Add Items' ); ?> <p class="new-menu-item-invitation"> <?php printf( /* translators: %s: "Add Items" button text. */ __( 'Time to add some links! Click “%s” to start putting pages, categories, and custom links in your menu. Add as many things as you would like.' ), $add_items ); ?> </p> <div class="customize-control-nav_menu-buttons"> <button type="button" class="button add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items"> <?php echo $add_items; ?> </button> <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}"> <span class="reorder"><?php _e( 'Reorder' ); ?></span> <span class="reorder-done"><?php _e( 'Done' ); ?></span> </button> </div> <p class="screen-reader-text" id="reorder-items-desc-{{ data.menu_id }}"> <?php /* translators: Hidden accessibility text. */ _e( 'When in reorder mode, additional controls to reorder menu items will be available in the items list above.' ); ?> </p> <?php } /** * Return parameters for this control. * * @since 4.3.0 * * @return array Exported parameters. */ public function json() { $exported = parent::json(); $exported['menu_id'] = $this->setting->term_id; return $exported; } } <?php /** * Customize API: WP_Customize_Sidebar_Section class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customizer section representing widget area (sidebar). * * @since 4.1.0 * * @see WP_Customize_Section */ class WP_Customize_Sidebar_Section extends WP_Customize_Section { /** * Type of this section. * * @since 4.1.0 * @var string */ public $type = 'sidebar'; /** * Unique identifier. * * @since 4.1.0 * @var string */ public $sidebar_id; /** * Gather the parameters passed to client JavaScript via JSON. * * @since 4.1.0 * * @return array The array to be exported to the client as JSON. */ public function json() { $json = parent::json(); $json['sidebarId'] = $this->sidebar_id; return $json; } /** * Whether the current sidebar is rendered on the page. * * @since 4.1.0 * * @return bool Whether sidebar is rendered. */ public function active_callback() { return $this->manager->widgets->is_sidebar_rendered( $this->sidebar_id ); } } <?php /** * Customize API: WP_Customize_Background_Image_Setting class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customizer Background Image Setting class. * * @since 3.4.0 * * @see WP_Customize_Setting */ final class WP_Customize_Background_Image_Setting extends WP_Customize_Setting { /** * Unique string identifier for the setting. * * @since 3.4.0 * @var string */ public $id = 'background_image_thumb'; /** * @since 3.4.0 * * @param mixed $value The value to update. Not used. */ public function update( $value ) { remove_theme_mod( 'background_image_thumb' ); } } <?php /** * Customize API: WP_Customize_New_Menu_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 * @deprecated 4.9.0 This file is no longer used as of the menu creation UX introduced in #40104. */ _deprecated_file( basename( __FILE__ ), '4.9.0' ); /** * Customize control class for new menus. * * @since 4.3.0 * @deprecated 4.9.0 This class is no longer used as of the menu creation UX introduced in #40104. * * @see WP_Customize_Control */ class WP_Customize_New_Menu_Control extends WP_Customize_Control { /** * Control type. * * @since 4.3.0 * @var string */ public $type = 'new_menu'; /** * Constructor. * * @since 4.9.0 * @deprecated 4.9.0 * * @see WP_Customize_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. * @param string $id The control ID. * @param array $args Optional. Arguments to override class property defaults. * See WP_Customize_Control::__construct() for information * on accepted arguments. Default empty array. */ public function __construct( WP_Customize_Manager $manager, $id, array $args = array() ) { _deprecated_function( __METHOD__, '4.9.0' ); parent::__construct( $manager, $id, $args ); } /** * Render the control's content. * * @since 4.3.0 * @deprecated 4.9.0 */ public function render_content() { _deprecated_function( __METHOD__, '4.9.0' ); ?> <button type="button" class="button button-primary" id="create-new-menu-submit"><?php _e( 'Create Menu' ); ?></button> <span class="spinner"></span> <?php } } <?php /** * Customize API: WP_Customize_Theme_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Theme Control class. * * @since 4.2.0 * * @see WP_Customize_Control */ class WP_Customize_Theme_Control extends WP_Customize_Control { /** * Customize control type. * * @since 4.2.0 * @var string */ public $type = 'theme'; /** * Theme object. * * @since 4.2.0 * @var WP_Theme */ public $theme; /** * Refresh the parameters passed to the JavaScript via JSON. * * @since 4.2.0 * * @see WP_Customize_Control::to_json() */ public function to_json() { parent::to_json(); $this->json['theme'] = $this->theme; } /** * Don't render the control content from PHP, as it's rendered via JS on load. * * @since 4.2.0 */ public function render_content() {} /** * Render a JS template for theme display. * * @since 4.2.0 */ public function content_template() { /* translators: %s: Theme name. */ $details_label = sprintf( __( 'Details for theme: %s' ), '{{ data.theme.name }}' ); /* translators: %s: Theme name. */ $customize_label = sprintf( __( 'Customize theme: %s' ), '{{ data.theme.name }}' ); /* translators: %s: Theme name. */ $preview_label = sprintf( __( 'Live preview theme: %s' ), '{{ data.theme.name }}' ); /* translators: %s: Theme name. */ $install_label = sprintf( __( 'Install and preview theme: %s' ), '{{ data.theme.name }}' ); ?> <# if ( data.theme.active ) { #> <div class="theme active" tabindex="0" aria-describedby="{{ data.section }}-{{ data.theme.id }}-action"> <# } else { #> <div class="theme" tabindex="0" aria-describedby="{{ data.section }}-{{ data.theme.id }}-action"> <# } #> <# if ( data.theme.screenshot && data.theme.screenshot[0] ) { #> <div class="theme-screenshot"> <img data-src="{{ data.theme.screenshot[0] }}?ver={{ data.theme.version }}" alt="" /> </div> <# } else { #> <div class="theme-screenshot blank"></div> <# } #> <span class="more-details theme-details" id="{{ data.section }}-{{ data.theme.id }}-action" aria-label="<?php echo esc_attr( $details_label ); ?>"><?php _e( 'Theme Details' ); ?></span> <div class="theme-author"> <?php /* translators: Theme author name. */ printf( _x( 'By %s', 'theme author' ), '{{ data.theme.author }}' ); ?> </div> <# if ( 'installed' === data.theme.type && data.theme.hasUpdate ) { #> <# if ( data.theme.updateResponse.compatibleWP && data.theme.updateResponse.compatiblePHP ) { #> <div class="update-message notice inline notice-warning notice-alt" data-slug="{{ data.theme.id }}"> <p> <?php if ( is_multisite() ) { _e( 'New version available.' ); } else { printf( /* translators: %s: "Update now" button. */ __( 'New version available. %s' ), '<button class="button-link update-theme" type="button">' . __( 'Update now' ) . '</button>' ); } ?> </p> </div> <# } else { #> <div class="update-message notice inline notice-error notice-alt" data-slug="{{ data.theme.id }}"> <p> <# if ( ! data.theme.updateResponse.compatibleWP && ! data.theme.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your versions of WordPress and PHP.' ), '{{{ data.theme.name }}}' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.theme.updateResponse.compatibleWP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of WordPress.' ), '{{{ data.theme.name }}}' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.theme.updateResponse.compatiblePHP ) { #> <?php printf( /* translators: %s: Theme name. */ __( 'There is a new version of %s available, but it does not work with your version of PHP.' ), '{{{ data.theme.name }}}' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p> </div> <# } #> <# } #> <# if ( ! data.theme.compatibleWP || ! data.theme.compatiblePHP ) { #> <div class="notice notice-error notice-alt"><p> <# if ( ! data.theme.compatibleWP && ! data.theme.compatiblePHP ) { #> <?php _e( 'This theme does not work with your versions of WordPress and PHP.' ); if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { printf( /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ ' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ), self_admin_url( 'update-core.php' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } elseif ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } elseif ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } else if ( ! data.theme.compatibleWP ) { #> <?php _e( 'This theme does not work with your version of WordPress.' ); if ( current_user_can( 'update_core' ) ) { printf( /* translators: %s: URL to WordPress Updates screen. */ ' ' . __( '<a href="%s">Please update WordPress</a>.' ), self_admin_url( 'update-core.php' ) ); } ?> <# } else if ( ! data.theme.compatiblePHP ) { #> <?php _e( 'This theme does not work with your version of PHP.' ); if ( current_user_can( 'update_php' ) ) { printf( /* translators: %s: URL to Update PHP page. */ ' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ), esc_url( wp_get_update_php_url() ) ); wp_update_php_annotation( '</p><p><em>', '</em>' ); } ?> <# } #> </p></div> <# } #> <# if ( data.theme.active ) { #> <div class="theme-id-container"> <h3 class="theme-name" id="{{ data.section }}-{{ data.theme.id }}-name"> <span><?php _ex( 'Previewing:', 'theme' ); ?></span> {{ data.theme.name }} </h3> <div class="theme-actions"> <button type="button" class="button button-primary customize-theme" aria-label="<?php echo esc_attr( $customize_label ); ?>"><?php _e( 'Customize' ); ?></button> </div> </div> <?php wp_admin_notice( _x( 'Installed', 'theme' ), array( 'type' => 'success', 'additional_classes' => array( 'notice-alt' ), ) ); ?> <# } else if ( 'installed' === data.theme.type ) { #> <# if ( data.theme.blockTheme ) { #> <div class="theme-id-container"> <h3 class="theme-name" id="{{ data.section }}-{{ data.theme.id }}-name">{{ data.theme.name }}</h3> <div class="theme-actions"> <# if ( data.theme.actions.activate ) { #> <?php /* translators: %s: Theme name. */ $aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' ); ?> <a href="{{{ data.theme.actions.activate }}}" class="button button-primary activate" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a> <# } #> </div> </div> <?php $customizer_not_supported_message = __( 'This theme doesn\'t support Customizer.' ); ?> <# if ( data.theme.actions.activate ) { #> <?php $customizer_not_supported_message .= ' ' . sprintf( /* translators: %s: URL to the themes page (also it activates the theme). */ __( 'However, you can still <a href="%s">activate this theme</a>, and use the Site Editor to customize it.' ), '{{{ data.theme.actions.activate }}}' ); ?> <# } #> <?php wp_admin_notice( $customizer_not_supported_message, array( 'type' => 'error', 'additional_classes' => array( 'notice-alt' ), ) ); ?> <# } else { #> <div class="theme-id-container"> <h3 class="theme-name" id="{{ data.section }}-{{ data.theme.id }}-name">{{ data.theme.name }}</h3> <div class="theme-actions"> <# if ( data.theme.compatibleWP && data.theme.compatiblePHP ) { #> <button type="button" class="button button-primary preview-theme" aria-label="<?php echo esc_attr( $preview_label ); ?>" data-slug="{{ data.theme.id }}"><?php _e( 'Live Preview' ); ?></button> <# } else { #> <button type="button" class="button button-primary disabled" aria-label="<?php echo esc_attr( $preview_label ); ?>"><?php _e( 'Live Preview' ); ?></button> <# } #> </div> </div> <?php wp_admin_notice( _x( 'Installed', 'theme' ), array( 'type' => 'success', 'additional_classes' => array( 'notice-alt' ), ) ); ?> <# } #> <# } else { #> <div class="theme-id-container"> <h3 class="theme-name" id="{{ data.section }}-{{ data.theme.id }}-name">{{ data.theme.name }}</h3> <div class="theme-actions"> <# if ( data.theme.compatibleWP && data.theme.compatiblePHP ) { #> <button type="button" class="button button-primary theme-install preview" aria-label="<?php echo esc_attr( $install_label ); ?>" data-slug="{{ data.theme.id }}" data-name="{{ data.theme.name }}"><?php _e( 'Install & Preview' ); ?></button> <# } else { #> <button type="button" class="button button-primary disabled" aria-label="<?php echo esc_attr( $install_label ); ?>" disabled><?php _e( 'Install & Preview' ); ?></button> <# } #> </div> </div> <# } #> </div> <?php } } <?php /** * Customize API: WP_Customize_Background_Image_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Background Image Control class. * * @since 3.4.0 * * @see WP_Customize_Image_Control */ class WP_Customize_Background_Image_Control extends WP_Customize_Image_Control { /** * Customize control type. * * @since 4.1.0 * @var string */ public $type = 'background'; /** * Constructor. * * @since 3.4.0 * @uses WP_Customize_Image_Control::__construct() * * @param WP_Customize_Manager $manager Customizer bootstrap instance. */ public function __construct( $manager ) { parent::__construct( $manager, 'background_image', array( 'label' => __( 'Background Image' ), 'section' => 'background_image', ) ); } /** * Enqueue control related scripts/styles. * * @since 4.1.0 */ public function enqueue() { parent::enqueue(); $custom_background = get_theme_support( 'custom-background' ); wp_localize_script( 'customize-controls', '_wpCustomizeBackground', array( 'defaults' => ! empty( $custom_background[0] ) ? $custom_background[0] : array(), 'nonces' => array( 'add' => wp_create_nonce( 'background-add' ), ), ) ); } } <?php /** * Customize API: WP_Customize_Nav_Menu_Name_Control class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize control to represent the name field for a given menu. * * @since 4.3.0 * * @see WP_Customize_Control */ class WP_Customize_Nav_Menu_Name_Control extends WP_Customize_Control { /** * Type of control, used by JS. * * @since 4.3.0 * @var string */ public $type = 'nav_menu_name'; /** * No-op since we're using JS template. * * @since 4.3.0 */ protected function render_content() {} /** * Render the Underscore template for this control. * * @since 4.3.0 */ protected function content_template() { ?> <label> <# if ( data.label ) { #> <span class="customize-control-title">{{ data.label }}</span> <# } #> <input type="text" class="menu-name-field live-update-section-title" <# if ( data.description ) { #> aria-describedby="{{ data.section }}-description" <# } #> /> </label> <# if ( data.description ) { #> <p id="{{ data.section }}-description">{{ data.description }}</p> <# } #> <?php } } <?php /** * Customize API: WP_Customize_Themes_Section class * * @package WordPress * @subpackage Customize * @since 4.4.0 */ /** * Customize Themes Section class. * * A UI container for theme controls, which are displayed within sections. * * @since 4.2.0 * * @see WP_Customize_Section */ class WP_Customize_Themes_Section extends WP_Customize_Section { /** * Section type. * * @since 4.2.0 * @var string */ public $type = 'themes'; /** * Theme section action. * * Defines the type of themes to load (installed, wporg, etc.). * * @since 4.9.0 * @var string */ public $action = ''; /** * Theme section filter type. * * Determines whether filters are applied to loaded (local) themes or by initiating a new remote query (remote). * When filtering is local, the initial themes query is not paginated by default. * * @since 4.9.0 * @var string */ public $filter_type = 'local'; /** * Gets section parameters for JS. * * @since 4.9.0 * @return array Exported parameters. */ public function json() { $exported = parent::json(); $exported['action'] = $this->action; $exported['filter_type'] = $this->filter_type; return $exported; } /** * Renders a themes section as a JS template. * * The template is only rendered by PHP once, so all actions are prepared at once on the server side. * * @since 4.9.0 */ protected function render_template() { ?> <li id="accordion-section-{{ data.id }}" class="theme-section"> <button type="button" class="customize-themes-section-title themes-section-{{ data.id }}">{{ data.title }}</button> <?php if ( current_user_can( 'install_themes' ) || is_multisite() ) : // @todo Upload support. ?> <?php endif; ?> <div class="customize-themes-section themes-section-{{ data.id }} control-section-content themes-php"> <div class="theme-overlay" tabindex="0" role="dialog" aria-label="<?php esc_attr_e( 'Theme Details' ); ?>"></div> <div class="theme-browser rendered"> <div class="customize-preview-header themes-filter-bar"> <?php $this->filter_bar_content_template(); ?> </div> <?php $this->filter_drawer_content_template(); ?> <div class="error unexpected-error" style="display: none; "> <p> <?php printf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ); ?> </p> </div> <ul class="themes"> </ul> <p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p> <p class="no-themes-local"> <?php printf( /* translators: %s: "Search WordPress.org themes" button text. */ __( 'No themes found. Try a different search, or %s.' ), sprintf( '<button type="button" class="button-link search-dotorg-themes">%s</button>', __( 'Search WordPress.org themes' ) ) ); ?> </p> <p class="spinner"></p> </div> </div> </li> <?php } /** * Renders the filter bar portion of a themes section as a JS template. * * The template is only rendered by PHP once, so all actions are prepared at once on the server side. * The filter bar container is rendered by {@see render_template()}. * * @since 4.9.0 */ protected function filter_bar_content_template() { ?> <button type="button" class="button button-primary customize-section-back customize-themes-mobile-back"><?php _e( 'Go to theme sources' ); ?></button> <# if ( 'wporg' === data.action ) { #> <div class="themes-filter-container"> <label for="wp-filter-search-input-{{ data.id }}"><?php _e( 'Search themes' ); ?></label> <div class="search-form-input"> <input type="search" id="wp-filter-search-input-{{ data.id }}" aria-describedby="{{ data.id }}-live-search-desc" class="wp-filter-search"> <div class="search-icon" aria-hidden="true"></div> <span id="{{ data.id }}-live-search-desc" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'The search results will be updated as you type.' ); ?> </span> </div> </div> <# } else { #> <div class="themes-filter-container"> <label for="{{ data.id }}-themes-filter"><?php _e( 'Search themes' ); ?></label> <div class="search-form-input"> <input type="search" id="{{ data.id }}-themes-filter" aria-describedby="{{ data.id }}-live-search-desc" class="wp-filter-search wp-filter-search-themes" /> <div class="search-icon" aria-hidden="true"></div> <span id="{{ data.id }}-live-search-desc" class="screen-reader-text"> <?php /* translators: Hidden accessibility text. */ _e( 'The search results will be updated as you type.' ); ?> </span> </div> </div> <# } #> <div class="filter-themes-wrapper"> <# if ( 'wporg' === data.action ) { #> <button type="button" class="button feature-filter-toggle"> <span class="filter-count-0"><?php _e( 'Filter themes' ); ?></span><span class="filter-count-filters"> <?php /* translators: %s: Number of filters selected. */ printf( __( 'Filter themes (%s)' ), '<span class="theme-filter-count">0</span>' ); ?> </span> </button> <# } #> <div class="filter-themes-count"> <span class="themes-displayed"> <?php /* translators: %s: Number of themes displayed. */ printf( __( '%s themes' ), '<span class="theme-count">0</span>' ); ?> </span> </div> </div> <?php } /** * Renders the filter drawer portion of a themes section as a JS template. * * The filter bar container is rendered by {@see render_template()}. * * @since 4.9.0 */ protected function filter_drawer_content_template() { /* * @todo Use the .org API instead of the local core feature list. * The .org API is currently outdated and will be reconciled when the .org themes directory is next redesigned. */ $feature_list = get_theme_feature_list( false ); ?> <# if ( 'wporg' === data.action ) { #> <div class="filter-drawer filter-details"> <?php foreach ( $feature_list as $feature_name => $features ) : ?> <fieldset class="filter-group"> <legend><?php echo esc_html( $feature_name ); ?></legend> <div class="filter-group-feature"> <?php foreach ( $features as $feature => $feature_name ) : ?> <input type="checkbox" id="filter-id-<?php echo esc_attr( $feature ); ?>" value="<?php echo esc_attr( $feature ); ?>" /> <label for="filter-id-<?php echo esc_attr( $feature ); ?>"><?php echo esc_html( $feature_name ); ?></label> <?php endforeach; ?> </div> </fieldset> <?php endforeach; ?> </div> <# } #> <?php } } <?php /** * WordPress scripts and styles default loader. * * Several constants are used to manage the loading, concatenating and compression of scripts and CSS: * define('SCRIPT_DEBUG', true); loads the development (non-minified) versions of all scripts and CSS, and disables compression and concatenation, * define('CONCATENATE_SCRIPTS', false); disables compression and concatenation of scripts and CSS, * define('COMPRESS_SCRIPTS', false); disables compression of scripts, * define('COMPRESS_CSS', false); disables compression of CSS, * define('ENFORCE_GZIP', true); forces gzip for compression (default is deflate). * * The globals $concatenate_scripts, $compress_scripts and $compress_css can be set by plugins * to temporarily override the above settings. Also a compression test is run once and the result is saved * as option 'can_compress_scripts' (0/1). The test will run again if that option is deleted. * * @package WordPress */ /** WordPress Dependency Class */ require ABSPATH . WPINC . '/class-wp-dependency.php'; /** WordPress Dependencies Class */ require ABSPATH . WPINC . '/class-wp-dependencies.php'; /** WordPress Scripts Class */ require ABSPATH . WPINC . '/class-wp-scripts.php'; /** WordPress Scripts Functions */ require ABSPATH . WPINC . '/functions.wp-scripts.php'; /** WordPress Styles Class */ require ABSPATH . WPINC . '/class-wp-styles.php'; /** WordPress Styles Functions */ require ABSPATH . WPINC . '/functions.wp-styles.php'; /** * Registers TinyMCE scripts. * * @since 5.0.0 * * @global string $tinymce_version * @global bool $concatenate_scripts * @global bool $compress_scripts * * @param WP_Scripts $scripts WP_Scripts object. * @param bool $force_uncompressed Whether to forcibly prevent gzip compression. Default false. */ function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) { global $tinymce_version, $concatenate_scripts, $compress_scripts; $suffix = wp_scripts_get_suffix(); $dev_suffix = wp_scripts_get_suffix( 'dev' ); script_concat_settings(); $compressed = $compress_scripts && $concatenate_scripts && ! $force_uncompressed; /* * Load tinymce.js when running from /src, otherwise load wp-tinymce.js (in production) * or tinymce.min.js (when SCRIPT_DEBUG is true). */ if ( $compressed ) { $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . 'wp-tinymce.js', array(), $tinymce_version ); } else { $scripts->add( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce$dev_suffix.js", array(), $tinymce_version ); $scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin$dev_suffix.js", array( 'wp-tinymce-root' ), $tinymce_version ); } $scripts->add( 'wp-tinymce-lists', includes_url( "js/tinymce/plugins/lists/plugin$suffix.js" ), array( 'wp-tinymce' ), $tinymce_version ); } /** * Registers all the WordPress vendor scripts that are in the standardized * `js/dist/vendor/` location. * * For the order of `$scripts->add` see `wp_default_scripts`. * * @since 5.0.0 * * @global WP_Locale $wp_locale WordPress date and time locale object. * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_default_packages_vendor( $scripts ) { global $wp_locale; $suffix = wp_scripts_get_suffix(); $vendor_scripts = array( 'react', 'react-dom' => array( 'react' ), 'react-jsx-runtime' => array( 'react' ), 'regenerator-runtime', 'moment', 'lodash', 'wp-polyfill-fetch', 'wp-polyfill-formdata', 'wp-polyfill-node-contains', 'wp-polyfill-url', 'wp-polyfill-dom-rect', 'wp-polyfill-element-closest', 'wp-polyfill-object-fit', 'wp-polyfill-inert', 'wp-polyfill', ); $vendor_scripts_versions = array( 'react' => '18.3.1.1', // Final .1 due to switch to UMD build, can be removed in the next update. 'react-dom' => '18.3.1.1', // Final .1 due to switch to UMD build, can be removed in the next update. 'react-jsx-runtime' => '18.3.1', 'regenerator-runtime' => '0.14.1', 'moment' => '2.30.1', 'lodash' => '4.17.21', 'wp-polyfill-fetch' => '3.6.20', 'wp-polyfill-formdata' => '4.0.10', 'wp-polyfill-node-contains' => '4.8.0', 'wp-polyfill-url' => '3.6.4', 'wp-polyfill-dom-rect' => '4.8.0', 'wp-polyfill-element-closest' => '3.0.2', 'wp-polyfill-object-fit' => '2.3.5', 'wp-polyfill-inert' => '3.1.3', 'wp-polyfill' => '3.15.0', ); foreach ( $vendor_scripts as $handle => $dependencies ) { if ( is_string( $dependencies ) ) { $handle = $dependencies; $dependencies = array(); } $path = "/wp-includes/js/dist/vendor/$handle$suffix.js"; $version = $vendor_scripts_versions[ $handle ]; $scripts->add( $handle, $path, $dependencies, $version, 1 ); } did_action( 'init' ) && $scripts->add_inline_script( 'lodash', 'window.lodash = _.noConflict();' ); did_action( 'init' ) && $scripts->add_inline_script( 'moment', sprintf( "moment.updateLocale( '%s', %s );", esc_js( get_user_locale() ), wp_json_encode( array( 'months' => array_values( $wp_locale->month ), 'monthsShort' => array_values( $wp_locale->month_abbrev ), 'weekdays' => array_values( $wp_locale->weekday ), 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 'week' => array( 'dow' => (int) get_option( 'start_of_week', 0 ), ), 'longDateFormat' => array( 'LT' => get_option( 'time_format', __( 'g:i a' ) ), 'LTS' => null, 'L' => null, 'LL' => get_option( 'date_format', __( 'F j, Y' ) ), 'LLL' => __( 'F j, Y g:i a' ), 'LLLL' => null, ), ) ) ), 'after' ); } /** * Returns contents of an inline script used in appending polyfill scripts for * browsers which fail the provided tests. The provided array is a mapping from * a condition to verify feature support to its polyfill script handle. * * @since 5.0.0 * * @param WP_Scripts $scripts WP_Scripts object. * @param string[] $tests Features to detect. * @return string Conditional polyfill inline script. */ function wp_get_script_polyfill( $scripts, $tests ) { $polyfill = ''; foreach ( $tests as $test => $handle ) { if ( ! array_key_exists( $handle, $scripts->registered ) ) { continue; } $src = $scripts->registered[ $handle ]->src; $ver = $scripts->registered[ $handle ]->ver; if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $scripts->content_url && str_starts_with( $src, $scripts->content_url ) ) ) { $src = $scripts->base_url . $src; } if ( ! empty( $ver ) ) { $src = add_query_arg( 'ver', $ver, $src ); } /** This filter is documented in wp-includes/class-wp-scripts.php */ $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) ); if ( ! $src ) { continue; } $polyfill .= ( // Test presence of feature... '( ' . $test . ' ) || ' . /* * ...appending polyfill on any failures. Cautious viewers may balk * at the `document.write`. Its caveat of synchronous mid-stream * blocking write is exactly the behavior we need though. */ 'document.write( \'<script src="' . $src . '"></scr\' + \'ipt>\' );' ); } return $polyfill; } /** * Registers development scripts that integrate with `@wordpress/scripts`. * * @see https://github.com/WordPress/gutenberg/tree/trunk/packages/scripts#start * * @since 6.0.0 * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_register_development_scripts( $scripts ) { if ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG || empty( $scripts->registered['react'] ) || defined( 'WP_RUN_CORE_TESTS' ) ) { return; } $development_scripts = array( 'react-refresh-entry', 'react-refresh-runtime', ); foreach ( $development_scripts as $script_name ) { $assets = include ABSPATH . WPINC . '/assets/script-loader-' . $script_name . '.php'; if ( ! is_array( $assets ) ) { return; } $scripts->add( 'wp-' . $script_name, '/wp-includes/js/dist/development/' . $script_name . '.js', $assets['dependencies'], $assets['version'] ); } // See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react. $scripts->registered['react']->deps[] = 'wp-react-refresh-entry'; } /** * Registers all the WordPress packages scripts that are in the standardized * `js/dist/` location. * * For the order of `$scripts->add` see `wp_default_scripts`. * * @since 5.0.0 * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_default_packages_scripts( $scripts ) { $suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); /* * Expects multidimensional array like: * * 'a11y.js' => array('dependencies' => array(...), 'version' => '...'), * 'annotations.js' => array('dependencies' => array(...), 'version' => '...'), * 'api-fetch.js' => array(... */ $assets = include ABSPATH . WPINC . "/assets/script-loader-packages{$suffix}.php"; foreach ( $assets as $file_name => $package_data ) { $basename = str_replace( $suffix . '.js', '', basename( $file_name ) ); $handle = 'wp-' . $basename; $path = "/wp-includes/js/dist/{$basename}{$suffix}.js"; if ( ! empty( $package_data['dependencies'] ) ) { $dependencies = $package_data['dependencies']; } else { $dependencies = array(); } // Add dependencies that cannot be detected and generated by build tools. switch ( $handle ) { case 'wp-block-library': array_push( $dependencies, 'editor' ); break; case 'wp-edit-post': array_push( $dependencies, 'media-models', 'media-views', 'postbox', 'wp-dom-ready' ); break; case 'wp-preferences': array_push( $dependencies, 'wp-preferences-persistence' ); break; } $scripts->add( $handle, $path, $dependencies, $package_data['version'], 1 ); if ( in_array( 'wp-i18n', $dependencies, true ) ) { $scripts->set_translations( $handle ); } /* * Manually set the text direction localization after wp-i18n is printed. * This ensures that wp.i18n.isRTL() returns true in RTL languages. * We cannot use $scripts->set_translations( 'wp-i18n' ) to do this * because WordPress prints a script's translations *before* the script, * which means, in the case of wp-i18n, that wp.i18n.setLocaleData() * is called before wp.i18n is defined. */ if ( 'wp-i18n' === $handle ) { $ltr = _x( 'ltr', 'text direction' ); $script = sprintf( "wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ '%s' ] } );", $ltr ); $scripts->add_inline_script( $handle, $script, 'after' ); } } } /** * Adds inline scripts required for the WordPress JavaScript packages. * * @since 5.0.0 * @since 6.4.0 Added relative time strings for the `wp-date` inline script output. * * @global WP_Locale $wp_locale WordPress date and time locale object. * @global wpdb $wpdb WordPress database abstraction object. * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_default_packages_inline_scripts( $scripts ) { global $wp_locale, $wpdb; if ( isset( $scripts->registered['wp-api-fetch'] ) ) { $scripts->registered['wp-api-fetch']->deps[] = 'wp-hooks'; } $scripts->add_inline_script( 'wp-api-fetch', sprintf( 'wp.apiFetch.use( wp.apiFetch.createRootURLMiddleware( "%s" ) );', sanitize_url( get_rest_url() ) ), 'after' ); $scripts->add_inline_script( 'wp-api-fetch', implode( "\n", array( sprintf( 'wp.apiFetch.nonceMiddleware = wp.apiFetch.createNonceMiddleware( "%s" );', wp_installing() ? '' : wp_create_nonce( 'wp_rest' ) ), 'wp.apiFetch.use( wp.apiFetch.nonceMiddleware );', 'wp.apiFetch.use( wp.apiFetch.mediaUploadMiddleware );', sprintf( 'wp.apiFetch.nonceEndpoint = "%s";', admin_url( 'admin-ajax.php?action=rest-nonce' ) ), ) ), 'after' ); $meta_key = $wpdb->get_blog_prefix() . 'persisted_preferences'; $user_id = get_current_user_id(); $preload_data = get_user_meta( $user_id, $meta_key, true ); $scripts->add_inline_script( 'wp-preferences', sprintf( '( function() { var serverData = %s; var userId = "%d"; var persistenceLayer = wp.preferencesPersistence.__unstableCreatePersistenceLayer( serverData, userId ); var preferencesStore = wp.preferences.store; wp.data.dispatch( preferencesStore ).setPersistenceLayer( persistenceLayer ); } ) ();', wp_json_encode( $preload_data ), $user_id ) ); // Backwards compatibility - configure the old wp-data persistence system. $scripts->add_inline_script( 'wp-data', implode( "\n", array( '( function() {', ' var userId = ' . get_current_user_ID() . ';', ' var storageKey = "WP_DATA_USER_" + userId;', ' wp.data', ' .use( wp.data.plugins.persistence, { storageKey: storageKey } );', '} )();', ) ) ); // Calculate the timezone abbr (EDT, PST) if possible. $timezone_string = get_option( 'timezone_string', 'UTC' ); $timezone_abbr = ''; if ( ! empty( $timezone_string ) ) { $timezone_date = new DateTime( 'now', new DateTimeZone( $timezone_string ) ); $timezone_abbr = $timezone_date->format( 'T' ); } $gmt_offset = get_option( 'gmt_offset', 0 ); $scripts->add_inline_script( 'wp-date', sprintf( 'wp.date.setSettings( %s );', wp_json_encode( array( 'l10n' => array( 'locale' => get_user_locale(), 'months' => array_values( $wp_locale->month ), 'monthsShort' => array_values( $wp_locale->month_abbrev ), 'weekdays' => array_values( $wp_locale->weekday ), 'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ), 'meridiem' => (object) $wp_locale->meridiem, 'relative' => array( /* translators: %s: Duration. */ 'future' => __( '%s from now' ), /* translators: %s: Duration. */ 'past' => __( '%s ago' ), /* translators: One second from or to a particular datetime, e.g., "a second ago" or "a second from now". */ 's' => __( 'a second' ), /* translators: %d: Duration in seconds from or to a particular datetime, e.g., "4 seconds ago" or "4 seconds from now". */ 'ss' => __( '%d seconds' ), /* translators: One minute from or to a particular datetime, e.g., "a minute ago" or "a minute from now". */ 'm' => __( 'a minute' ), /* translators: %d: Duration in minutes from or to a particular datetime, e.g., "4 minutes ago" or "4 minutes from now". */ 'mm' => __( '%d minutes' ), /* translators: One hour from or to a particular datetime, e.g., "an hour ago" or "an hour from now". */ 'h' => __( 'an hour' ), /* translators: %d: Duration in hours from or to a particular datetime, e.g., "4 hours ago" or "4 hours from now". */ 'hh' => __( '%d hours' ), /* translators: One day from or to a particular datetime, e.g., "a day ago" or "a day from now". */ 'd' => __( 'a day' ), /* translators: %d: Duration in days from or to a particular datetime, e.g., "4 days ago" or "4 days from now". */ 'dd' => __( '%d days' ), /* translators: One month from or to a particular datetime, e.g., "a month ago" or "a month from now". */ 'M' => __( 'a month' ), /* translators: %d: Duration in months from or to a particular datetime, e.g., "4 months ago" or "4 months from now". */ 'MM' => __( '%d months' ), /* translators: One year from or to a particular datetime, e.g., "a year ago" or "a year from now". */ 'y' => __( 'a year' ), /* translators: %d: Duration in years from or to a particular datetime, e.g., "4 years ago" or "4 years from now". */ 'yy' => __( '%d years' ), ), 'startOfWeek' => (int) get_option( 'start_of_week', 0 ), ), 'formats' => array( /* translators: Time format, see https://www.php.net/manual/datetime.format.php */ 'time' => get_option( 'time_format', __( 'g:i a' ) ), /* translators: Date format, see https://www.php.net/manual/datetime.format.php */ 'date' => get_option( 'date_format', __( 'F j, Y' ) ), /* translators: Date/Time format, see https://www.php.net/manual/datetime.format.php */ 'datetime' => __( 'F j, Y g:i a' ), /* translators: Abbreviated date/time format, see https://www.php.net/manual/datetime.format.php */ 'datetimeAbbreviated' => __( 'M j, Y g:i a' ), ), 'timezone' => array( 'offset' => (float) $gmt_offset, 'offsetFormatted' => str_replace( array( '.25', '.5', '.75' ), array( ':15', ':30', ':45' ), (string) $gmt_offset ), 'string' => $timezone_string, 'abbr' => $timezone_abbr, ), ) ) ), 'after' ); // Loading the old editor and its config to ensure the classic block works as expected. $scripts->add_inline_script( 'editor', 'window.wp.oldEditor = window.wp.editor;', 'after' ); /* * wp-editor module is exposed as window.wp.editor. * Problem: there is quite some code expecting window.wp.oldEditor object available under window.wp.editor. * Solution: fuse the two objects together to maintain backward compatibility. * For more context, see https://github.com/WordPress/gutenberg/issues/33203. */ $scripts->add_inline_script( 'wp-editor', 'Object.assign( window.wp.editor, window.wp.oldEditor );', 'after' ); } /** * Adds inline scripts required for the TinyMCE in the block editor. * * These TinyMCE init settings are used to extend and override the default settings * from `_WP_Editors::default_settings()` for the Classic block. * * @since 5.0.0 * * @global WP_Scripts $wp_scripts */ function wp_tinymce_inline_scripts() { global $wp_scripts; /** This filter is documented in wp-includes/class-wp-editor.php */ $editor_settings = apply_filters( 'wp_editor_settings', array( 'tinymce' => true ), 'classic-block' ); $tinymce_plugins = array( 'charmap', 'colorpicker', 'hr', 'lists', 'media', 'paste', 'tabfocus', 'textcolor', 'fullscreen', 'wordpress', 'wpautoresize', 'wpeditimage', 'wpemoji', 'wpgallery', 'wplink', 'wpdialogs', 'wptextpattern', 'wpview', ); /** This filter is documented in wp-includes/class-wp-editor.php */ $tinymce_plugins = apply_filters( 'tiny_mce_plugins', $tinymce_plugins, 'classic-block' ); $tinymce_plugins = array_unique( $tinymce_plugins ); $disable_captions = false; // Runs after `tiny_mce_plugins` but before `mce_buttons`. /** This filter is documented in wp-admin/includes/media.php */ if ( apply_filters( 'disable_captions', '' ) ) { $disable_captions = true; } $toolbar1 = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker', 'wp_add_media', 'wp_adv', ); /** This filter is documented in wp-includes/class-wp-editor.php */ $toolbar1 = apply_filters( 'mce_buttons', $toolbar1, 'classic-block' ); $toolbar2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo', 'wp_help', ); /** This filter is documented in wp-includes/class-wp-editor.php */ $toolbar2 = apply_filters( 'mce_buttons_2', $toolbar2, 'classic-block' ); /** This filter is documented in wp-includes/class-wp-editor.php */ $toolbar3 = apply_filters( 'mce_buttons_3', array(), 'classic-block' ); /** This filter is documented in wp-includes/class-wp-editor.php */ $toolbar4 = apply_filters( 'mce_buttons_4', array(), 'classic-block' ); /** This filter is documented in wp-includes/class-wp-editor.php */ $external_plugins = apply_filters( 'mce_external_plugins', array(), 'classic-block' ); $tinymce_settings = array( 'plugins' => implode( ',', $tinymce_plugins ), 'toolbar1' => implode( ',', $toolbar1 ), 'toolbar2' => implode( ',', $toolbar2 ), 'toolbar3' => implode( ',', $toolbar3 ), 'toolbar4' => implode( ',', $toolbar4 ), 'external_plugins' => wp_json_encode( $external_plugins ), 'classic_block_editor' => true, ); if ( $disable_captions ) { $tinymce_settings['wpeditimage_disable_captions'] = true; } if ( ! empty( $editor_settings['tinymce'] ) && is_array( $editor_settings['tinymce'] ) ) { $tinymce_settings = array_merge( $tinymce_settings, $editor_settings['tinymce'] ); } /** This filter is documented in wp-includes/class-wp-editor.php */ $tinymce_settings = apply_filters( 'tiny_mce_before_init', $tinymce_settings, 'classic-block' ); /* * Do "by hand" translation from PHP array to js object. * Prevents breakage in some custom settings. */ $init_obj = ''; foreach ( $tinymce_settings as $key => $value ) { if ( is_bool( $value ) ) { $val = $value ? 'true' : 'false'; $init_obj .= $key . ':' . $val . ','; continue; } elseif ( ! empty( $value ) && is_string( $value ) && ( ( '{' === $value[0] && '}' === $value[ strlen( $value ) - 1 ] ) || ( '[' === $value[0] && ']' === $value[ strlen( $value ) - 1 ] ) || preg_match( '/^\(?function ?\(/', $value ) ) ) { $init_obj .= $key . ':' . $value . ','; continue; } $init_obj .= $key . ':"' . $value . '",'; } $init_obj = '{' . trim( $init_obj, ' ,' ) . '}'; $script = 'window.wpEditorL10n = { tinymce: { baseURL: ' . wp_json_encode( includes_url( 'js/tinymce' ) ) . ', suffix: ' . ( SCRIPT_DEBUG ? '""' : '".min"' ) . ', settings: ' . $init_obj . ', } }'; $wp_scripts->add_inline_script( 'wp-block-library', $script, 'before' ); } /** * Registers all the WordPress packages scripts. * * @since 5.0.0 * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_default_packages( $scripts ) { wp_default_packages_vendor( $scripts ); wp_register_development_scripts( $scripts ); wp_register_tinymce_scripts( $scripts ); wp_default_packages_scripts( $scripts ); if ( did_action( 'init' ) ) { wp_default_packages_inline_scripts( $scripts ); } } /** * Returns the suffix that can be used for the scripts. * * There are two suffix types, the normal one and the dev suffix. * * @since 5.0.0 * * @param string $type The type of suffix to retrieve. * @return string The script suffix. */ function wp_scripts_get_suffix( $type = '' ) { static $suffixes; if ( null === $suffixes ) { /* * Include an unmodified $wp_version. * * Note: wp_get_wp_version() is not used here, as this file can be included * via wp-admin/load-scripts.php or wp-admin/load-styles.php, in which case * wp-includes/functions.php is not loaded. */ require ABSPATH . WPINC . '/version.php'; /* * Note: str_contains() is not used here, as this file can be included * via wp-admin/load-scripts.php or wp-admin/load-styles.php, in which case * the polyfills from wp-includes/compat.php are not loaded. */ $develop_src = false !== strpos( $wp_version, '-src' ); if ( ! defined( 'SCRIPT_DEBUG' ) ) { define( 'SCRIPT_DEBUG', $develop_src ); } $suffix = SCRIPT_DEBUG ? '' : '.min'; $dev_suffix = $develop_src ? '' : '.min'; $suffixes = array( 'suffix' => $suffix, 'dev_suffix' => $dev_suffix, ); } if ( 'dev' === $type ) { return $suffixes['dev_suffix']; } return $suffixes['suffix']; } /** * Registers all WordPress scripts. * * Localizes some of them. * args order: `$scripts->add( 'handle', 'url', 'dependencies', 'query-string', 1 );` * when last arg === 1 queues the script for the footer * * @since 2.6.0 * * @param WP_Scripts $scripts WP_Scripts object. */ function wp_default_scripts( $scripts ) { $suffix = wp_scripts_get_suffix(); $dev_suffix = wp_scripts_get_suffix( 'dev' ); $guessurl = site_url(); if ( ! $guessurl ) { $guessed_url = true; $guessurl = wp_guess_url(); } $scripts->base_url = $guessurl; $scripts->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; $scripts->default_version = get_bloginfo( 'version' ); $scripts->default_dirs = array( '/wp-admin/js/', '/wp-includes/js/' ); $scripts->add( 'utils', "/wp-includes/js/utils$suffix.js" ); did_action( 'init' ) && $scripts->localize( 'utils', 'userSettings', array( 'url' => (string) SITECOOKIEPATH, 'uid' => (string) get_current_user_id(), 'time' => (string) time(), 'secure' => (string) ( 'https' === parse_url( site_url(), PHP_URL_SCHEME ) ), ) ); $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array( 'jquery', 'hoverIntent', 'utils', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'common' ); $bulk_action_observer_ids = array( 'bulk_action' => 'action', 'changeit' => 'new_role', ); did_action( 'init' ) && $scripts->localize( 'common', 'bulkActionObserverIds', /** * Filters the array of field name attributes for bulk actions. * * @since 6.8.1 * * @param array $bulk_action_observer_ids { * An array of field name attributes for bulk actions. * * @type string $bulk_action The bulk action field name. Default 'action'. * @type string $changeit The new role field name. Default 'new_role'. * } */ apply_filters( 'bulk_action_observer_ids', $bulk_action_observer_ids ) ); $scripts->add( 'wp-sanitize', "/wp-includes/js/wp-sanitize$suffix.js", array(), false, 1 ); $scripts->add( 'sack', "/wp-includes/js/tw-sack$suffix.js", array(), '1.6.1', 1 ); $scripts->add( 'quicktags', "/wp-includes/js/quicktags$suffix.js", array(), false, 1 ); did_action( 'init' ) && $scripts->localize( 'quicktags', 'quicktagsL10n', array( 'closeAllOpenTags' => __( 'Close all open tags' ), 'closeTags' => __( 'close tags' ), 'enterURL' => __( 'Enter the URL' ), 'enterImageURL' => __( 'Enter the URL of the image' ), 'enterImageDescription' => __( 'Enter a description of the image' ), 'textdirection' => __( 'text direction' ), 'toggleTextdirection' => __( 'Toggle Editor Text Direction' ), 'dfw' => __( 'Distraction-free writing mode' ), 'strong' => __( 'Bold' ), 'strongClose' => __( 'Close bold tag' ), 'em' => __( 'Italic' ), 'emClose' => __( 'Close italic tag' ), 'link' => __( 'Insert link' ), 'blockquote' => __( 'Blockquote' ), 'blockquoteClose' => __( 'Close blockquote tag' ), 'del' => __( 'Deleted text (strikethrough)' ), 'delClose' => __( 'Close deleted text tag' ), 'ins' => __( 'Inserted text' ), 'insClose' => __( 'Close inserted text tag' ), 'image' => __( 'Insert image' ), 'ul' => __( 'Bulleted list' ), 'ulClose' => __( 'Close bulleted list tag' ), 'ol' => __( 'Numbered list' ), 'olClose' => __( 'Close numbered list tag' ), 'li' => __( 'List item' ), 'liClose' => __( 'Close list item tag' ), 'code' => __( 'Code' ), 'codeClose' => __( 'Close code tag' ), 'more' => __( 'Insert Read More tag' ), ) ); $scripts->add( 'colorpicker', "/wp-includes/js/colorpicker$suffix.js", array( 'prototype' ), '3517m' ); $scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", array( 'utils', 'jquery' ), false, 1 ); $scripts->add( 'clipboard', "/wp-includes/js/clipboard$suffix.js", array(), '2.0.11', 1 ); $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-ajax-response', 'wpAjax', array( 'noPerm' => __( 'Sorry, you are not allowed to do that.' ), 'broken' => __( 'An error occurred while processing your request. Please try again later.' ), ) ); $scripts->add( 'wp-api-request', "/wp-includes/js/api-request$suffix.js", array( 'jquery' ), false, 1 ); // `wpApiSettings` is also used by `wp-api`, which depends on this script. did_action( 'init' ) && $scripts->localize( 'wp-api-request', 'wpApiSettings', array( 'root' => sanitize_url( get_rest_url() ), 'nonce' => wp_installing() ? '' : wp_create_nonce( 'wp_rest' ), 'versionString' => 'wp/v2/', ) ); $scripts->add( 'wp-pointer', "/wp-includes/js/wp-pointer$suffix.js", array( 'jquery-ui-core' ), false, 1 ); $scripts->set_translations( 'wp-pointer' ); $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array( 'heartbeat' ), false, 1 ); $scripts->add( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array( 'jquery', 'wp-hooks' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'heartbeat', 'heartbeatSettings', /** * Filters the Heartbeat settings. * * @since 3.6.0 * * @param array $settings Heartbeat settings array. */ apply_filters( 'heartbeat_settings', array() ) ); $scripts->add( 'wp-auth-check', "/wp-includes/js/wp-auth-check$suffix.js", array( 'heartbeat' ), false, 1 ); $scripts->set_translations( 'wp-auth-check' ); $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 ); $scripts->add( 'site-icon', '/wp-admin/js/site-icon.js', array( 'jquery' ), false, 1 ); $scripts->set_translations( 'site-icon' ); // WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source. $scripts->add( 'prototype', 'https://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1' ); $scripts->add( 'scriptaculous-root', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array( 'prototype' ), '1.9.0' ); $scripts->add( 'scriptaculous-builder', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/builder.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-dragdrop', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/dragdrop.js', array( 'scriptaculous-builder', 'scriptaculous-effects' ), '1.9.0' ); $scripts->add( 'scriptaculous-effects', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/effects.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-slider', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/slider.js', array( 'scriptaculous-effects' ), '1.9.0' ); $scripts->add( 'scriptaculous-sound', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/sound.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous-controls', 'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/controls.js', array( 'scriptaculous-root' ), '1.9.0' ); $scripts->add( 'scriptaculous', false, array( 'scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls' ) ); // Not used in core, replaced by Jcrop.js. $scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array( 'scriptaculous-dragdrop' ) ); /* * jQuery. * The unminified jquery.js and jquery-migrate.js are included to facilitate debugging. */ $scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ), '3.7.1' ); $scripts->add( 'jquery-core', "/wp-includes/js/jquery/jquery$suffix.js", array(), '3.7.1' ); $scripts->add( 'jquery-migrate', "/wp-includes/js/jquery/jquery-migrate$suffix.js", array(), '3.4.1' ); /* * Full jQuery UI. * The build process in 1.12.1 has changed significantly. * In order to keep backwards compatibility, and to keep the optimized loading, * the source files were flattened and included with some modifications for AMD loading. * A notable change is that 'jquery-ui-core' now contains 'jquery-ui-position' and 'jquery-ui-widget'. */ $scripts->add( 'jquery-ui-core', "/wp-includes/js/jquery/ui/core$suffix.js", array( 'jquery' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-core', "/wp-includes/js/jquery/ui/effect$suffix.js", array( 'jquery' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-blind', "/wp-includes/js/jquery/ui/effect-blind$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-bounce', "/wp-includes/js/jquery/ui/effect-bounce$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-clip', "/wp-includes/js/jquery/ui/effect-clip$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-drop', "/wp-includes/js/jquery/ui/effect-drop$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-explode', "/wp-includes/js/jquery/ui/effect-explode$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-fade', "/wp-includes/js/jquery/ui/effect-fade$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-fold', "/wp-includes/js/jquery/ui/effect-fold$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-highlight', "/wp-includes/js/jquery/ui/effect-highlight$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-puff', "/wp-includes/js/jquery/ui/effect-puff$suffix.js", array( 'jquery-effects-core', 'jquery-effects-scale' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-pulsate', "/wp-includes/js/jquery/ui/effect-pulsate$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-scale', "/wp-includes/js/jquery/ui/effect-scale$suffix.js", array( 'jquery-effects-core', 'jquery-effects-size' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-shake', "/wp-includes/js/jquery/ui/effect-shake$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-size', "/wp-includes/js/jquery/ui/effect-size$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-slide', "/wp-includes/js/jquery/ui/effect-slide$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-effects-transfer', "/wp-includes/js/jquery/ui/effect-transfer$suffix.js", array( 'jquery-effects-core' ), '1.13.3', 1 ); // Widgets $scripts->add( 'jquery-ui-accordion', "/wp-includes/js/jquery/ui/accordion$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-autocomplete', "/wp-includes/js/jquery/ui/autocomplete$suffix.js", array( 'jquery-ui-menu', 'wp-a11y' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-button', "/wp-includes/js/jquery/ui/button$suffix.js", array( 'jquery-ui-core', 'jquery-ui-controlgroup', 'jquery-ui-checkboxradio' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-datepicker', "/wp-includes/js/jquery/ui/datepicker$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-dialog', "/wp-includes/js/jquery/ui/dialog$suffix.js", array( 'jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-menu', "/wp-includes/js/jquery/ui/menu$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-mouse', "/wp-includes/js/jquery/ui/mouse$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-progressbar', "/wp-includes/js/jquery/ui/progressbar$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-selectmenu', "/wp-includes/js/jquery/ui/selectmenu$suffix.js", array( 'jquery-ui-menu' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-slider', "/wp-includes/js/jquery/ui/slider$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-spinner', "/wp-includes/js/jquery/ui/spinner$suffix.js", array( 'jquery-ui-button' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-tabs', "/wp-includes/js/jquery/ui/tabs$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-tooltip', "/wp-includes/js/jquery/ui/tooltip$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); // New in 1.12.1 $scripts->add( 'jquery-ui-checkboxradio', "/wp-includes/js/jquery/ui/checkboxradio$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-controlgroup', "/wp-includes/js/jquery/ui/controlgroup$suffix.js", array( 'jquery-ui-core' ), '1.13.3', 1 ); // Interactions $scripts->add( 'jquery-ui-draggable', "/wp-includes/js/jquery/ui/draggable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-droppable', "/wp-includes/js/jquery/ui/droppable$suffix.js", array( 'jquery-ui-draggable' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-resizable', "/wp-includes/js/jquery/ui/resizable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-selectable', "/wp-includes/js/jquery/ui/selectable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-sortable', "/wp-includes/js/jquery/ui/sortable$suffix.js", array( 'jquery-ui-mouse' ), '1.13.3', 1 ); /* * As of 1.12.1 `jquery-ui-position` and `jquery-ui-widget` are part of `jquery-ui-core`. * Listed here for back-compat. */ $scripts->add( 'jquery-ui-position', false, array( 'jquery-ui-core' ), '1.13.3', 1 ); $scripts->add( 'jquery-ui-widget', false, array( 'jquery-ui-core' ), '1.13.3', 1 ); // Deprecated, not used in core, most functionality is included in jQuery 1.3. $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array( 'jquery' ), '4.3.0', 1 ); // jQuery plugins. $scripts->add( 'jquery-color', '/wp-includes/js/jquery/jquery.color.min.js', array( 'jquery' ), '3.0.0', 1 ); $scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array( 'jquery' ), '20m', 1 ); $scripts->add( 'jquery-query', '/wp-includes/js/jquery/jquery.query.js', array( 'jquery' ), '2.2.3', 1 ); $scripts->add( 'jquery-serialize-object', '/wp-includes/js/jquery/jquery.serialize-object.js', array( 'jquery' ), '0.2-wp', 1 ); $scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array( 'jquery' ), '0.0.2m', 1 ); $scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array( 'jquery', 'jquery-hotkeys' ), false, 1 ); $scripts->add( 'jquery-touch-punch', '/wp-includes/js/jquery/jquery.ui.touch-punch.js', array( 'jquery-ui-core', 'jquery-ui-mouse' ), '0.2.2', 1 ); // Not used any more, registered for backward compatibility. $scripts->add( 'suggest', "/wp-includes/js/jquery/suggest$suffix.js", array( 'jquery' ), '1.1-20110113', 1 ); /* * Masonry v2 depended on jQuery. v3 does not. The older jquery-masonry handle is a shiv. * It sets jQuery as a dependency, as the theme may have been implicitly loading it this way. */ $scripts->add( 'imagesloaded', '/wp-includes/js/imagesloaded.min.js', array(), '5.0.0', 1 ); $scripts->add( 'masonry', '/wp-includes/js/masonry.min.js', array( 'imagesloaded' ), '4.2.2', 1 ); $scripts->add( 'jquery-masonry', '/wp-includes/js/jquery/jquery.masonry.min.js', array( 'jquery', 'masonry' ), '3.1.2b', 1 ); $scripts->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array( 'jquery' ), '3.1-20121105', 1 ); did_action( 'init' ) && $scripts->localize( 'thickbox', 'thickboxL10n', array( 'next' => __( 'Next >' ), 'prev' => __( '< Prev' ), 'image' => __( 'Image' ), 'of' => __( 'of' ), 'close' => __( 'Close' ), 'noiframes' => __( 'This feature requires inline frames. You have iframes disabled or your browser does not support them.' ), 'loadingAnimation' => includes_url( 'js/thickbox/loadingAnimation.gif' ), ) ); // Not used in core, replaced by imgAreaSelect. $scripts->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.js', array( 'jquery' ), '0.9.15' ); $scripts->add( 'swfobject', '/wp-includes/js/swfobject.js', array(), '2.2-20120417' ); // Error messages for Plupload. $uploader_l10n = array( 'queue_limit_exceeded' => __( 'You have attempted to queue too many files.' ), /* translators: %s: File name. */ 'file_exceeds_size_limit' => __( '%s exceeds the maximum upload size for this site.' ), 'zero_byte_file' => __( 'This file is empty. Please try another.' ), 'invalid_filetype' => __( 'This file cannot be processed by the web server.' ), 'not_an_image' => __( 'This file is not an image. Please try another.' ), 'image_memory_exceeded' => __( 'Memory exceeded. Please try another smaller file.' ), 'image_dimensions_exceeded' => __( 'This is larger than the maximum size. Please try another.' ), 'default_error' => __( 'An error occurred in the upload. Please try again later.' ), 'missing_upload_url' => __( 'There was a configuration error. Please contact the server administrator.' ), 'upload_limit_exceeded' => __( 'You may only upload 1 file.' ), 'http_error' => __( 'Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.' ), 'http_error_image' => __( 'The server cannot process the image. This can happen if the server is busy or does not have enough resources to complete the task. Uploading a smaller image may help. Suggested maximum size is 2560 pixels.' ), 'upload_failed' => __( 'Upload failed.' ), /* translators: 1: Opening link tag, 2: Closing link tag. */ 'big_upload_failed' => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.' ), /* translators: %s: File name. */ 'big_upload_queued' => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.' ), 'io_error' => __( 'IO error.' ), 'security_error' => __( 'Security error.' ), 'file_cancelled' => __( 'File canceled.' ), 'upload_stopped' => __( 'Upload stopped.' ), 'dismiss' => __( 'Dismiss' ), 'crunching' => __( 'Crunching…' ), 'deleted' => __( 'moved to the Trash.' ), /* translators: %s: File name. */ 'error_uploading' => __( '“%s” has failed to upload.' ), 'unsupported_image' => __( 'This image cannot be displayed in a web browser. For best results convert it to JPEG before uploading.' ), 'noneditable_image' => __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), 'file_url_copied' => __( 'The file URL has been copied to your clipboard' ), ); $scripts->add( 'moxiejs', "/wp-includes/js/plupload/moxie$suffix.js", array(), '1.3.5.1' ); $scripts->add( 'plupload', "/wp-includes/js/plupload/plupload$suffix.js", array( 'moxiejs' ), '2.1.9' ); // Back compat handles: foreach ( array( 'all', 'html5', 'flash', 'silverlight', 'html4' ) as $handle ) { $scripts->add( "plupload-$handle", false, array( 'plupload' ), '2.1.1' ); } $scripts->add( 'plupload-handlers', "/wp-includes/js/plupload/handlers$suffix.js", array( 'clipboard', 'jquery', 'plupload', 'underscore', 'wp-a11y', 'wp-i18n' ) ); did_action( 'init' ) && $scripts->localize( 'plupload-handlers', 'pluploadL10n', $uploader_l10n ); $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array( 'plupload', 'jquery', 'json2', 'media-models' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-plupload', 'pluploadL10n', $uploader_l10n ); // Keep 'swfupload' for back-compat. $scripts->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', array(), '2201-20110113' ); $scripts->add( 'swfupload-all', false, array( 'swfupload' ), '2201' ); $scripts->add( 'swfupload-handlers', "/wp-includes/js/swfupload/handlers$suffix.js", array( 'swfupload-all', 'jquery' ), '2201-20110524' ); did_action( 'init' ) && $scripts->localize( 'swfupload-handlers', 'swfuploadL10n', $uploader_l10n ); $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", array(), false, 1 ); did_action( 'init' ) && $scripts->add_data( 'comment-reply', 'strategy', 'async' ); $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2015-05-03' ); did_action( 'init' ) && $scripts->add_data( 'json2', 'conditional', 'lt IE 8' ); $scripts->add( 'underscore', "/wp-includes/js/underscore$dev_suffix.js", array(), '1.13.7', 1 ); $scripts->add( 'backbone', "/wp-includes/js/backbone$dev_suffix.js", array( 'underscore', 'jquery' ), '1.6.0', 1 ); $scripts->add( 'wp-util', "/wp-includes/js/wp-util$suffix.js", array( 'underscore', 'jquery' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-util', '_wpUtilSettings', array( 'ajax' => array( 'url' => admin_url( 'admin-ajax.php', 'relative' ), ), ) ); $scripts->add( 'wp-backbone', "/wp-includes/js/wp-backbone$suffix.js", array( 'backbone', 'wp-util' ), false, 1 ); $scripts->add( 'revisions', "/wp-admin/js/revisions$suffix.js", array( 'wp-backbone', 'jquery-ui-slider', 'hoverIntent' ), false, 1 ); $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'mediaelement', false, array( 'jquery', 'mediaelement-core', 'mediaelement-migrate' ), '4.2.17', 1 ); $scripts->add( 'mediaelement-core', "/wp-includes/js/mediaelement/mediaelement-and-player$suffix.js", array(), '4.2.17', 1 ); $scripts->add( 'mediaelement-migrate', "/wp-includes/js/mediaelement/mediaelement-migrate$suffix.js", array(), false, 1 ); did_action( 'init' ) && $scripts->add_inline_script( 'mediaelement-core', sprintf( 'var mejsL10n = %s;', wp_json_encode( array( 'language' => strtolower( strtok( determine_locale(), '_-' ) ), 'strings' => array( 'mejs.download-file' => __( 'Download File' ), 'mejs.install-flash' => __( 'You are using a browser that does not have Flash player enabled or installed. Please turn on your Flash player plugin or download the latest version from https://get.adobe.com/flashplayer/' ), 'mejs.fullscreen' => __( 'Fullscreen' ), 'mejs.play' => __( 'Play' ), 'mejs.pause' => __( 'Pause' ), 'mejs.time-slider' => __( 'Time Slider' ), 'mejs.time-help-text' => __( 'Use Left/Right Arrow keys to advance one second, Up/Down arrows to advance ten seconds.' ), 'mejs.live-broadcast' => __( 'Live Broadcast' ), 'mejs.volume-help-text' => __( 'Use Up/Down Arrow keys to increase or decrease volume.' ), 'mejs.unmute' => __( 'Unmute' ), 'mejs.mute' => __( 'Mute' ), 'mejs.volume-slider' => __( 'Volume Slider' ), 'mejs.video-player' => __( 'Video Player' ), 'mejs.audio-player' => __( 'Audio Player' ), 'mejs.captions-subtitles' => __( 'Captions/Subtitles' ), 'mejs.captions-chapters' => __( 'Chapters' ), 'mejs.none' => __( 'None' ), 'mejs.afrikaans' => __( 'Afrikaans' ), 'mejs.albanian' => __( 'Albanian' ), 'mejs.arabic' => __( 'Arabic' ), 'mejs.belarusian' => __( 'Belarusian' ), 'mejs.bulgarian' => __( 'Bulgarian' ), 'mejs.catalan' => __( 'Catalan' ), 'mejs.chinese' => __( 'Chinese' ), 'mejs.chinese-simplified' => __( 'Chinese (Simplified)' ), 'mejs.chinese-traditional' => __( 'Chinese (Traditional)' ), 'mejs.croatian' => __( 'Croatian' ), 'mejs.czech' => __( 'Czech' ), 'mejs.danish' => __( 'Danish' ), 'mejs.dutch' => __( 'Dutch' ), 'mejs.english' => __( 'English' ), 'mejs.estonian' => __( 'Estonian' ), 'mejs.filipino' => __( 'Filipino' ), 'mejs.finnish' => __( 'Finnish' ), 'mejs.french' => __( 'French' ), 'mejs.galician' => __( 'Galician' ), 'mejs.german' => __( 'German' ), 'mejs.greek' => __( 'Greek' ), 'mejs.haitian-creole' => __( 'Haitian Creole' ), 'mejs.hebrew' => __( 'Hebrew' ), 'mejs.hindi' => __( 'Hindi' ), 'mejs.hungarian' => __( 'Hungarian' ), 'mejs.icelandic' => __( 'Icelandic' ), 'mejs.indonesian' => __( 'Indonesian' ), 'mejs.irish' => __( 'Irish' ), 'mejs.italian' => __( 'Italian' ), 'mejs.japanese' => __( 'Japanese' ), 'mejs.korean' => __( 'Korean' ), 'mejs.latvian' => __( 'Latvian' ), 'mejs.lithuanian' => __( 'Lithuanian' ), 'mejs.macedonian' => __( 'Macedonian' ), 'mejs.malay' => __( 'Malay' ), 'mejs.maltese' => __( 'Maltese' ), 'mejs.norwegian' => __( 'Norwegian' ), 'mejs.persian' => __( 'Persian' ), 'mejs.polish' => __( 'Polish' ), 'mejs.portuguese' => __( 'Portuguese' ), 'mejs.romanian' => __( 'Romanian' ), 'mejs.russian' => __( 'Russian' ), 'mejs.serbian' => __( 'Serbian' ), 'mejs.slovak' => __( 'Slovak' ), 'mejs.slovenian' => __( 'Slovenian' ), 'mejs.spanish' => __( 'Spanish' ), 'mejs.swahili' => __( 'Swahili' ), 'mejs.swedish' => __( 'Swedish' ), 'mejs.tagalog' => __( 'Tagalog' ), 'mejs.thai' => __( 'Thai' ), 'mejs.turkish' => __( 'Turkish' ), 'mejs.ukrainian' => __( 'Ukrainian' ), 'mejs.vietnamese' => __( 'Vietnamese' ), 'mejs.welsh' => __( 'Welsh' ), 'mejs.yiddish' => __( 'Yiddish' ), ), ) ) ), 'before' ); $scripts->add( 'mediaelement-vimeo', '/wp-includes/js/mediaelement/renderers/vimeo.min.js', array( 'mediaelement' ), '4.2.17', 1 ); $scripts->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.js", array( 'mediaelement' ), false, 1 ); $mejs_settings = array( 'pluginPath' => includes_url( 'js/mediaelement/', 'relative' ), 'classPrefix' => 'mejs-', 'stretching' => 'responsive', /** This filter is documented in wp-includes/media.php */ 'audioShortcodeLibrary' => apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ), /** This filter is documented in wp-includes/media.php */ 'videoShortcodeLibrary' => apply_filters( 'wp_video_shortcode_library', 'mediaelement' ), ); did_action( 'init' ) && $scripts->localize( 'mediaelement', '_wpmejsSettings', /** * Filters the MediaElement configuration settings. * * @since 4.4.0 * * @param array $mejs_settings MediaElement settings array. */ apply_filters( 'mejs_settings', $mejs_settings ) ); $scripts->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.js', array(), '5.29.1-alpha-ee20357' ); $scripts->add( 'csslint', '/wp-includes/js/codemirror/csslint.js', array(), '1.0.5' ); $scripts->add( 'esprima', '/wp-includes/js/codemirror/esprima.js', array(), '4.0.0' ); $scripts->add( 'jshint', '/wp-includes/js/codemirror/fakejshint.js', array( 'esprima' ), '2.9.5' ); $scripts->add( 'jsonlint', '/wp-includes/js/codemirror/jsonlint.js', array(), '1.6.2' ); $scripts->add( 'htmlhint', '/wp-includes/js/codemirror/htmlhint.js', array(), '0.9.14-xwp' ); $scripts->add( 'htmlhint-kses', '/wp-includes/js/codemirror/htmlhint-kses.js', array( 'htmlhint' ) ); $scripts->add( 'code-editor', "/wp-admin/js/code-editor$suffix.js", array( 'jquery', 'wp-codemirror', 'underscore' ) ); $scripts->add( 'wp-theme-plugin-editor', "/wp-admin/js/theme-plugin-editor$suffix.js", array( 'common', 'wp-util', 'wp-sanitize', 'jquery', 'jquery-ui-core', 'wp-a11y', 'underscore' ), false, 1 ); $scripts->set_translations( 'wp-theme-plugin-editor' ); $scripts->add( 'wp-playlist', "/wp-includes/js/mediaelement/wp-playlist$suffix.js", array( 'wp-util', 'backbone', 'mediaelement' ), false, 1 ); $scripts->add( 'zxcvbn-async', "/wp-includes/js/zxcvbn-async$suffix.js", array(), '1.0' ); did_action( 'init' ) && $scripts->localize( 'zxcvbn-async', '_zxcvbnSettings', array( 'src' => empty( $guessed_url ) ? includes_url( '/js/zxcvbn.min.js' ) : $scripts->base_url . '/wp-includes/js/zxcvbn.min.js', ) ); $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array( 'jquery', 'zxcvbn-async' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'password-strength-meter', 'pwsL10n', array( 'unknown' => _x( 'Password strength unknown', 'password strength' ), 'short' => _x( 'Very weak', 'password strength' ), 'bad' => _x( 'Weak', 'password strength' ), 'good' => _x( 'Medium', 'password strength' ), 'strong' => _x( 'Strong', 'password strength' ), 'mismatch' => _x( 'Mismatch', 'password mismatch' ), ) ); $scripts->set_translations( 'password-strength-meter' ); $scripts->add( 'password-toggle', "/wp-admin/js/password-toggle$suffix.js", array(), false, 1 ); $scripts->set_translations( 'password-toggle' ); $scripts->add( 'application-passwords', "/wp-admin/js/application-passwords$suffix.js", array( 'jquery', 'wp-util', 'wp-api-request', 'wp-date', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'application-passwords' ); $scripts->add( 'auth-app', "/wp-admin/js/auth-app$suffix.js", array( 'jquery', 'wp-api-request', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'auth-app' ); $scripts->add( 'user-profile', "/wp-admin/js/user-profile$suffix.js", array( 'clipboard', 'jquery', 'password-strength-meter', 'wp-util', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'user-profile' ); $user_id = isset( $_GET['user_id'] ) ? (int) $_GET['user_id'] : 0; did_action( 'init' ) && $scripts->localize( 'user-profile', 'userProfileL10n', array( 'user_id' => $user_id, 'nonce' => wp_installing() ? '' : wp_create_nonce( 'reset-password-for-' . $user_id ), ) ); $scripts->add( 'language-chooser', "/wp-admin/js/language-chooser$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'user-suggest', "/wp-admin/js/user-suggest$suffix.js", array( 'jquery-ui-autocomplete' ), false, 1 ); $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array( 'hoverintent-js' ), false, 1 ); $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'common', 'jquery', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'wplink' ); did_action( 'init' ) && $scripts->localize( 'wplink', 'wpLinkL10n', array( 'title' => __( 'Insert/edit link' ), 'update' => __( 'Update' ), 'save' => __( 'Add Link' ), 'noTitle' => __( '(no title)' ), 'noMatchesFound' => __( 'No results found.' ), 'linkSelected' => __( 'Link selected.' ), 'linkInserted' => __( 'Link inserted.' ), /* translators: Minimum input length in characters to start searching posts in the "Insert/edit link" modal. */ 'minInputLength' => (int) _x( '3', 'minimum input length for searching post links' ), ) ); $scripts->add( 'wpdialogs', "/wp-includes/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), false, 1 ); $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 ); $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 ); $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.10.2', 1 ); // JS-only version of hoverintent (no dependencies). $scripts->add( 'hoverintent-js', '/wp-includes/js/hoverintent-js.min.js', array(), '2.2.1', 1 ); $scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 ); $scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 ); $scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'wp-a11y', 'customize-base' ), false, 1 ); $scripts->add( 'customize-models', '/wp-includes/js/customize-models.js', array( 'underscore', 'backbone' ), false, 1 ); $scripts->add( 'customize-views', '/wp-includes/js/customize-views.js', array( 'jquery', 'underscore', 'imgareaselect', 'customize-models', 'media-editor', 'media-views' ), false, 1 ); $scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base', 'wp-a11y', 'wp-util', 'jquery-ui-core' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'customize-controls', '_wpCustomizeControlsL10n', array( 'activate' => __( 'Activate & Publish' ), 'save' => __( 'Save & Publish' ), // @todo Remove as not required. 'publish' => __( 'Publish' ), 'published' => __( 'Published' ), 'saveDraft' => __( 'Save Draft' ), 'draftSaved' => __( 'Draft Saved' ), 'updating' => __( 'Updating' ), 'schedule' => _x( 'Schedule', 'customizer changeset action/button label' ), 'scheduled' => _x( 'Scheduled', 'customizer changeset status' ), 'invalid' => __( 'Invalid' ), 'saveBeforeShare' => __( 'Please save your changes in order to share the preview.' ), 'futureDateError' => __( 'You must supply a future date to schedule.' ), 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ), 'saved' => __( 'Saved' ), 'cancel' => __( 'Cancel' ), 'close' => __( 'Close' ), 'action' => __( 'Action' ), 'discardChanges' => __( 'Discard changes' ), 'cheatin' => __( 'An error occurred. Please try again later.' ), 'notAllowedHeading' => __( 'You need a higher level of permission.' ), 'notAllowed' => __( 'Sorry, you are not allowed to customize this site.' ), 'previewIframeTitle' => __( 'Site Preview' ), 'loginIframeTitle' => __( 'Session expired' ), 'collapseSidebar' => _x( 'Hide Controls', 'label for hide controls button without length constraints' ), 'expandSidebar' => _x( 'Show Controls', 'label for hide controls button without length constraints' ), 'untitledBlogName' => __( '(Untitled)' ), 'unknownRequestFail' => __( 'Looks like something’s gone wrong. Wait a couple seconds, and then try again.' ), 'themeDownloading' => __( 'Downloading your new theme…' ), 'themePreviewWait' => __( 'Setting up your live preview. This may take a bit.' ), 'revertingChanges' => __( 'Reverting unpublished changes…' ), 'trashConfirm' => __( 'Are you sure you want to discard your unpublished changes?' ), /* translators: %s: Display name of the user who has taken over the changeset in customizer. */ 'takenOverMessage' => __( '%s has taken over and is currently customizing.' ), /* translators: %s: URL to the Customizer to load the autosaved version. */ 'autosaveNotice' => __( 'There is a more recent autosave of your changes than the one you are previewing. <a href="%s">Restore the autosave</a>' ), 'videoHeaderNotice' => __( 'This theme does not support video headers on this page. Navigate to the front page or another page that supports video headers.' ), // Used for overriding the file types allowed in Plupload. 'allowedFiles' => __( 'Allowed Files' ), 'customCssError' => array( /* translators: %d: Error count. */ 'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ), /* translators: %d: Error count. */ 'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ), // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. ), 'pageOnFrontError' => __( 'Homepage and posts page must be different.' ), 'saveBlockedError' => array( /* translators: %s: Number of invalid settings. */ 'singular' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 1 ), /* translators: %s: Number of invalid settings. */ 'plural' => _n( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.', 2 ), // @todo This is lacking, as some languages have a dedicated dual form. For proper handling of plurals in JS, see #20491. ), 'scheduleDescription' => __( 'Schedule your customization changes to publish ("go live") at a future date.' ), 'themePreviewUnavailable' => __( 'Sorry, you cannot preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.' ), 'themeInstallUnavailable' => sprintf( /* translators: %s: URL to Add Themes admin screen. */ __( 'You will not be able to install new themes from here yet since your install requires SFTP credentials. For now, please <a href="%s">add themes in the admin</a>.' ), esc_url( admin_url( 'theme-install.php' ) ) ), 'publishSettings' => __( 'Publish Settings' ), 'invalidDate' => __( 'Invalid date.' ), 'invalidValue' => __( 'Invalid value.' ), 'blockThemeNotification' => sprintf( /* translators: 1: Link to Site Editor documentation on HelpHub, 2: HTML button. */ __( 'Hurray! Your theme supports site editing with blocks. <a href="%1$s">Tell me more</a>. %2$s' ), __( 'https://wordpress.org/documentation/article/site-editor/' ), sprintf( '<button type="button" data-action="%1$s" class="button switch-to-editor">%2$s</button>', esc_url( admin_url( 'site-editor.php' ) ), __( 'Use Site Editor' ) ) ), ) ); $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); $scripts->add( 'customize-widgets', "/wp-admin/js/customize-widgets$suffix.js", array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-droppable', 'wp-backbone', 'customize-controls' ), false, 1 ); $scripts->add( 'customize-preview-widgets', "/wp-includes/js/customize-preview-widgets$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); $scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu', 'wp-sanitize' ), false, 1 ); $scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 ); $scripts->add( 'wp-custom-header', "/wp-includes/js/wp-custom-header$suffix.js", array( 'wp-a11y' ), false, 1 ); $scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 ); $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'wp-backbone' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'media-models', '_wpMediaModelsL10n', array( 'settings' => array( 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), 'post' => array( 'id' => 0 ), ), ) ); $scripts->add( 'wp-embed', "/wp-includes/js/wp-embed$suffix.js" ); did_action( 'init' ) && $scripts->add_data( 'wp-embed', 'strategy', 'defer' ); /* * To enqueue media-views or media-editor, call wp_enqueue_media(). * Both rely on numerous settings, styles, and templates to operate correctly. */ $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement', 'wp-api-request', 'wp-a11y', 'clipboard' ), false, 1 ); $scripts->set_translations( 'media-views' ); $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); $scripts->set_translations( 'media-editor' ); $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 ); $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'jquery', 'media-views', 'media-audiovideo' ), false, 1 ); $scripts->add( 'wp-api', "/wp-includes/js/wp-api$suffix.js", array( 'jquery', 'backbone', 'underscore', 'wp-api-request' ), false, 1 ); if ( is_admin() ) { $scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 ); $scripts->set_translations( 'admin-tags' ); $scripts->add( 'admin-comments', "/wp-admin/js/edit-comments$suffix.js", array( 'wp-lists', 'quicktags', 'jquery-query', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'admin-comments' ); did_action( 'init' ) && $scripts->localize( 'admin-comments', 'adminCommentsSettings', array( 'hotkeys_highlight_first' => isset( $_GET['hotkeys_highlight_first'] ), 'hotkeys_highlight_last' => isset( $_GET['hotkeys_highlight_last'] ), ) ); $scripts->add( 'xfn', "/wp-admin/js/xfn$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array( 'jquery-ui-sortable', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'postbox' ); $scripts->add( 'tags-box', "/wp-admin/js/tags-box$suffix.js", array( 'jquery', 'tags-suggest' ), false, 1 ); $scripts->set_translations( 'tags-box' ); $scripts->add( 'tags-suggest', "/wp-admin/js/tags-suggest$suffix.js", array( 'common', 'jquery-ui-autocomplete', 'wp-a11y', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'tags-suggest' ); $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count', 'wp-a11y', 'wp-sanitize', 'clipboard' ), false, 1 ); $scripts->set_translations( 'post' ); $scripts->add( 'editor-expand', "/wp-admin/js/editor-expand$suffix.js", array( 'jquery', 'underscore' ), false, 1 ); $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array( 'wp-lists', 'postbox' ), false, 1 ); $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array( 'jquery', 'postbox' ), false, 1 ); $scripts->set_translations( 'comment' ); $scripts->add( 'admin-gallery', "/wp-admin/js/gallery$suffix.js", array( 'jquery-ui-sortable' ) ); $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'admin-widgets' ); $scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views', 'wp-api-request' ) ); $scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' ); $scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) ); $scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) ); $scripts->add( 'media-gallery-widget', "/wp-admin/js/widgets/media-gallery-widget$suffix.js", array( 'media-widgets' ) ); $scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo', 'wp-api-request' ) ); $scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util', 'wp-a11y' ) ); $scripts->add( 'custom-html-widgets', "/wp-admin/js/widgets/custom-html-widgets$suffix.js", array( 'jquery', 'backbone', 'wp-util', 'jquery-ui-core', 'wp-a11y' ) ); $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone', 'wp-a11y', 'customize-base' ), false, 1 ); $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'tags-suggest', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'inline-edit-post' ); $scripts->add( 'inline-edit-tax', "/wp-admin/js/inline-edit-tax$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'inline-edit-tax' ); $scripts->add( 'plugin-install', "/wp-admin/js/plugin-install$suffix.js", array( 'jquery', 'jquery-ui-core', 'thickbox' ), false, 1 ); $scripts->set_translations( 'plugin-install' ); $scripts->add( 'site-health', "/wp-admin/js/site-health$suffix.js", array( 'clipboard', 'jquery', 'wp-util', 'wp-a11y', 'wp-api-request', 'wp-url', 'wp-i18n', 'wp-hooks' ), false, 1 ); $scripts->set_translations( 'site-health' ); $scripts->add( 'privacy-tools', "/wp-admin/js/privacy-tools$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'privacy-tools' ); $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'common', 'jquery', 'wp-util', 'wp-a11y', 'wp-sanitize', 'wp-i18n' ), false, 1 ); $scripts->set_translations( 'updates' ); did_action( 'init' ) && $scripts->localize( 'updates', '_wpUpdatesSettings', array( 'ajax_nonce' => wp_installing() ? '' : wp_create_nonce( 'updates' ), ) ); $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array( 'jquery' ), '1.2' ); $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), '1.1.1', 1 ); $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); $scripts->set_translations( 'wp-color-picker' ); $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox', 'wp-util', 'wp-a11y', 'wp-date' ), false, 1 ); $scripts->set_translations( 'dashboard' ); $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); $scripts->add( 'media-grid', "/wp-includes/js/media-grid$suffix.js", array( 'media-editor' ), false, 1 ); $scripts->add( 'media', "/wp-admin/js/media$suffix.js", array( 'jquery', 'clipboard', 'wp-i18n', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'media' ); $scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array( 'jquery', 'jquery-ui-core', 'json2', 'imgareaselect', 'wp-a11y' ), false, 1 ); $scripts->set_translations( 'image-edit' ); $scripts->add( 'set-post-thumbnail', "/wp-admin/js/set-post-thumbnail$suffix.js", array( 'jquery' ), false, 1 ); $scripts->set_translations( 'set-post-thumbnail' ); /* * Navigation Menus: Adding underscore as a dependency to utilize _.debounce * see https://core.trac.wordpress.org/ticket/42321 */ $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-lists', 'postbox', 'json2', 'underscore' ) ); $scripts->set_translations( 'nav-menu' ); $scripts->add( 'custom-header', '/wp-admin/js/custom-header.js', array( 'jquery-masonry' ), false, 1 ); $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 ); $scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array( 'jquery' ), false, 1 ); $scripts->add( 'svg-painter', '/wp-admin/js/svg-painter.js', array( 'jquery' ), false, 1 ); } } /** * Assigns default styles to $styles object. * * Nothing is returned, because the $styles parameter is passed by reference. * Meaning that whatever object is passed will be updated without having to * reassign the variable that was passed back to the same value. This saves * memory. * * Adding default styles is not the only task, it also assigns the base_url * property, the default version, and text direction for the object. * * @since 2.6.0 * * @global array $editor_styles * * @param WP_Styles $styles */ function wp_default_styles( $styles ) { global $editor_styles; /* * Include an unmodified $wp_version. * * Note: wp_get_wp_version() is not used here, as this file can be included * via wp-admin/load-scripts.php or wp-admin/load-styles.php, in which case * wp-includes/functions.php is not loaded. */ require ABSPATH . WPINC . '/version.php'; if ( ! defined( 'SCRIPT_DEBUG' ) ) { /* * Note: str_contains() is not used here, as this file can be included * via wp-admin/load-scripts.php or wp-admin/load-styles.php, in which case * the polyfills from wp-includes/compat.php are not loaded. */ define( 'SCRIPT_DEBUG', false !== strpos( $wp_version, '-src' ) ); } $guessurl = site_url(); if ( ! $guessurl ) { $guessurl = wp_guess_url(); } $styles->base_url = $guessurl; $styles->content_url = defined( 'WP_CONTENT_URL' ) ? WP_CONTENT_URL : ''; $styles->default_version = get_bloginfo( 'version' ); $styles->text_direction = function_exists( 'is_rtl' ) && is_rtl() ? 'rtl' : 'ltr'; $styles->default_dirs = array( '/wp-admin/', '/wp-includes/css/' ); // Open Sans is no longer used by core, but may be relied upon by themes and plugins. $open_sans_font_url = ''; /* * translators: If there are characters in your language that are not supported * by Open Sans, translate this to 'off'. Do not translate into your own language. */ if ( 'off' !== _x( 'on', 'Open Sans font: on or off' ) ) { $subsets = 'latin,latin-ext'; /* * translators: To add an additional Open Sans character subset specific to your language, * translate this to 'greek', 'cyrillic' or 'vietnamese'. Do not translate into your own language. */ $subset = _x( 'no-subset', 'Open Sans font: add new subset (greek, cyrillic, vietnamese)' ); if ( 'cyrillic' === $subset ) { $subsets .= ',cyrillic,cyrillic-ext'; } elseif ( 'greek' === $subset ) { $subsets .= ',greek,greek-ext'; } elseif ( 'vietnamese' === $subset ) { $subsets .= ',vietnamese'; } // Hotlink Open Sans, for now. $open_sans_font_url = "https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,300,400,600&subset=$subsets&display=fallback"; } // Register a stylesheet for the selected admin color scheme. $styles->add( 'colors', true, array( 'wp-admin', 'buttons' ) ); $suffix = SCRIPT_DEBUG ? '' : '.min'; // Admin CSS. $styles->add( 'common', "/wp-admin/css/common$suffix.css" ); $styles->add( 'forms', "/wp-admin/css/forms$suffix.css" ); $styles->add( 'admin-menu', "/wp-admin/css/admin-menu$suffix.css" ); $styles->add( 'dashboard', "/wp-admin/css/dashboard$suffix.css" ); $styles->add( 'list-tables', "/wp-admin/css/list-tables$suffix.css" ); $styles->add( 'edit', "/wp-admin/css/edit$suffix.css" ); $styles->add( 'revisions', "/wp-admin/css/revisions$suffix.css" ); $styles->add( 'media', "/wp-admin/css/media$suffix.css" ); $styles->add( 'themes', "/wp-admin/css/themes$suffix.css" ); $styles->add( 'about', "/wp-admin/css/about$suffix.css" ); $styles->add( 'nav-menus', "/wp-admin/css/nav-menus$suffix.css" ); $styles->add( 'widgets', "/wp-admin/css/widgets$suffix.css", array( 'wp-pointer' ) ); $styles->add( 'site-icon', "/wp-admin/css/site-icon$suffix.css" ); $styles->add( 'l10n', "/wp-admin/css/l10n$suffix.css" ); $styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) ); $styles->add( 'site-health', "/wp-admin/css/site-health$suffix.css" ); $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n' ) ); $styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); $styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) ); $styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" ); $styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'imgareaselect' ) ); $styles->add( 'customize-widgets', "/wp-admin/css/customize-widgets$suffix.css", array( 'wp-admin', 'colors' ) ); $styles->add( 'customize-nav-menus', "/wp-admin/css/customize-nav-menus$suffix.css", array( 'wp-admin', 'colors' ) ); // Common dependencies. $styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" ); $styles->add( 'dashicons', "/wp-includes/css/dashicons$suffix.css" ); // Includes CSS. $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css", array( 'dashicons' ) ); $styles->add( 'wp-auth-check', "/wp-includes/css/wp-auth-check$suffix.css", array( 'dashicons' ) ); $styles->add( 'editor-buttons', "/wp-includes/css/editor$suffix.css", array( 'dashicons' ) ); $styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons', 'dashicons', 'wp-mediaelement' ) ); $styles->add( 'wp-pointer', "/wp-includes/css/wp-pointer$suffix.css", array( 'dashicons' ) ); $styles->add( 'customize-preview', "/wp-includes/css/customize-preview$suffix.css", array( 'dashicons' ) ); $styles->add( 'wp-embed-template-ie', "/wp-includes/css/wp-embed-template-ie$suffix.css" ); $styles->add( 'wp-empty-template-alert', "/wp-includes/css/wp-empty-template-alert$suffix.css" ); $styles->add_data( 'wp-embed-template-ie', 'conditional', 'lte IE 8' ); // External libraries and friends. $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.8' ); $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css", array( 'dashicons' ) ); $styles->add( 'mediaelement', '/wp-includes/js/mediaelement/mediaelementplayer-legacy.min.css', array(), '4.2.17' ); $styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement$suffix.css", array( 'mediaelement' ) ); $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array( 'dashicons' ) ); $styles->add( 'wp-codemirror', '/wp-includes/js/codemirror/codemirror.min.css', array(), '5.29.1-alpha-ee20357' ); // Deprecated CSS. $styles->add( 'deprecated-media', "/wp-admin/css/deprecated-media$suffix.css" ); $styles->add( 'farbtastic', "/wp-admin/css/farbtastic$suffix.css", array(), '1.3u1' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.min.css', array(), '0.9.15' ); $styles->add( 'colors-fresh', false, array( 'wp-admin', 'buttons' ) ); // Old handle. $styles->add( 'open-sans', $open_sans_font_url ); // No longer used in core as of 4.6. // Noto Serif is no longer used by core, but may be relied upon by themes and plugins. $fonts_url = ''; /* * translators: Use this to specify the proper Google Font name and variants * to load that is supported by your language. Do not translate. * Set to 'off' to disable loading. */ $font_family = _x( 'Noto Serif:400,400i,700,700i', 'Google Font Name and Variants' ); if ( 'off' !== $font_family ) { $fonts_url = 'https://fonts.googleapis.com/css?family=' . urlencode( $font_family ); } $styles->add( 'wp-editor-font', $fonts_url ); // No longer used in core as of 5.7. $block_library_theme_path = WPINC . "/css/dist/block-library/theme$suffix.css"; $styles->add( 'wp-block-library-theme', "/$block_library_theme_path" ); $styles->add_data( 'wp-block-library-theme', 'path', ABSPATH . $block_library_theme_path ); $classic_theme_styles_path = WPINC . "/css/classic-themes$suffix.css"; $styles->add( 'classic-theme-styles', "/$classic_theme_styles_path" ); $styles->add_data( 'classic-theme-styles', 'path', ABSPATH . $classic_theme_styles_path ); $styles->add( 'wp-reset-editor-styles', "/wp-includes/css/dist/block-library/reset$suffix.css", array( 'common', 'forms' ) // Make sure the reset is loaded after the default WP Admin styles. ); $styles->add( 'wp-editor-classic-layout-styles', "/wp-includes/css/dist/edit-post/classic$suffix.css", array() ); $styles->add( 'wp-block-editor-content', "/wp-includes/css/dist/block-editor/content$suffix.css", array( 'wp-components' ) ); // Only add CONTENT styles here that should be enqueued in the iframe! $wp_edit_blocks_dependencies = array( 'wp-components', /* * This needs to be added before the block library styles, * The block library styles override the "reset" styles. */ 'wp-reset-editor-styles', 'wp-block-library', 'wp-block-editor-content', ); // Only load the default layout and margin styles for themes without theme.json file. if ( ! wp_theme_has_theme_json() ) { $wp_edit_blocks_dependencies[] = 'wp-editor-classic-layout-styles'; } if ( current_theme_supports( 'wp-block-styles' ) && ( ! is_array( $editor_styles ) || count( $editor_styles ) === 0 ) ) { /* * Include opinionated block styles if the theme supports block styles and * no $editor_styles are declared, so the editor never appears broken. */ $wp_edit_blocks_dependencies[] = 'wp-block-library-theme'; } $styles->add( 'wp-edit-blocks', "/wp-includes/css/dist/block-library/editor$suffix.css", $wp_edit_blocks_dependencies ); $package_styles = array( 'block-editor' => array( 'wp-components', 'wp-preferences' ), 'block-library' => array(), 'block-directory' => array(), 'components' => array(), 'commands' => array(), 'edit-post' => array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-commands', 'wp-preferences', ), 'editor' => array( 'wp-components', 'wp-block-editor', 'wp-reusable-blocks', 'wp-patterns', 'wp-preferences', ), 'format-library' => array(), 'list-reusable-blocks' => array( 'wp-components' ), 'reusable-blocks' => array( 'wp-components' ), 'patterns' => array( 'wp-components' ), 'preferences' => array( 'wp-components' ), 'nux' => array( 'wp-components' ), 'widgets' => array( 'wp-components', ), 'edit-widgets' => array( 'wp-widgets', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-patterns', 'wp-preferences', ), 'customize-widgets' => array( 'wp-widgets', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-block-library', 'wp-patterns', 'wp-preferences', ), 'edit-site' => array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-commands', 'wp-preferences', ), ); foreach ( $package_styles as $package => $dependencies ) { $handle = 'wp-' . $package; $path = "/wp-includes/css/dist/$package/style$suffix.css"; if ( 'block-library' === $package && wp_should_load_separate_core_block_assets() ) { $path = "/wp-includes/css/dist/$package/common$suffix.css"; } $styles->add( $handle, $path, $dependencies ); $styles->add_data( $handle, 'path', ABSPATH . $path ); } // RTL CSS. $rtl_styles = array( // Admin CSS. 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'install', 'wp-color-picker', 'customize-controls', 'customize-widgets', 'customize-nav-menus', 'customize-preview', 'login', 'site-health', 'wp-empty-template-alert', // Includes CSS. 'buttons', 'admin-bar', 'wp-auth-check', 'editor-buttons', 'media-views', 'wp-pointer', 'wp-jquery-ui-dialog', // Package styles. 'wp-reset-editor-styles', 'wp-editor-classic-layout-styles', 'wp-block-library-theme', 'wp-edit-blocks', 'wp-block-editor', 'wp-block-library', 'wp-block-directory', 'wp-commands', 'wp-components', 'wp-customize-widgets', 'wp-edit-post', 'wp-edit-site', 'wp-edit-widgets', 'wp-editor', 'wp-format-library', 'wp-list-reusable-blocks', 'wp-reusable-blocks', 'wp-patterns', 'wp-nux', 'wp-widgets', // Deprecated CSS. 'deprecated-media', 'farbtastic', ); foreach ( $rtl_styles as $rtl_style ) { $styles->add_data( $rtl_style, 'rtl', 'replace' ); if ( $suffix ) { $styles->add_data( $rtl_style, 'suffix', $suffix ); } } } /** * Reorders JavaScript scripts array to place prototype before jQuery. * * @since 2.3.1 * * @param string[] $js_array JavaScript scripts array * @return string[] Reordered array, if needed. */ function wp_prototype_before_jquery( $js_array ) { $prototype = array_search( 'prototype', $js_array, true ); if ( false === $prototype ) { return $js_array; } $jquery = array_search( 'jquery', $js_array, true ); if ( false === $jquery ) { return $js_array; } if ( $prototype < $jquery ) { return $js_array; } unset( $js_array[ $prototype ] ); array_splice( $js_array, $jquery, 0, 'prototype' ); return $js_array; } /** * Loads localized data on print rather than initialization. * * These localizations require information that may not be loaded even by init. * * @since 2.5.0 * * @global array $shortcode_tags */ function wp_just_in_time_script_localization() { wp_localize_script( 'autosave', 'autosaveL10n', array( 'autosaveInterval' => AUTOSAVE_INTERVAL, 'blog_id' => get_current_blog_id(), ) ); wp_localize_script( 'mce-view', 'mceViewL10n', array( 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), ) ); wp_localize_script( 'word-count', 'wordCountL10n', array( 'type' => wp_get_word_count_type(), 'shortcodes' => ! empty( $GLOBALS['shortcode_tags'] ) ? array_keys( $GLOBALS['shortcode_tags'] ) : array(), ) ); } /** * Localizes the jQuery UI datepicker. * * @since 4.6.0 * * @link https://api.jqueryui.com/datepicker/#options * * @global WP_Locale $wp_locale WordPress date and time locale object. */ function wp_localize_jquery_ui_datepicker() { global $wp_locale; if ( ! wp_script_is( 'jquery-ui-datepicker', 'enqueued' ) ) { return; } // Convert the PHP date format into jQuery UI's format. $datepicker_date_format = str_replace( array( 'd', 'j', 'l', 'z', // Day. 'F', 'M', 'n', 'm', // Month. 'Y', 'y', // Year. ), array( 'dd', 'd', 'DD', 'o', 'MM', 'M', 'm', 'mm', 'yy', 'y', ), get_option( 'date_format' ) ); $datepicker_defaults = wp_json_encode( array( 'closeText' => __( 'Close' ), 'currentText' => __( 'Today' ), 'monthNames' => array_values( $wp_locale->month ), 'monthNamesShort' => array_values( $wp_locale->month_abbrev ), 'nextText' => __( 'Next' ), 'prevText' => __( 'Previous' ), 'dayNames' => array_values( $wp_locale->weekday ), 'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ), 'dayNamesMin' => array_values( $wp_locale->weekday_initial ), 'dateFormat' => $datepicker_date_format, 'firstDay' => absint( get_option( 'start_of_week' ) ), 'isRTL' => $wp_locale->is_rtl(), ) ); wp_add_inline_script( 'jquery-ui-datepicker', "jQuery(function(jQuery){jQuery.datepicker.setDefaults({$datepicker_defaults});});" ); } /** * Localizes community events data that needs to be passed to dashboard.js. * * @since 4.8.0 */ function wp_localize_community_events() { if ( ! wp_script_is( 'dashboard' ) ) { return; } require_once ABSPATH . 'wp-admin/includes/class-wp-community-events.php'; $user_id = get_current_user_id(); $saved_location = get_user_option( 'community-events-location', $user_id ); $saved_ip_address = isset( $saved_location['ip'] ) ? $saved_location['ip'] : false; $current_ip_address = WP_Community_Events::get_unsafe_client_ip(); /* * If the user's location is based on their IP address, then update their * location when their IP address changes. This allows them to see events * in their current city when travelling. Otherwise, they would always be * shown events in the city where they were when they first loaded the * Dashboard, which could have been months or years ago. */ if ( $saved_ip_address && $current_ip_address && $current_ip_address !== $saved_ip_address ) { $saved_location['ip'] = $current_ip_address; update_user_meta( $user_id, 'community-events-location', $saved_location ); } $events_client = new WP_Community_Events( $user_id, $saved_location ); wp_localize_script( 'dashboard', 'communityEventsData', array( 'nonce' => wp_create_nonce( 'community_events' ), 'cache' => $events_client->get_cached_events(), 'time_format' => get_option( 'time_format' ), ) ); } /** * Administration Screen CSS for changing the styles. * * If installing the 'wp-admin/' directory will be replaced with './'. * * The $_wp_admin_css_colors global manages the Administration Screens CSS * stylesheet that is loaded. The option that is set is 'admin_color' and is the * color and key for the array. The value for the color key is an object with * a 'url' parameter that has the URL path to the CSS file. * * The query from $src parameter will be appended to the URL that is given from * the $_wp_admin_css_colors array value URL. * * @since 2.6.0 * * @global array $_wp_admin_css_colors * * @param string $src Source URL. * @param string $handle Either 'colors' or 'colors-rtl'. * @return string|false URL path to CSS stylesheet for Administration Screens. */ function wp_style_loader_src( $src, $handle ) { global $_wp_admin_css_colors; if ( wp_installing() ) { return preg_replace( '#^wp-admin/#', './', $src ); } if ( 'colors' === $handle ) { $color = get_user_option( 'admin_color' ); if ( empty( $color ) || ! isset( $_wp_admin_css_colors[ $color ] ) ) { $color = 'fresh'; } $color = $_wp_admin_css_colors[ $color ]; $url = $color->url; if ( ! $url ) { return false; } $parsed = parse_url( $src ); if ( isset( $parsed['query'] ) && $parsed['query'] ) { wp_parse_str( $parsed['query'], $qv ); $url = add_query_arg( $qv, $url ); } return $url; } return $src; } /** * Prints the script queue in the HTML head on admin pages. * * Postpones the scripts that were queued for the footer. * print_footer_scripts() is called in the footer to print these scripts. * * @since 2.8.0 * * @see wp_print_scripts() * * @global bool $concatenate_scripts * * @return string[] Handles of the scripts that were printed. */ function print_head_scripts() { global $concatenate_scripts; if ( ! did_action( 'wp_print_scripts' ) ) { /** This action is documented in wp-includes/functions.wp-scripts.php */ do_action( 'wp_print_scripts' ); } $wp_scripts = wp_scripts(); script_concat_settings(); $wp_scripts->do_concat = $concatenate_scripts; $wp_scripts->do_head_items(); /** * Filters whether to print the head scripts. * * @since 2.8.0 * * @param bool $print Whether to print the head scripts. Default true. */ if ( apply_filters( 'print_head_scripts', true ) ) { _print_scripts(); } $wp_scripts->reset(); return $wp_scripts->done; } /** * Prints the scripts that were queued for the footer or too late for the HTML head. * * @since 2.8.0 * * @global WP_Scripts $wp_scripts * @global bool $concatenate_scripts * * @return string[] Handles of the scripts that were printed. */ function print_footer_scripts() { global $wp_scripts, $concatenate_scripts; if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { return array(); // No need to run if not instantiated. } script_concat_settings(); $wp_scripts->do_concat = $concatenate_scripts; $wp_scripts->do_footer_items(); /** * Filters whether to print the footer scripts. * * @since 2.8.0 * * @param bool $print Whether to print the footer scripts. Default true. */ if ( apply_filters( 'print_footer_scripts', true ) ) { _print_scripts(); } $wp_scripts->reset(); return $wp_scripts->done; } /** * Prints scripts (internal use only) * * @ignore * * @global WP_Scripts $wp_scripts * @global bool $compress_scripts */ function _print_scripts() { global $wp_scripts, $compress_scripts; $zip = $compress_scripts ? 1 : 0; if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { $zip = 'gzip'; } $concat = trim( $wp_scripts->concat, ', ' ); $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : " type='text/javascript'"; if ( $concat ) { if ( ! empty( $wp_scripts->print_code ) ) { echo "\n<script{$type_attr}>\n"; echo "/* <![CDATA[ */\n"; // Not needed in HTML 5. echo $wp_scripts->print_code; echo "/* ]]> */\n"; echo "</script>\n"; } $concat = str_split( $concat, 128 ); $concatenated = ''; foreach ( $concat as $key => $chunk ) { $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; } $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}" . $concatenated . '&ver=' . $wp_scripts->default_version; echo "<script{$type_attr} src='" . esc_attr( $src ) . "'></script>\n"; } if ( ! empty( $wp_scripts->print_html ) ) { echo $wp_scripts->print_html; } } /** * Prints the script queue in the HTML head on the front end. * * Postpones the scripts that were queued for the footer. * wp_print_footer_scripts() is called in the footer to print these scripts. * * @since 2.8.0 * * @global WP_Scripts $wp_scripts * * @return string[] Handles of the scripts that were printed. */ function wp_print_head_scripts() { global $wp_scripts; if ( ! did_action( 'wp_print_scripts' ) ) { /** This action is documented in wp-includes/functions.wp-scripts.php */ do_action( 'wp_print_scripts' ); } if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { return array(); // No need to run if nothing is queued. } return print_head_scripts(); } /** * Private, for use in *_footer_scripts hooks * * @since 3.3.0 */ function _wp_footer_scripts() { print_late_styles(); print_footer_scripts(); } /** * Hooks to print the scripts and styles in the footer. * * @since 2.8.0 */ function wp_print_footer_scripts() { /** * Fires when footer scripts are printed. * * @since 2.8.0 */ do_action( 'wp_print_footer_scripts' ); } /** * Wrapper for do_action( 'wp_enqueue_scripts' ). * * Allows plugins to queue scripts for the front end using wp_enqueue_script(). * Runs first in wp_head() where all is_home(), is_page(), etc. functions are available. * * @since 2.8.0 */ function wp_enqueue_scripts() { /** * Fires when scripts and styles are enqueued. * * @since 2.8.0 */ do_action( 'wp_enqueue_scripts' ); } /** * Prints the styles queue in the HTML head on admin pages. * * @since 2.8.0 * * @global bool $concatenate_scripts * * @return string[] Handles of the styles that were printed. */ function print_admin_styles() { global $concatenate_scripts; $wp_styles = wp_styles(); script_concat_settings(); $wp_styles->do_concat = $concatenate_scripts; $wp_styles->do_items( false ); /** * Filters whether to print the admin styles. * * @since 2.8.0 * * @param bool $print Whether to print the admin styles. Default true. */ if ( apply_filters( 'print_admin_styles', true ) ) { _print_styles(); } $wp_styles->reset(); return $wp_styles->done; } /** * Prints the styles that were queued too late for the HTML head. * * @since 3.3.0 * * @global WP_Styles $wp_styles * @global bool $concatenate_scripts * * @return array|void */ function print_late_styles() { global $wp_styles, $concatenate_scripts; if ( ! ( $wp_styles instanceof WP_Styles ) ) { return; } script_concat_settings(); $wp_styles->do_concat = $concatenate_scripts; $wp_styles->do_footer_items(); /** * Filters whether to print the styles queued too late for the HTML head. * * @since 3.3.0 * * @param bool $print Whether to print the 'late' styles. Default true. */ if ( apply_filters( 'print_late_styles', true ) ) { _print_styles(); } $wp_styles->reset(); return $wp_styles->done; } /** * Prints styles (internal use only). * * @ignore * @since 3.3.0 * * @global bool $compress_css */ function _print_styles() { global $compress_css; $wp_styles = wp_styles(); $zip = $compress_css ? 1 : 0; if ( $zip && defined( 'ENFORCE_GZIP' ) && ENFORCE_GZIP ) { $zip = 'gzip'; } $concat = trim( $wp_styles->concat, ', ' ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; if ( $concat ) { $dir = $wp_styles->text_direction; $ver = $wp_styles->default_version; $concat = str_split( $concat, 128 ); $concatenated = ''; foreach ( $concat as $key => $chunk ) { $concatenated .= "&load%5Bchunk_{$key}%5D={$chunk}"; } $href = $wp_styles->base_url . "/wp-admin/load-styles.php?c={$zip}&dir={$dir}" . $concatenated . '&ver=' . $ver; echo "<link rel='stylesheet' href='" . esc_attr( $href ) . "'{$type_attr} media='all' />\n"; if ( ! empty( $wp_styles->print_code ) ) { echo "<style{$type_attr}>\n"; echo $wp_styles->print_code; echo "\n</style>\n"; } } if ( ! empty( $wp_styles->print_html ) ) { echo $wp_styles->print_html; } } /** * Determines the concatenation and compression settings for scripts and styles. * * @since 2.8.0 * * @global bool $concatenate_scripts * @global bool $compress_scripts * @global bool $compress_css */ function script_concat_settings() { global $concatenate_scripts, $compress_scripts, $compress_css; $compressed_output = ( ini_get( 'zlib.output_compression' ) || 'ob_gzhandler' === ini_get( 'output_handler' ) ); $can_compress_scripts = ! wp_installing() && get_site_option( 'can_compress_scripts' ); if ( ! isset( $concatenate_scripts ) ) { $concatenate_scripts = defined( 'CONCATENATE_SCRIPTS' ) ? CONCATENATE_SCRIPTS : true; if ( ( ! is_admin() && ! did_action( 'login_init' ) ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ) { $concatenate_scripts = false; } } if ( ! isset( $compress_scripts ) ) { $compress_scripts = defined( 'COMPRESS_SCRIPTS' ) ? COMPRESS_SCRIPTS : true; if ( $compress_scripts && ( ! $can_compress_scripts || $compressed_output ) ) { $compress_scripts = false; } } if ( ! isset( $compress_css ) ) { $compress_css = defined( 'COMPRESS_CSS' ) ? COMPRESS_CSS : true; if ( $compress_css && ( ! $can_compress_scripts || $compressed_output ) ) { $compress_css = false; } } } /** * Handles the enqueueing of block scripts and styles that are common to both * the editor and the front-end. * * @since 5.0.0 */ function wp_common_block_scripts_and_styles() { if ( is_admin() && ! wp_should_load_block_editor_scripts_and_styles() ) { return; } wp_enqueue_style( 'wp-block-library' ); if ( current_theme_supports( 'wp-block-styles' ) && ! wp_should_load_separate_core_block_assets() ) { wp_enqueue_style( 'wp-block-library-theme' ); } /** * Fires after enqueuing block assets for both editor and front-end. * * Call `add_action` on any hook before 'wp_enqueue_scripts'. * * In the function call you supply, simply use `wp_enqueue_script` and * `wp_enqueue_style` to add your functionality to the Gutenberg editor. * * @since 5.0.0 */ do_action( 'enqueue_block_assets' ); } /** * Applies a filter to the list of style nodes that comes from WP_Theme_JSON::get_style_nodes(). * * This particular filter removes all of the blocks from the array. * * We want WP_Theme_JSON to be ignorant of the implementation details of how the CSS is being used. * This filter allows us to modify the output of WP_Theme_JSON depending on whether or not we are * loading separate assets, without making the class aware of that detail. * * @since 6.1.0 * * @param array $nodes The nodes to filter. * @return array A filtered array of style nodes. */ function wp_filter_out_block_nodes( $nodes ) { return array_filter( $nodes, static function ( $node ) { return ! in_array( 'blocks', $node['path'], true ); }, ARRAY_FILTER_USE_BOTH ); } /** * Enqueues the global styles defined via theme.json. * * @since 5.8.0 */ function wp_enqueue_global_styles() { $assets_on_demand = wp_should_load_block_assets_on_demand(); $is_block_theme = wp_is_block_theme(); $is_classic_theme = ! $is_block_theme; /* * Global styles should be printed in the head for block themes, or for classic themes when loading assets on * demand is disabled, which is the default. * The footer should only be used for classic themes when loading assets on demand is enabled. * * See https://core.trac.wordpress.org/ticket/53494 and https://core.trac.wordpress.org/ticket/61965. */ if ( ( $is_block_theme && doing_action( 'wp_footer' ) ) || ( $is_classic_theme && doing_action( 'wp_footer' ) && ! $assets_on_demand ) || ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) && $assets_on_demand ) ) { return; } /* * If loading the CSS for each block separately, then load the theme.json CSS conditionally. * This removes the CSS from the global-styles stylesheet and adds it to the inline CSS for each block. * This filter must be registered before calling wp_get_global_stylesheet(); */ add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); $stylesheet = wp_get_global_stylesheet(); if ( $is_block_theme ) { /* * Dequeue the Customizer's custom CSS * and add it before the global styles custom CSS. */ remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); // Get the custom CSS from the Customizer and add it to the global stylesheet. $custom_css = wp_get_custom_css(); $stylesheet .= $custom_css; // Add the global styles custom CSS at the end. $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); } if ( empty( $stylesheet ) ) { return; } wp_register_style( 'global-styles', false ); wp_add_inline_style( 'global-styles', $stylesheet ); wp_enqueue_style( 'global-styles' ); // Add each block as an inline css. wp_add_global_styles_for_blocks(); } /** * Checks if the editor scripts and styles for all registered block types * should be enqueued on the current screen. * * @since 5.6.0 * * @global WP_Screen $current_screen WordPress current screen object. * * @return bool Whether scripts and styles should be enqueued. */ function wp_should_load_block_editor_scripts_and_styles() { global $current_screen; $is_block_editor_screen = ( $current_screen instanceof WP_Screen ) && $current_screen->is_block_editor(); /** * Filters the flag that decides whether or not block editor scripts and styles * are going to be enqueued on the current screen. * * @since 5.6.0 * * @param bool $is_block_editor_screen Current value of the flag. */ return apply_filters( 'should_load_block_editor_scripts_and_styles', $is_block_editor_screen ); } /** * Checks whether separate styles should be loaded for core blocks. * * When this function returns true, other functions ensure that core blocks use their own separate stylesheets. * When this function returns false, all core blocks will use the single combined 'wp-block-library' stylesheet. * * As a side effect, the return value will by default result in block assets to be loaded on demand, via the * {@see wp_should_load_block_assets_on_demand()} function. This behavior can be separately altered via that function. * * This only affects front end and not the block editor screens. * * @since 5.8.0 * @see @see wp_should_load_block_assets_on_demand() * @see wp_enqueue_registered_block_scripts_and_styles() * @see register_block_style_handle() * * @return bool Whether separate core block assets will be loaded. */ function wp_should_load_separate_core_block_assets() { if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) { return false; } /** * Filters whether block styles should be loaded separately. * * Returning false loads all core block assets, regardless of whether they are rendered * in a page or not. Returning true loads core block assets only when they are rendered. * * @since 5.8.0 * * @param bool $load_separate_assets Whether separate assets will be loaded. * Default false (all block assets are loaded, even when not used). */ return apply_filters( 'should_load_separate_core_block_assets', false ); } /** * Checks whether block styles should be loaded only on-render. * * When this function returns true, other functions ensure that blocks only load their assets on-render. * When this function returns false, all block assets are loaded regardless of whether they are rendered in a page. * * The default return value depends on the result of {@see wp_should_load_separate_core_block_assets()}, which controls * whether Core block stylesheets should be loaded separately or via a combined 'wp-block-library' stylesheet. * * This only affects front end and not the block editor screens. * * @since 6.8.0 * @see wp_should_load_separate_core_block_assets() * * @return bool Whether to load block assets only when they are rendered. */ function wp_should_load_block_assets_on_demand() { if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) { return false; } /* * For backward compatibility, the default return value for this function is based on the return value of * `wp_should_load_separate_core_block_assets()`. Initially, this function used to control both of these concerns. */ $load_assets_on_demand = wp_should_load_separate_core_block_assets(); /** * Filters whether block styles should be loaded on demand. * * Returning false loads all block assets, regardless of whether they are rendered in a page or not. * Returning true loads block assets only when they are rendered. * * The default value of the filter depends on the result of {@see wp_should_load_separate_core_block_assets()}, * which controls whether Core block stylesheets should be loaded separately or via a combined 'wp-block-library' * stylesheet. * * @since 6.8.0 * * @param bool $load_assets_on_demand Whether to load block assets only when they are rendered. */ return apply_filters( 'should_load_block_assets_on_demand', $load_assets_on_demand ); } /** * Enqueues registered block scripts and styles, depending on current rendered * context (only enqueuing editor scripts while in context of the editor). * * @since 5.0.0 * * @global WP_Screen $current_screen WordPress current screen object. */ function wp_enqueue_registered_block_scripts_and_styles() { global $current_screen; if ( wp_should_load_block_assets_on_demand() ) { return; } $load_editor_scripts_and_styles = is_admin() && wp_should_load_block_editor_scripts_and_styles(); $block_registry = WP_Block_Type_Registry::get_instance(); /* * Block styles are only enqueued if they're registered. For core blocks, this is only the case if * `wp_should_load_separate_core_block_assets()` returns true. Otherwise they use the single combined * 'wp-block-library` stylesheet. See also `register_core_block_style_handles()`. * Since `wp_enqueue_style()` does not trigger warnings if the style is not registered, it is okay to not cater for * this behavior here and simply call `wp_enqueue_style()` unconditionally. */ foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) { // Front-end and editor styles. foreach ( $block_type->style_handles as $style_handle ) { wp_enqueue_style( $style_handle ); } // Front-end and editor scripts. foreach ( $block_type->script_handles as $script_handle ) { wp_enqueue_script( $script_handle ); } if ( $load_editor_scripts_and_styles ) { // Editor styles. foreach ( $block_type->editor_style_handles as $editor_style_handle ) { wp_enqueue_style( $editor_style_handle ); } // Editor scripts. foreach ( $block_type->editor_script_handles as $editor_script_handle ) { wp_enqueue_script( $editor_script_handle ); } } } } /** * Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend. * * @since 5.3.0 * * @global WP_Styles $wp_styles */ function enqueue_block_styles_assets() { global $wp_styles; $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); foreach ( $block_styles as $block_name => $styles ) { foreach ( $styles as $style_properties ) { if ( isset( $style_properties['style_handle'] ) ) { // If the site loads block styles on demand, enqueue the stylesheet on render. if ( wp_should_load_block_assets_on_demand() ) { add_filter( 'render_block', static function ( $html, $block ) use ( $block_name, $style_properties ) { if ( $block['blockName'] === $block_name ) { wp_enqueue_style( $style_properties['style_handle'] ); } return $html; }, 10, 2 ); } else { wp_enqueue_style( $style_properties['style_handle'] ); } } if ( isset( $style_properties['inline_style'] ) ) { // Default to "wp-block-library". $handle = 'wp-block-library'; // If the site loads block styles on demand, check if the block has a stylesheet registered. if ( wp_should_load_block_assets_on_demand() ) { $block_stylesheet_handle = generate_block_asset_handle( $block_name, 'style' ); if ( isset( $wp_styles->registered[ $block_stylesheet_handle ] ) ) { $handle = $block_stylesheet_handle; } } // Add inline styles to the calculated handle. wp_add_inline_style( $handle, $style_properties['inline_style'] ); } } } } /** * Function responsible for enqueuing the assets required for block styles functionality on the editor. * * @since 5.3.0 */ function enqueue_editor_block_styles_assets() { $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered(); $register_script_lines = array( '( function() {' ); foreach ( $block_styles as $block_name => $styles ) { foreach ( $styles as $style_properties ) { $block_style = array( 'name' => $style_properties['name'], 'label' => $style_properties['label'], ); if ( isset( $style_properties['is_default'] ) ) { $block_style['isDefault'] = $style_properties['is_default']; } $register_script_lines[] = sprintf( ' wp.blocks.registerBlockStyle( \'%s\', %s );', $block_name, wp_json_encode( $block_style ) ); } } $register_script_lines[] = '} )();'; $inline_script = implode( "\n", $register_script_lines ); wp_register_script( 'wp-block-styles', false, array( 'wp-blocks' ), true, array( 'in_footer' => true ) ); wp_add_inline_script( 'wp-block-styles', $inline_script ); wp_enqueue_script( 'wp-block-styles' ); } /** * Enqueues the assets required for the block directory within the block editor. * * @since 5.5.0 */ function wp_enqueue_editor_block_directory_assets() { wp_enqueue_script( 'wp-block-directory' ); wp_enqueue_style( 'wp-block-directory' ); } /** * Enqueues the assets required for the format library within the block editor. * * @since 5.8.0 */ function wp_enqueue_editor_format_library_assets() { wp_enqueue_script( 'wp-format-library' ); wp_enqueue_style( 'wp-format-library' ); } /** * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag. * * Automatically injects type attribute if needed. * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}. * * @since 5.7.0 * * @param array $attributes Key-value pairs representing `<script>` tag attributes. * @return string String made of sanitized `<script>` tag attributes. */ function wp_sanitize_script_attributes( $attributes ) { $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' ); $attributes_string = ''; /* * If HTML5 script tag is supported, only the attribute name is added * to $attributes_string for entries with a boolean value, and that are true. */ foreach ( $attributes as $attribute_name => $attribute_value ) { if ( is_bool( $attribute_value ) ) { if ( $attribute_value ) { $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_name ) ) : ' ' . esc_attr( $attribute_name ); } } else { $attributes_string .= sprintf( ' %1$s="%2$s"', esc_attr( $attribute_name ), esc_attr( $attribute_value ) ); } } return $attributes_string; } /** * Formats `<script>` loader tags. * * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. * Automatically injects type attribute if needed. * * @since 5.7.0 * * @param array $attributes Key-value pairs representing `<script>` tag attributes. * @return string String containing `<script>` opening and closing tags. */ function wp_get_script_tag( $attributes ) { if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { // Keep the type attribute as the first for legacy reasons (it has always been this way in core). $attributes = array_merge( array( 'type' => 'text/javascript' ), $attributes ); } /** * Filters attributes to be added to a script tag. * * @since 5.7.0 * * @param array $attributes Key-value pairs representing `<script>` tag attributes. * Only the attribute name is added to the `<script>` tag for * entries with a boolean value, and that are true. */ $attributes = apply_filters( 'wp_script_attributes', $attributes ); return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) ); } /** * Prints formatted `<script>` loader tag. * * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. * Automatically injects type attribute if needed. * * @since 5.7.0 * * @param array $attributes Key-value pairs representing `<script>` tag attributes. */ function wp_print_script_tag( $attributes ) { echo wp_get_script_tag( $attributes ); } /** * Constructs an inline script tag. * * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. * Automatically injects type attribute if needed. * * @since 5.7.0 * * @param string $data Data for script tag: JavaScript, importmap, speculationrules, etc. * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. * @return string String containing inline JavaScript code wrapped around `<script>` tag. */ function wp_get_inline_script_tag( $data, $attributes = array() ) { $is_html5 = current_theme_supports( 'html5', 'script' ) || is_admin(); if ( ! isset( $attributes['type'] ) && ! $is_html5 ) { // Keep the type attribute as the first for legacy reasons (it has always been this way in core). $attributes = array_merge( array( 'type' => 'text/javascript' ), $attributes ); } /* * XHTML extracts the contents of the SCRIPT element and then the XML parser * decodes character references and other syntax elements. This can lead to * misinterpretation of the script contents or invalid XHTML documents. * * Wrapping the contents in a CDATA section instructs the XML parser not to * transform the contents of the SCRIPT element before passing them to the * JavaScript engine. * * Example: * * <script>console.log('…');</script> * * In an HTML document this would print "…" to the console, * but in an XHTML document it would print "…" to the console. * * <script>console.log('An image is <img> in HTML');</script> * * In an HTML document this would print "An image is <img> in HTML", * but it's an invalid XHTML document because it interprets the `<img>` * as an empty tag missing its closing `/`. * * @see https://www.w3.org/TR/xhtml1/#h-4.8 */ if ( ! $is_html5 && ( ! isset( $attributes['type'] ) || 'module' === $attributes['type'] || str_contains( $attributes['type'], 'javascript' ) || str_contains( $attributes['type'], 'ecmascript' ) || str_contains( $attributes['type'], 'jscript' ) || str_contains( $attributes['type'], 'livescript' ) ) ) { /* * If the string `]]>` exists within the JavaScript it would break * out of any wrapping CDATA section added here, so to start, it's * necessary to escape that sequence which requires splitting the * content into two CDATA sections wherever it's found. * * Note: it's only necessary to escape the closing `]]>` because * an additional `<![CDATA[` leaves the contents unchanged. */ $data = str_replace( ']]>', ']]]]><![CDATA[>', $data ); // Wrap the entire escaped script inside a CDATA section. $data = sprintf( "/* <![CDATA[ */\n%s\n/* ]]> */", $data ); } $data = "\n" . trim( $data, "\n\r " ) . "\n"; /** * Filters attributes to be added to a script tag. * * @since 5.7.0 * * @param array $attributes Key-value pairs representing `<script>` tag attributes. * Only the attribute name is added to the `<script>` tag for * entries with a boolean value, and that are true. * @param string $data Inline data. */ $attributes = apply_filters( 'wp_inline_script_attributes', $attributes, $data ); return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $data ); } /** * Prints an inline script tag. * * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter. * Automatically injects type attribute if needed. * * @since 5.7.0 * * @param string $data Data for script tag: JavaScript, importmap, speculationrules, etc. * @param array $attributes Optional. Key-value pairs representing `<script>` tag attributes. */ function wp_print_inline_script_tag( $data, $attributes = array() ) { echo wp_get_inline_script_tag( $data, $attributes ); } /** * Allows small styles to be inlined. * * This improves performance and sustainability, and is opt-in. Stylesheets can opt in * by adding `path` data using `wp_style_add_data`, and defining the file's absolute path: * * wp_style_add_data( $style_handle, 'path', $file_path ); * * @since 5.8.0 * * @global WP_Styles $wp_styles */ function wp_maybe_inline_styles() { global $wp_styles; $total_inline_limit = 20000; /** * The maximum size of inlined styles in bytes. * * @since 5.8.0 * * @param int $total_inline_limit The file-size threshold, in bytes. Default 20000. */ $total_inline_limit = apply_filters( 'styles_inline_size_limit', $total_inline_limit ); $styles = array(); // Build an array of styles that have a path defined. foreach ( $wp_styles->queue as $handle ) { if ( ! isset( $wp_styles->registered[ $handle ] ) ) { continue; } $src = $wp_styles->registered[ $handle ]->src; $path = $wp_styles->get_data( $handle, 'path' ); if ( $path && $src ) { $size = wp_filesize( $path ); if ( ! $size ) { continue; } $styles[] = array( 'handle' => $handle, 'src' => $src, 'path' => $path, 'size' => $size, ); } } if ( ! empty( $styles ) ) { // Reorder styles array based on size. usort( $styles, static function ( $a, $b ) { return ( $a['size'] <= $b['size'] ) ? -1 : 1; } ); /* * The total inlined size. * * On each iteration of the loop, if a style gets added inline the value of this var increases * to reflect the total size of inlined styles. */ $total_inline_size = 0; // Loop styles. foreach ( $styles as $style ) { // Size check. Since styles are ordered by size, we can break the loop. if ( $total_inline_size + $style['size'] > $total_inline_limit ) { break; } // Get the styles if we don't already have them. $style['css'] = file_get_contents( $style['path'] ); /* * Check if the style contains relative URLs that need to be modified. * URLs relative to the stylesheet's path should be converted to relative to the site's root. */ $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] ); // Set `src` to `false` and add styles inline. $wp_styles->registered[ $style['handle'] ]->src = false; if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) { $wp_styles->registered[ $style['handle'] ]->extra['after'] = array(); } array_unshift( $wp_styles->registered[ $style['handle'] ]->extra['after'], $style['css'] ); // Add the styles size to the $total_inline_size var. $total_inline_size += (int) $style['size']; } } } /** * Makes URLs relative to the WordPress installation. * * @since 5.9.0 * @access private * * @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 ) { return preg_replace_callback( '#(url\s*\(\s*[\'"]?\s*)([^\'"\)]+)#', static function ( $matches ) use ( $stylesheet_url ) { list( , $prefix, $url ) = $matches; // Short-circuit if the URL does not require normalization. if ( str_starts_with( $url, 'http:' ) || str_starts_with( $url, 'https:' ) || str_starts_with( $url, '/' ) || str_starts_with( $url, '#' ) || str_starts_with( $url, 'data:' ) ) { return $matches[0]; } // Build the absolute URL. $absolute_url = dirname( $stylesheet_url ) . '/' . $url; $absolute_url = str_replace( '/./', '/', $absolute_url ); // Convert to URL related to the site root. $url = wp_make_link_relative( $absolute_url ); return $prefix . $url; }, $css ); } /** * Function that enqueues the CSS Custom Properties coming from theme.json. * * @since 5.9.0 */ function wp_enqueue_global_styles_css_custom_properties() { wp_register_style( 'global-styles-css-custom-properties', false ); wp_add_inline_style( 'global-styles-css-custom-properties', wp_get_global_stylesheet( array( 'variables' ) ) ); wp_enqueue_style( 'global-styles-css-custom-properties' ); } /** * Hooks inline styles in the proper place, depending on the active theme. * * @since 5.9.1 * @since 6.1.0 Added the `$priority` parameter. * * For block themes, styles are loaded in the head. * For classic ones, styles are loaded in the body because the wp_head action happens before render_block. * * @link https://core.trac.wordpress.org/ticket/53494. * * @param string $style String containing the CSS styles to be added. * @param int $priority To set the priority for the add_action. */ function wp_enqueue_block_support_styles( $style, $priority = 10 ) { $action_hook_name = 'wp_footer'; if ( wp_is_block_theme() ) { $action_hook_name = 'wp_head'; } add_action( $action_hook_name, static function () use ( $style ) { echo "<style>$style</style>\n"; }, $priority ); } /** * Fetches, processes and compiles stored core styles, then combines and renders them to the page. * Styles are stored via the style engine API. * * @link https://developer.wordpress.org/block-editor/reference-guides/packages/packages-style-engine/ * * @since 6.1.0 * * @param array $options { * Optional. An array of options to pass to wp_style_engine_get_stylesheet_from_context(). * Default empty array. * * @type bool $optimize Whether to optimize the CSS output, e.g., combine rules. * Default false. * @type bool $prettify Whether to add new lines and indents to output. * Default to whether the `SCRIPT_DEBUG` constant is defined. * } */ function wp_enqueue_stored_styles( $options = array() ) { $is_block_theme = wp_is_block_theme(); $is_classic_theme = ! $is_block_theme; /* * For block themes, this function prints stored styles in the header. * For classic themes, in the footer. */ if ( ( $is_block_theme && doing_action( 'wp_footer' ) ) || ( $is_classic_theme && doing_action( 'wp_enqueue_scripts' ) ) ) { return; } $core_styles_keys = array( 'block-supports' ); $compiled_core_stylesheet = ''; $style_tag_id = 'core'; // Adds comment if code is prettified to identify core styles sections in debugging. $should_prettify = isset( $options['prettify'] ) ? true === $options['prettify'] : defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG; foreach ( $core_styles_keys as $style_key ) { if ( $should_prettify ) { $compiled_core_stylesheet .= "/**\n * Core styles: $style_key\n */\n"; } // Chains core store ids to signify what the styles contain. $style_tag_id .= '-' . $style_key; $compiled_core_stylesheet .= wp_style_engine_get_stylesheet_from_context( $style_key, $options ); } // Combines Core styles. if ( ! empty( $compiled_core_stylesheet ) ) { wp_register_style( $style_tag_id, false ); wp_add_inline_style( $style_tag_id, $compiled_core_stylesheet ); wp_enqueue_style( $style_tag_id ); } // Prints out any other stores registered by themes or otherwise. $additional_stores = WP_Style_Engine_CSS_Rules_Store::get_stores(); foreach ( array_keys( $additional_stores ) as $store_name ) { if ( in_array( $store_name, $core_styles_keys, true ) ) { continue; } $styles = wp_style_engine_get_stylesheet_from_context( $store_name, $options ); if ( ! empty( $styles ) ) { $key = "wp-style-engine-$store_name"; wp_register_style( $key, false ); wp_add_inline_style( $key, $styles ); wp_enqueue_style( $key ); } } } /** * Enqueues a stylesheet for a specific block. * * If the theme has opted-in to load block styles on demand, * then the stylesheet will be enqueued on-render, * otherwise when the block inits. * * @since 5.9.0 * * @param string $block_name The block-name, including namespace. * @param array $args { * An array of arguments. See wp_register_style() for full information about each argument. * * @type string $handle The handle for the stylesheet. * @type string|false $src The source URL of the stylesheet. * @type string[] $deps Array of registered stylesheet handles this stylesheet depends on. * @type string|bool|null $ver Stylesheet version number. * @type string $media The media for which this stylesheet has been defined. * @type string|null $path Absolute path to the stylesheet, so that it can potentially be inlined. * } */ function wp_enqueue_block_style( $block_name, $args ) { $args = wp_parse_args( $args, array( 'handle' => '', 'src' => '', 'deps' => array(), 'ver' => false, 'media' => 'all', ) ); /** * Callback function to register and enqueue styles. * * @param string $content When the callback is used for the render_block filter, * the content needs to be returned so the function parameter * is to ensure the content exists. * @return string Block content. */ $callback = static function ( $content ) use ( $args ) { // Register the stylesheet. if ( ! empty( $args['src'] ) ) { wp_register_style( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['media'] ); } // Add `path` data if provided. if ( isset( $args['path'] ) ) { wp_style_add_data( $args['handle'], 'path', $args['path'] ); // Get the RTL file path. $rtl_file_path = str_replace( '.css', '-rtl.css', $args['path'] ); // Add RTL stylesheet. if ( file_exists( $rtl_file_path ) ) { wp_style_add_data( $args['handle'], 'rtl', 'replace' ); if ( is_rtl() ) { wp_style_add_data( $args['handle'], 'path', $rtl_file_path ); } } } // Enqueue the stylesheet. wp_enqueue_style( $args['handle'] ); return $content; }; $hook = did_action( 'wp_enqueue_scripts' ) ? 'wp_footer' : 'wp_enqueue_scripts'; if ( wp_should_load_block_assets_on_demand() ) { /** * Callback function to register and enqueue styles. * * @param string $content The block content. * @param array $block The full block, including name and attributes. * @return string Block content. */ $callback_separate = static function ( $content, $block ) use ( $block_name, $callback ) { if ( ! empty( $block['blockName'] ) && $block_name === $block['blockName'] ) { return $callback( $content ); } return $content; }; /* * The filter's callback here is an anonymous function because * using a named function in this case is not possible. * * The function cannot be unhooked, however, users are still able * to dequeue the stylesheets registered/enqueued by the callback * which is why in this case, using an anonymous function * was deemed acceptable. */ add_filter( 'render_block', $callback_separate, 10, 2 ); return; } /* * The filter's callback here is an anonymous function because * using a named function in this case is not possible. * * The function cannot be unhooked, however, users are still able * to dequeue the stylesheets registered/enqueued by the callback * which is why in this case, using an anonymous function * was deemed acceptable. */ add_filter( $hook, $callback ); // Enqueue assets in the editor. add_action( 'enqueue_block_assets', $callback ); } /** * Loads classic theme styles on classic themes in the frontend. * * This is used for backwards compatibility for Button and File blocks specifically. * * @since 6.1.0 * @since 6.2.0 Added File block styles. * @since 6.8.0 Moved stylesheet registration outside of this function. */ function wp_enqueue_classic_theme_styles() { if ( ! wp_theme_has_theme_json() ) { wp_enqueue_style( 'classic-theme-styles' ); } } /** * Removes leading and trailing _empty_ script tags. * * This is a helper meant to be used for literal script tag construction * within `wp_get_inline_script_tag()` or `wp_print_inline_script_tag()`. * It removes the literal values of "<script>" and "</script>" from * around an inline script after trimming whitespace. Typically this * is used in conjunction with output buffering, where `ob_get_clean()` * is passed as the `$contents` argument. * * Example: * * // Strips exact literal empty SCRIPT tags. * $js = '<script>sayHello();</script>; * 'sayHello();' === wp_remove_surrounding_empty_script_tags( $js ); * * // Otherwise if anything is different it warns in the JS console. * $js = '<script type="text/javascript">console.log( "hi" );</script>'; * 'console.error( ... )' === wp_remove_surrounding_empty_script_tags( $js ); * * @since 6.4.0 * @access private * * @see wp_print_inline_script_tag() * @see wp_get_inline_script_tag() * * @param string $contents Script body with manually created SCRIPT tag literals. * @return string Script body without surrounding script tag literals, or * original contents if both exact literals aren't present. */ function wp_remove_surrounding_empty_script_tags( $contents ) { $contents = trim( $contents ); $opener = '<SCRIPT>'; $closer = '</SCRIPT>'; if ( strlen( $contents ) > strlen( $opener ) + strlen( $closer ) && strtoupper( substr( $contents, 0, strlen( $opener ) ) ) === $opener && strtoupper( substr( $contents, -strlen( $closer ) ) ) === $closer ) { return substr( $contents, strlen( $opener ), -strlen( $closer ) ); } else { $error_message = __( 'Expected string to start with script tag (without attributes) and end with script tag, with optional whitespace.' ); _doing_it_wrong( __FUNCTION__, $error_message, '6.4' ); return sprintf( 'console.error(%s)', wp_json_encode( sprintf( /* translators: %s: wp_remove_surrounding_empty_script_tags() */ __( 'Function %s used incorrectly in PHP.' ), 'wp_remove_surrounding_empty_script_tags()' ) . ' ' . $error_message ) ); } } <?php /** * Deprecated. Use rss.php instead. * * @package WordPress * @deprecated 2.1.0 */ if ( ! defined( 'ABSPATH' ) ) { exit(); } _deprecated_file( basename( __FILE__ ), '2.1.0', WPINC . '/rss.php' ); require_once ABSPATH . WPINC . '/rss.php'; <?php /** * Theme, template, and stylesheet functions. * * @package WordPress * @subpackage Theme */ /** * Returns an array of WP_Theme objects based on the arguments. * * Despite advances over get_themes(), this function is quite expensive, and grows * linearly with additional themes. Stick to wp_get_theme() if possible. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param array $args { * Optional. The search arguments. * * @type mixed $errors True to return themes with errors, false to return * themes without errors, null to return all themes. * Default false. * @type mixed $allowed (Multisite) True to return only allowed themes for a site. * False to return only disallowed themes for a site. * 'site' to return only site-allowed themes. * 'network' to return only network-allowed themes. * Null to return all themes. Default null. * @type int $blog_id (Multisite) The blog ID used to calculate which themes * are allowed. Default 0, synonymous for the current blog. * } * @return WP_Theme[] Array of WP_Theme objects. */ function wp_get_themes( $args = array() ) { global $wp_theme_directories; $defaults = array( 'errors' => false, 'allowed' => null, 'blog_id' => 0, ); $args = wp_parse_args( $args, $defaults ); $theme_directories = search_theme_directories(); if ( is_array( $wp_theme_directories ) && count( $wp_theme_directories ) > 1 ) { /* * Make sure the active theme wins out, in case search_theme_directories() picks the wrong * one in the case of a conflict. (Normally, last registered theme root wins.) */ $current_theme = get_stylesheet(); if ( isset( $theme_directories[ $current_theme ] ) ) { $root_of_current_theme = get_raw_theme_root( $current_theme ); if ( ! in_array( $root_of_current_theme, $wp_theme_directories, true ) ) { $root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme; } $theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme; } } if ( empty( $theme_directories ) ) { return array(); } if ( is_multisite() && null !== $args['allowed'] ) { $allowed = $args['allowed']; if ( 'network' === $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_network() ); } elseif ( 'site' === $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed_on_site( $args['blog_id'] ) ); } elseif ( $allowed ) { $theme_directories = array_intersect_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) ); } else { $theme_directories = array_diff_key( $theme_directories, WP_Theme::get_allowed( $args['blog_id'] ) ); } } $themes = array(); static $_themes = array(); foreach ( $theme_directories as $theme => $theme_root ) { if ( isset( $_themes[ $theme_root['theme_root'] . '/' . $theme ] ) ) { $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ]; } else { $themes[ $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] ); $_themes[ $theme_root['theme_root'] . '/' . $theme ] = $themes[ $theme ]; } } if ( null !== $args['errors'] ) { foreach ( $themes as $theme => $wp_theme ) { if ( (bool) $wp_theme->errors() !== $args['errors'] ) { unset( $themes[ $theme ] ); } } } return $themes; } /** * Gets a WP_Theme object for a theme. * * @since 3.4.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet Optional. Directory name for the theme. Defaults to active theme. * @param string $theme_root Optional. Absolute path of the theme root to look in. * If not specified, get_raw_theme_root() is used to calculate * the theme root for the $stylesheet provided (or active theme). * @return WP_Theme Theme object. Be sure to check the object's exists() method * if you need to confirm the theme's existence. */ function wp_get_theme( $stylesheet = '', $theme_root = '' ) { global $wp_theme_directories; if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } if ( empty( $theme_root ) ) { $theme_root = get_raw_theme_root( $stylesheet ); if ( false === $theme_root ) { $theme_root = WP_CONTENT_DIR . '/themes'; } elseif ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { $theme_root = WP_CONTENT_DIR . $theme_root; } } return new WP_Theme( $stylesheet, $theme_root ); } /** * Clears the cache held by get_theme_roots() and WP_Theme. * * @since 3.5.0 * @param bool $clear_update_cache Whether to clear the theme updates cache. */ function wp_clean_themes_cache( $clear_update_cache = true ) { if ( $clear_update_cache ) { delete_site_transient( 'update_themes' ); } search_theme_directories( true ); foreach ( wp_get_themes( array( 'errors' => null ) ) as $theme ) { $theme->cache_delete(); } } /** * Whether a child theme is in use. * * @since 3.0.0 * @since 6.5.0 Makes use of global template variables. * * @global string $wp_stylesheet_path Path to current theme's stylesheet directory. * @global string $wp_template_path Path to current theme's template directory. * * @return bool True if a child theme is in use, false otherwise. */ function is_child_theme() { global $wp_stylesheet_path, $wp_template_path; return $wp_stylesheet_path !== $wp_template_path; } /** * Retrieves name of the current stylesheet. * * The theme name that is currently set as the front end theme. * * For all intents and purposes, the template name and the stylesheet name * are going to be the same for most cases. * * @since 1.5.0 * * @return string Stylesheet name. */ function get_stylesheet() { /** * Filters the name of current stylesheet. * * @since 1.5.0 * * @param string $stylesheet Name of the current stylesheet. */ return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); } /** * Retrieves stylesheet directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.2 Memoization removed. * * @return string Path to active theme's stylesheet directory. */ function get_stylesheet_directory() { $stylesheet = get_stylesheet(); $theme_root = get_theme_root( $stylesheet ); $stylesheet_dir = "$theme_root/$stylesheet"; /** * Filters the stylesheet directory path for the active theme. * * @since 1.5.0 * * @param string $stylesheet_dir Absolute path to the active theme. * @param string $stylesheet Directory name of the active theme. * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); } /** * Retrieves stylesheet directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's stylesheet directory. */ function get_stylesheet_directory_uri() { $stylesheet = str_replace( '%2F', '/', rawurlencode( get_stylesheet() ) ); $theme_root_uri = get_theme_root_uri( $stylesheet ); $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; /** * Filters the stylesheet directory URI. * * @since 1.5.0 * * @param string $stylesheet_dir_uri Stylesheet directory URI. * @param string $stylesheet Name of the activated theme's directory. * @param string $theme_root_uri Themes root URI. */ return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); } /** * Retrieves stylesheet URI for the active theme. * * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path. * See get_stylesheet_directory_uri(). * * @since 1.5.0 * * @return string URI to active theme's stylesheet. */ function get_stylesheet_uri() { $stylesheet_dir_uri = get_stylesheet_directory_uri(); $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; /** * Filters the URI of the active theme stylesheet. * * @since 1.5.0 * * @param string $stylesheet_uri Stylesheet URI for the active theme/child theme. * @param string $stylesheet_dir_uri Stylesheet directory URI for the active theme/child theme. */ return apply_filters( 'stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves the localized stylesheet URI. * * The stylesheet directory for the localized stylesheet files are located, by * default, in the base theme directory. The name of the locale file will be the * locale followed by '.css'. If that does not exist, then the text direction * stylesheet will be checked for existence, for example 'ltr.css'. * * The theme may change the location of the stylesheet directory by either using * the {@see 'stylesheet_directory_uri'} or {@see 'locale_stylesheet_uri'} filters. * * If you want to change the location of the stylesheet files for the entire * WordPress workflow, then change the former. If you just have the locale in a * separate folder, then change the latter. * * @since 2.1.0 * * @global WP_Locale $wp_locale WordPress date and time locale object. * * @return string URI to active theme's localized stylesheet. */ function get_locale_stylesheet_uri() { global $wp_locale; $stylesheet_dir_uri = get_stylesheet_directory_uri(); $dir = get_stylesheet_directory(); $locale = get_locale(); if ( file_exists( "$dir/$locale.css" ) ) { $stylesheet_uri = "$stylesheet_dir_uri/$locale.css"; } elseif ( ! empty( $wp_locale->text_direction ) && file_exists( "$dir/{$wp_locale->text_direction}.css" ) ) { $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css"; } else { $stylesheet_uri = ''; } /** * Filters the localized stylesheet URI. * * @since 2.1.0 * * @param string $stylesheet_uri Localized stylesheet URI. * @param string $stylesheet_dir_uri Stylesheet directory URI. */ return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); } /** * Retrieves name of the active theme. * * @since 1.5.0 * * @return string Template name. */ function get_template() { /** * Filters the name of the active theme. * * @since 1.5.0 * * @param string $template active theme's directory name. */ return apply_filters( 'template', get_option( 'template' ) ); } /** * Retrieves template directory path for the active theme. * * @since 1.5.0 * @since 6.4.0 Memoizes filter execution so that it only runs once for the current theme. * @since 6.4.1 Memoization removed. * * @return string Path to active theme's template directory. */ function get_template_directory() { $template = get_template(); $theme_root = get_theme_root( $template ); $template_dir = "$theme_root/$template"; /** * Filters the active theme directory path. * * @since 1.5.0 * * @param string $template_dir The path of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root Absolute path to the themes directory. */ return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); } /** * Retrieves template directory URI for the active theme. * * @since 1.5.0 * * @return string URI to active theme's template directory. */ function get_template_directory_uri() { $template = str_replace( '%2F', '/', rawurlencode( get_template() ) ); $theme_root_uri = get_theme_root_uri( $template ); $template_dir_uri = "$theme_root_uri/$template"; /** * Filters the active theme directory URI. * * @since 1.5.0 * * @param string $template_dir_uri The URI of the active theme directory. * @param string $template Directory name of the active theme. * @param string $theme_root_uri The themes root URI. */ return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); } /** * Retrieves theme roots. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @return array|string An array of theme roots keyed by template/stylesheet * or a single theme root if all themes have the same root. */ function get_theme_roots() { global $wp_theme_directories; if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { return '/themes'; } $theme_roots = get_site_transient( 'theme_roots' ); if ( false === $theme_roots ) { search_theme_directories( true ); // Regenerate the transient. $theme_roots = get_site_transient( 'theme_roots' ); } return $theme_roots; } /** * Registers a directory that contains themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param string $directory Either the full filesystem path to a theme folder * or a folder within WP_CONTENT_DIR. * @return bool True if successfully registered a directory that contains themes, * false if the directory does not exist. */ function register_theme_directory( $directory ) { global $wp_theme_directories; if ( ! file_exists( $directory ) ) { // Try prepending as the theme directory could be relative to the content directory. $directory = WP_CONTENT_DIR . '/' . $directory; // If this directory does not exist, return and do not register. if ( ! file_exists( $directory ) ) { return false; } } if ( ! is_array( $wp_theme_directories ) ) { $wp_theme_directories = array(); } $untrailed = untrailingslashit( $directory ); if ( ! empty( $untrailed ) && ! in_array( $untrailed, $wp_theme_directories, true ) ) { $wp_theme_directories[] = $untrailed; } return true; } /** * Searches all registered theme directories for complete and valid themes. * * @since 2.9.0 * * @global string[] $wp_theme_directories * * @param bool $force Optional. Whether to force a new directory scan. Default false. * @return array|false Valid themes found on success, false on failure. */ function search_theme_directories( $force = false ) { global $wp_theme_directories; static $found_themes = null; if ( empty( $wp_theme_directories ) ) { return false; } if ( ! $force && isset( $found_themes ) ) { return $found_themes; } $found_themes = array(); $wp_theme_directories = (array) $wp_theme_directories; $relative_theme_roots = array(); /* * Set up maybe-relative, maybe-absolute array of theme directories. * We always want to return absolute, but we need to cache relative * to use in get_theme_root(). */ foreach ( $wp_theme_directories as $theme_root ) { if ( str_starts_with( $theme_root, WP_CONTENT_DIR ) ) { $relative_theme_roots[ str_replace( WP_CONTENT_DIR, '', $theme_root ) ] = $theme_root; } else { $relative_theme_roots[ $theme_root ] = $theme_root; } } /** * Filters whether to get the cache of the registered theme directories. * * @since 3.4.0 * * @param bool $cache_expiration Whether to get the cache of the theme directories. Default false. * @param string $context The class or function name calling the filter. */ $cache_expiration = apply_filters( 'wp_cache_themes_persistently', false, 'search_theme_directories' ); if ( $cache_expiration ) { $cached_roots = get_site_transient( 'theme_roots' ); if ( is_array( $cached_roots ) ) { foreach ( $cached_roots as $theme_dir => $theme_root ) { // A cached theme root is no longer around, so skip it. if ( ! isset( $relative_theme_roots[ $theme_root ] ) ) { continue; } $found_themes[ $theme_dir ] = array( 'theme_file' => $theme_dir . '/style.css', 'theme_root' => $relative_theme_roots[ $theme_root ], // Convert relative to absolute. ); } return $found_themes; } if ( ! is_int( $cache_expiration ) ) { $cache_expiration = 30 * MINUTE_IN_SECONDS; } } else { $cache_expiration = 30 * MINUTE_IN_SECONDS; } /* Loop the registered theme directories and extract all themes */ foreach ( $wp_theme_directories as $theme_root ) { // Start with directories in the root of the active theme directory. $dirs = @ scandir( $theme_root ); if ( ! $dirs ) { wp_trigger_error( __FUNCTION__, "$theme_root is not readable" ); continue; } foreach ( $dirs as $dir ) { if ( ! is_dir( $theme_root . '/' . $dir ) || '.' === $dir[0] || 'CVS' === $dir ) { continue; } if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { /* * wp-content/themes/a-single-theme * wp-content/themes is $theme_root, a-single-theme is $dir. */ $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } else { $found_theme = false; /* * wp-content/themes/a-folder-of-themes/* * wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs. */ $sub_dirs = @ scandir( $theme_root . '/' . $dir ); if ( ! $sub_dirs ) { wp_trigger_error( __FUNCTION__, "$theme_root/$dir is not readable" ); continue; } foreach ( $sub_dirs as $sub_dir ) { if ( ! is_dir( $theme_root . '/' . $dir . '/' . $sub_dir ) || '.' === $dir[0] || 'CVS' === $dir ) { continue; } if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) { continue; } $found_themes[ $dir . '/' . $sub_dir ] = array( 'theme_file' => $dir . '/' . $sub_dir . '/style.css', 'theme_root' => $theme_root, ); $found_theme = true; } /* * Never mind the above, it's just a theme missing a style.css. * Return it; WP_Theme will catch the error. */ if ( ! $found_theme ) { $found_themes[ $dir ] = array( 'theme_file' => $dir . '/style.css', 'theme_root' => $theme_root, ); } } } } asort( $found_themes ); $theme_roots = array(); $relative_theme_roots = array_flip( $relative_theme_roots ); foreach ( $found_themes as $theme_dir => $theme_data ) { $theme_roots[ $theme_dir ] = $relative_theme_roots[ $theme_data['theme_root'] ]; // Convert absolute to relative. } if ( get_site_transient( 'theme_roots' ) !== $theme_roots ) { set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); } return $found_themes; } /** * Retrieves path to themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @return string Themes directory path. */ function get_theme_root( $stylesheet_or_template = '' ) { global $wp_theme_directories; $theme_root = ''; if ( $stylesheet_or_template ) { $theme_root = get_raw_theme_root( $stylesheet_or_template ); if ( $theme_root ) { /* * Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. * This gives relative theme roots the benefit of the doubt when things go haywire. */ if ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { $theme_root = WP_CONTENT_DIR . $theme_root; } } } if ( ! $theme_root ) { $theme_root = WP_CONTENT_DIR . '/themes'; } /** * Filters the absolute path to the themes directory. * * @since 1.5.0 * * @param string $theme_root Absolute path to themes directory. */ return apply_filters( 'theme_root', $theme_root ); } /** * Retrieves URI for themes directory. * * Does not have trailing slash. * * @since 1.5.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. * Default is to leverage the main theme root. * @param string $theme_root Optional. The theme root for which calculations will be based, * preventing the need for a get_raw_theme_root() call. Default empty. * @return string Themes directory URI. */ function get_theme_root_uri( $stylesheet_or_template = '', $theme_root = '' ) { global $wp_theme_directories; if ( $stylesheet_or_template && ! $theme_root ) { $theme_root = get_raw_theme_root( $stylesheet_or_template ); } if ( $stylesheet_or_template && $theme_root ) { if ( in_array( $theme_root, (array) $wp_theme_directories, true ) ) { // Absolute path. Make an educated guess. YMMV -- but note the filter below. if ( str_starts_with( $theme_root, WP_CONTENT_DIR ) ) { $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); } elseif ( str_starts_with( $theme_root, ABSPATH ) ) { $theme_root_uri = site_url( str_replace( ABSPATH, '', $theme_root ) ); } elseif ( str_starts_with( $theme_root, WP_PLUGIN_DIR ) || str_starts_with( $theme_root, WPMU_PLUGIN_DIR ) ) { $theme_root_uri = plugins_url( basename( $theme_root ), $theme_root ); } else { $theme_root_uri = $theme_root; } } else { $theme_root_uri = content_url( $theme_root ); } } else { $theme_root_uri = content_url( 'themes' ); } /** * Filters the URI for themes directory. * * @since 1.5.0 * * @param string $theme_root_uri The URI for themes directory. * @param string $siteurl WordPress web address which is set in General Options. * @param string $stylesheet_or_template The stylesheet or template name of the theme. */ return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); } /** * Gets the raw theme root relative to the content directory with no filters applied. * * @since 3.1.0 * * @global string[] $wp_theme_directories * * @param string $stylesheet_or_template The stylesheet or template name of the theme. * @param bool $skip_cache Optional. Whether to skip the cache. * Defaults to false, meaning the cache is used. * @return string Theme root. */ function get_raw_theme_root( $stylesheet_or_template, $skip_cache = false ) { global $wp_theme_directories; if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { return '/themes'; } $theme_root = false; // If requesting the root for the active theme, consult options to avoid calling get_theme_roots(). if ( ! $skip_cache ) { if ( get_option( 'stylesheet' ) === $stylesheet_or_template ) { $theme_root = get_option( 'stylesheet_root' ); } elseif ( get_option( 'template' ) === $stylesheet_or_template ) { $theme_root = get_option( 'template_root' ); } } if ( empty( $theme_root ) ) { $theme_roots = get_theme_roots(); if ( ! empty( $theme_roots[ $stylesheet_or_template ] ) ) { $theme_root = $theme_roots[ $stylesheet_or_template ]; } } return $theme_root; } /** * Displays localized stylesheet link element. * * @since 2.1.0 */ function locale_stylesheet() { $stylesheet = get_locale_stylesheet_uri(); if ( empty( $stylesheet ) ) { return; } $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; printf( '<link rel="stylesheet" href="%s"%s media="screen" />', $stylesheet, $type_attr ); } /** * Switches the theme. * * Accepts one argument: $stylesheet of the theme. It also accepts an additional function signature * of two arguments: $template then $stylesheet. This is for backward compatibility. * * @since 2.5.0 * * @global string[] $wp_theme_directories * @global WP_Customize_Manager $wp_customize * @global array $sidebars_widgets * @global array $wp_registered_sidebars * * @param string $stylesheet Stylesheet name. */ function switch_theme( $stylesheet ) { global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars; $requirements = validate_theme_requirements( $stylesheet ); if ( is_wp_error( $requirements ) ) { wp_die( $requirements ); } $_sidebars_widgets = null; if ( 'wp_ajax_customize_save' === current_action() ) { $old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' ); if ( $old_sidebars_widgets_data_setting ) { $_sidebars_widgets = $wp_customize->post_value( $old_sidebars_widgets_data_setting ); } } elseif ( is_array( $sidebars_widgets ) ) { $_sidebars_widgets = $sidebars_widgets; } if ( is_array( $_sidebars_widgets ) ) { set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $_sidebars_widgets, ) ); } $nav_menu_locations = get_theme_mod( 'nav_menu_locations' ); update_option( 'theme_switch_menu_locations', $nav_menu_locations, true ); if ( func_num_args() > 1 ) { $stylesheet = func_get_arg( 1 ); } $old_theme = wp_get_theme(); $new_theme = wp_get_theme( $stylesheet ); $template = $new_theme->get_template(); if ( wp_is_recovery_mode() ) { $paused_themes = wp_paused_themes(); $paused_themes->delete( $old_theme->get_stylesheet() ); $paused_themes->delete( $old_theme->get_template() ); } update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); if ( count( $wp_theme_directories ) > 1 ) { update_option( 'template_root', get_raw_theme_root( $template, true ) ); update_option( 'stylesheet_root', get_raw_theme_root( $stylesheet, true ) ); } else { delete_option( 'template_root' ); delete_option( 'stylesheet_root' ); } $new_name = $new_theme->get( 'Name' ); update_option( 'current_theme', $new_name ); // Migrate from the old mods_{name} option to theme_mods_{slug}. if ( is_admin() && false === get_option( 'theme_mods_' . $stylesheet ) ) { $default_theme_mods = (array) get_option( 'mods_' . $new_name ); if ( ! empty( $nav_menu_locations ) && empty( $default_theme_mods['nav_menu_locations'] ) ) { $default_theme_mods['nav_menu_locations'] = $nav_menu_locations; } add_option( "theme_mods_$stylesheet", $default_theme_mods ); } else { /* * Since retrieve_widgets() is called when initializing a theme in the Customizer, * we need to remove the theme mods to avoid overwriting changes made via * the Customizer when accessing wp-admin/widgets.php. */ if ( 'wp_ajax_customize_save' === current_action() ) { remove_theme_mod( 'sidebars_widgets' ); } } // Stores classic sidebars for later use by block themes. if ( $new_theme->is_block_theme() ) { set_theme_mod( 'wp_classic_sidebars', $wp_registered_sidebars ); } update_option( 'theme_switched', $old_theme->get_stylesheet() ); /* * Reset template globals when switching themes outside of a switched blog * context to ensure templates will be loaded from the new theme. */ if ( ! is_multisite() || ! ms_is_switched() ) { wp_set_template_globals(); } // Clear pattern caches. if ( ! is_multisite() ) { $new_theme->delete_pattern_cache(); $old_theme->delete_pattern_cache(); } // Set autoload=no for the old theme, autoload=yes for the switched theme. $theme_mods_options = array( 'theme_mods_' . $stylesheet => 'yes', 'theme_mods_' . $old_theme->get_stylesheet() => 'no', ); wp_set_option_autoload_values( $theme_mods_options ); /** * Fires after the theme is switched. * * See {@see 'after_switch_theme'}. * * @since 1.5.0 * @since 4.5.0 Introduced the `$old_theme` parameter. * * @param string $new_name Name of the new theme. * @param WP_Theme $new_theme WP_Theme instance of the new theme. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); } /** * Checks that the active theme has the required files. * * Standalone themes need to have a `templates/index.html` or `index.php` template file. * Child themes need to have a `Template` header in the `style.css` stylesheet. * * Does not initially check the default theme, which is the fallback and should always exist. * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. * Will switch theme to the fallback theme if active theme does not validate. * * You can use the {@see 'validate_current_theme'} filter to return false to disable * this functionality. * * @since 1.5.0 * @since 6.0.0 Removed the requirement for block themes to have an `index.php` template. * * @see WP_DEFAULT_THEME * * @return bool */ function validate_current_theme() { /** * Filters whether to validate the active theme. * * @since 2.7.0 * * @param bool $validate Whether to validate the active theme. Default true. */ if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) { return true; } if ( ! file_exists( get_template_directory() . '/templates/index.html' ) && ! file_exists( get_template_directory() . '/block-templates/index.html' ) // Deprecated path support since 5.9.0. && ! file_exists( get_template_directory() . '/index.php' ) ) { // Invalid. } elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) { // Invalid. } elseif ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { // Invalid. } else { // Valid. return true; } $default = wp_get_theme( WP_DEFAULT_THEME ); if ( $default->exists() ) { switch_theme( WP_DEFAULT_THEME ); return false; } /** * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, * switch to the latest core default theme that's installed. * * If it turns out that this latest core default theme is our current * theme, then there's nothing we can do about that, so we have to bail, * rather than going into an infinite loop. (This is why there are * checks against WP_DEFAULT_THEME above, also.) We also can't do anything * if it turns out there is no default theme installed. (That's `false`.) */ $default = WP_Theme::get_core_default_theme(); if ( false === $default || get_stylesheet() === $default->get_stylesheet() ) { return true; } switch_theme( $default->get_stylesheet() ); return false; } /** * Validates the theme requirements for WordPress version and PHP version. * * Uses the information from `Requires at least` and `Requires PHP` headers * defined in the theme's `style.css` file. * * @since 5.5.0 * @since 5.8.0 Removed support for using `readme.txt` as a fallback. * * @param string $stylesheet Directory name for the theme. * @return true|WP_Error True if requirements are met, WP_Error on failure. */ function validate_theme_requirements( $stylesheet ) { $theme = wp_get_theme( $stylesheet ); $requirements = array( 'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '', 'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '', ); $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); if ( ! $compatible_wp && ! $compatible_php ) { return new WP_Error( 'theme_wp_php_incompatible', sprintf( /* translators: %s: Theme name. */ _x( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } elseif ( ! $compatible_php ) { return new WP_Error( 'theme_php_incompatible', sprintf( /* translators: %s: Theme name. */ _x( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } elseif ( ! $compatible_wp ) { return new WP_Error( 'theme_wp_incompatible', sprintf( /* translators: %s: Theme name. */ _x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ), $theme->display( 'Name' ) ) ); } return true; } /** * Retrieves all theme modifications. * * @since 3.1.0 * @since 5.9.0 The return value is always an array. * * @return array Theme modifications. */ function get_theme_mods() { $theme_slug = get_option( 'stylesheet' ); $mods = get_option( "theme_mods_$theme_slug" ); if ( false === $mods ) { $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } $mods = get_option( "mods_$theme_name" ); // Deprecated location. if ( is_admin() && false !== $mods ) { update_option( "theme_mods_$theme_slug", $mods ); delete_option( "mods_$theme_name" ); } } if ( ! is_array( $mods ) ) { $mods = array(); } return $mods; } /** * Retrieves theme modification value for the active theme. * * If the modification name does not exist and `$default_value` is a string, then the * default will be passed through the {@link https://www.php.net/sprintf sprintf()} * PHP function with the template directory URI as the first value and the * stylesheet directory URI as the second value. * * @since 2.1.0 * * @param string $name Theme modification name. * @param mixed $default_value Optional. Theme modification default value. Default false. * @return mixed Theme modification value. */ function get_theme_mod( $name, $default_value = false ) { $mods = get_theme_mods(); if ( isset( $mods[ $name ] ) ) { /** * Filters the theme modification, or 'theme_mod', value. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 2.2.0 * * @param mixed $current_mod The value of the active theme modification. */ return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); } if ( is_string( $default_value ) ) { // Only run the replacement if an sprintf() string format pattern was found. if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default_value ) ) { // Remove a single trailing percent sign. $default_value = preg_replace( '#(?<!%)%$#', '', $default_value ); $default_value = sprintf( $default_value, get_template_directory_uri(), get_stylesheet_directory_uri() ); } } /** This filter is documented in wp-includes/theme.php */ return apply_filters( "theme_mod_{$name}", $default_value ); } /** * Updates theme modification value for the active theme. * * @since 2.1.0 * @since 5.6.0 A return value was added. * * @param string $name Theme modification name. * @param mixed $value Theme modification value. * @return bool True if the value was updated, false otherwise. */ function set_theme_mod( $name, $value ) { $mods = get_theme_mods(); $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; /** * Filters the theme modification, or 'theme_mod', value on save. * * The dynamic portion of the hook name, `$name`, refers to the key name * of the modification array. For example, 'header_textcolor', 'header_image', * and so on depending on the theme options. * * @since 3.9.0 * * @param mixed $value The new value of the theme modification. * @param mixed $old_value The current value of the theme modification. */ $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); $theme = get_option( 'stylesheet' ); return update_option( "theme_mods_$theme", $mods ); } /** * Removes theme modification name from active theme list. * * If removing the name also removes all elements, then the entire option * will be removed. * * @since 2.1.0 * * @param string $name Theme modification name. */ function remove_theme_mod( $name ) { $mods = get_theme_mods(); if ( ! isset( $mods[ $name ] ) ) { return; } unset( $mods[ $name ] ); if ( empty( $mods ) ) { remove_theme_mods(); return; } $theme = get_option( 'stylesheet' ); update_option( "theme_mods_$theme", $mods ); } /** * Removes theme modifications option for the active theme. * * @since 2.1.0 */ function remove_theme_mods() { delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); // Old style. $theme_name = get_option( 'current_theme' ); if ( false === $theme_name ) { $theme_name = wp_get_theme()->get( 'Name' ); } delete_option( 'mods_' . $theme_name ); } /** * Retrieves the custom header text color in 3- or 6-digit hexadecimal form. * * @since 2.1.0 * * @return string Header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). */ function get_header_textcolor() { return get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); } /** * Displays the custom header text color in 3- or 6-digit hexadecimal form (minus the hash symbol). * * @since 2.1.0 */ function header_textcolor() { echo get_header_textcolor(); } /** * Whether to display the header text. * * @since 3.4.0 * * @return bool */ function display_header_text() { if ( ! current_theme_supports( 'custom-header', 'header-text' ) ) { return false; } $text_color = get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); return 'blank' !== $text_color; } /** * Checks whether a header image is set or not. * * @since 4.2.0 * * @see get_header_image() * * @return bool Whether a header image is set or not. */ function has_header_image() { return (bool) get_header_image(); } /** * Retrieves header image for custom header. * * @since 2.1.0 * * @return string|false */ function get_header_image() { $url = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); if ( 'remove-header' === $url ) { return false; } if ( is_random_header_image() ) { $url = get_random_header_image(); } /** * Filters the header image URL. * * @since 6.1.0 * * @param string $url Header image URL. */ $url = apply_filters( 'get_header_image', $url ); if ( ! is_string( $url ) ) { return false; } $url = trim( $url ); return sanitize_url( set_url_scheme( $url ) ); } /** * Creates image tag markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Additional attributes for the image tag. Can be used * to override the default attributes. Default empty. * @return string HTML image element markup or empty string on failure. */ function get_header_image_tag( $attr = array() ) { $header = get_custom_header(); $header->url = get_header_image(); if ( ! $header->url ) { return ''; } $width = absint( $header->width ); $height = absint( $header->height ); $alt = ''; // Use alternative text assigned to the image, if available. Otherwise, leave it empty. if ( ! empty( $header->attachment_id ) ) { $image_alt = get_post_meta( $header->attachment_id, '_wp_attachment_image_alt', true ); if ( is_string( $image_alt ) ) { $alt = $image_alt; } } $attr = wp_parse_args( $attr, array( 'src' => $header->url, 'width' => $width, 'height' => $height, 'alt' => $alt, ) ); // Generate 'srcset' and 'sizes' if not already present. if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) ) { $image_meta = get_post_meta( $header->attachment_id, '_wp_attachment_metadata', true ); $size_array = array( $width, $height ); if ( is_array( $image_meta ) ) { $srcset = wp_calculate_image_srcset( $size_array, $header->url, $image_meta, $header->attachment_id ); if ( ! empty( $attr['sizes'] ) ) { $sizes = $attr['sizes']; } else { $sizes = wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id ); } if ( $srcset && $sizes ) { $attr['srcset'] = $srcset; $attr['sizes'] = $sizes; } } } $attr = array_merge( $attr, wp_get_loading_optimization_attributes( 'img', $attr, 'get_header_image_tag' ) ); /* * If the default value of `lazy` for the `loading` attribute is overridden * to omit the attribute for this image, ensure it is not included. */ if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); } // If the `fetchpriority` attribute is overridden and set to false or an empty string. if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); } // If the `decoding` attribute is overridden and set to false or an empty string. if ( isset( $attr['decoding'] ) && ! $attr['decoding'] ) { unset( $attr['decoding'] ); } /** * Filters the list of header image attributes. * * @since 5.9.0 * * @param array $attr Array of the attributes for the image tag. * @param object $header The custom header object returned by 'get_custom_header()'. */ $attr = apply_filters( 'get_header_image_tag_attributes', $attr, $header ); $attr = array_map( 'esc_attr', $attr ); $html = '<img'; foreach ( $attr as $name => $value ) { $html .= ' ' . $name . '="' . $value . '"'; } $html .= ' />'; /** * Filters the markup of header images. * * @since 4.4.0 * * @param string $html The HTML image tag markup being filtered. * @param object $header The custom header object returned by 'get_custom_header()'. * @param array $attr Array of the attributes for the image tag. */ return apply_filters( 'get_header_image_tag', $html, $header, $attr ); } /** * Displays the image markup for a custom header image. * * @since 4.4.0 * * @param array $attr Optional. Attributes for the image markup. Default empty. */ function the_header_image_tag( $attr = array() ) { echo get_header_image_tag( $attr ); } /** * Gets random header image data from registered images in theme. * * @since 3.4.0 * * @access private * * @global array $_wp_default_headers * * @return object */ function _get_random_header_data() { global $_wp_default_headers; static $_wp_random_header = null; if ( empty( $_wp_random_header ) ) { $header_image_mod = get_theme_mod( 'header_image', '' ); $headers = array(); if ( 'random-uploaded-image' === $header_image_mod ) { $headers = get_uploaded_header_images(); } elseif ( ! empty( $_wp_default_headers ) ) { if ( 'random-default-image' === $header_image_mod ) { $headers = $_wp_default_headers; } else { if ( current_theme_supports( 'custom-header', 'random-default' ) ) { $headers = $_wp_default_headers; } } } if ( empty( $headers ) ) { return new stdClass(); } $_wp_random_header = (object) $headers[ array_rand( $headers ) ]; $_wp_random_header->url = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() ); $_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() ); } return $_wp_random_header; } /** * Gets random header image URL from registered images in theme. * * @since 3.2.0 * * @return string Path to header image. */ function get_random_header_image() { $random_image = _get_random_header_data(); if ( empty( $random_image->url ) ) { return ''; } return $random_image->url; } /** * Checks if random header image is in use. * * Always true if user expressly chooses the option in Appearance > Header. * Also true if theme has multiple header images registered, no specific header image * is chosen, and theme turns on random headers with add_theme_support(). * * @since 3.2.0 * * @param string $type The random pool to use. Possible values include 'any', * 'default', 'uploaded'. Default 'any'. * @return bool */ function is_random_header_image( $type = 'any' ) { $header_image_mod = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); if ( 'any' === $type ) { if ( 'random-default-image' === $header_image_mod || 'random-uploaded-image' === $header_image_mod || ( empty( $header_image_mod ) && '' !== get_random_header_image() ) ) { return true; } } else { if ( "random-$type-image" === $header_image_mod ) { return true; } elseif ( 'default' === $type && empty( $header_image_mod ) && '' !== get_random_header_image() ) { return true; } } return false; } /** * Displays header image URL. * * @since 2.1.0 */ function header_image() { $image = get_header_image(); if ( $image ) { echo esc_url( $image ); } } /** * Gets the header images uploaded for the active theme. * * @since 3.2.0 * * @return array */ function get_uploaded_header_images() { $header_images = array(); // @todo Caching. $headers = get_posts( array( 'post_type' => 'attachment', 'meta_key' => '_wp_attachment_is_custom_header', 'meta_value' => get_option( 'stylesheet' ), 'orderby' => 'none', 'nopaging' => true, ) ); if ( empty( $headers ) ) { return array(); } foreach ( (array) $headers as $header ) { $url = sanitize_url( wp_get_attachment_url( $header->ID ) ); $header_data = wp_get_attachment_metadata( $header->ID ); $header_index = $header->ID; $header_images[ $header_index ] = array(); $header_images[ $header_index ]['attachment_id'] = $header->ID; $header_images[ $header_index ]['url'] = $url; $header_images[ $header_index ]['thumbnail_url'] = $url; $header_images[ $header_index ]['alt_text'] = get_post_meta( $header->ID, '_wp_attachment_image_alt', true ); if ( isset( $header_data['attachment_parent'] ) ) { $header_images[ $header_index ]['attachment_parent'] = $header_data['attachment_parent']; } else { $header_images[ $header_index ]['attachment_parent'] = ''; } if ( isset( $header_data['width'] ) ) { $header_images[ $header_index ]['width'] = $header_data['width']; } if ( isset( $header_data['height'] ) ) { $header_images[ $header_index ]['height'] = $header_data['height']; } } return $header_images; } /** * Gets the header image data. * * @since 3.4.0 * * @global array $_wp_default_headers * * @return object */ function get_custom_header() { global $_wp_default_headers; if ( is_random_header_image() ) { $data = _get_random_header_data(); } else { $data = get_theme_mod( 'header_image_data' ); if ( ! $data && current_theme_supports( 'custom-header', 'default-image' ) ) { $directory_args = array( get_template_directory_uri(), get_stylesheet_directory_uri() ); $data = array(); $data['url'] = vsprintf( get_theme_support( 'custom-header', 'default-image' ), $directory_args ); $data['thumbnail_url'] = $data['url']; if ( ! empty( $_wp_default_headers ) ) { foreach ( (array) $_wp_default_headers as $default_header ) { $url = vsprintf( $default_header['url'], $directory_args ); if ( $data['url'] === $url ) { $data = $default_header; $data['url'] = $url; $data['thumbnail_url'] = vsprintf( $data['thumbnail_url'], $directory_args ); break; } } } } } $default = array( 'url' => '', 'thumbnail_url' => '', 'width' => get_theme_support( 'custom-header', 'width' ), 'height' => get_theme_support( 'custom-header', 'height' ), 'video' => get_theme_support( 'custom-header', 'video' ), ); return (object) wp_parse_args( $data, $default ); } /** * Registers a selection of default headers to be displayed by the custom header admin UI. * * @since 3.0.0 * * @global array $_wp_default_headers * * @param array $headers Array of headers keyed by a string ID. The IDs point to arrays * containing 'url', 'thumbnail_url', and 'description' keys. */ function register_default_headers( $headers ) { global $_wp_default_headers; $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); } /** * Unregisters default headers. * * This function must be called after register_default_headers() has already added the * header you want to remove. * * @see register_default_headers() * @since 3.0.0 * * @global array $_wp_default_headers * * @param string|array $header The header string id (key of array) to remove, or an array thereof. * @return bool|void A single header returns true on success, false on failure. * There is currently no return value for multiple headers. */ function unregister_default_headers( $header ) { global $_wp_default_headers; if ( is_array( $header ) ) { array_map( 'unregister_default_headers', $header ); } elseif ( isset( $_wp_default_headers[ $header ] ) ) { unset( $_wp_default_headers[ $header ] ); return true; } else { return false; } } /** * Checks whether a header video is set or not. * * @since 4.7.0 * * @see get_header_video_url() * * @return bool Whether a header video is set or not. */ function has_header_video() { return (bool) get_header_video_url(); } /** * Retrieves header video URL for custom header. * * Uses a local video if present, or falls back to an external video. * * @since 4.7.0 * * @return string|false Header video URL or false if there is no video. */ function get_header_video_url() { $id = absint( get_theme_mod( 'header_video' ) ); if ( $id ) { // Get the file URL from the attachment ID. $url = wp_get_attachment_url( $id ); } else { $url = get_theme_mod( 'external_header_video' ); } /** * Filters the header video URL. * * @since 4.7.3 * * @param string $url Header video URL, if available. */ $url = apply_filters( 'get_header_video_url', $url ); if ( ! $id && ! $url ) { return false; } return sanitize_url( set_url_scheme( $url ) ); } /** * Displays header video URL. * * @since 4.7.0 */ function the_header_video_url() { $video = get_header_video_url(); if ( $video ) { echo esc_url( $video ); } } /** * Retrieves header video settings. * * @since 4.7.0 * * @return array */ function get_header_video_settings() { $header = get_custom_header(); $video_url = get_header_video_url(); $video_type = wp_check_filetype( $video_url, wp_get_mime_types() ); $settings = array( 'mimeType' => '', 'posterUrl' => get_header_image(), 'videoUrl' => $video_url, 'width' => absint( $header->width ), 'height' => absint( $header->height ), 'minWidth' => 900, 'minHeight' => 500, 'l10n' => array( 'pause' => __( 'Pause' ), 'play' => __( 'Play' ), 'pauseSpeak' => __( 'Video is paused.' ), 'playSpeak' => __( 'Video is playing.' ), ), ); if ( preg_match( '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#', $video_url ) ) { $settings['mimeType'] = 'video/x-youtube'; } elseif ( ! empty( $video_type['type'] ) ) { $settings['mimeType'] = $video_type['type']; } /** * Filters header video settings. * * @since 4.7.0 * * @param array $settings An array of header video settings. */ return apply_filters( 'header_video_settings', $settings ); } /** * Checks whether a custom header is set or not. * * @since 4.7.0 * * @return bool True if a custom header is set. False if not. */ function has_custom_header() { if ( has_header_image() || ( has_header_video() && is_header_video_active() ) ) { return true; } return false; } /** * Checks whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @return bool True if the custom header video should be shown. False if not. */ function is_header_video_active() { if ( ! get_theme_support( 'custom-header', 'video' ) ) { return false; } $video_active_cb = get_theme_support( 'custom-header', 'video-active-callback' ); if ( empty( $video_active_cb ) || ! is_callable( $video_active_cb ) ) { $show_video = true; } else { $show_video = call_user_func( $video_active_cb ); } /** * Filters whether the custom header video is eligible to show on the current page. * * @since 4.7.0 * * @param bool $show_video Whether the custom header video should be shown. Returns the value * of the theme setting for the `custom-header`'s `video-active-callback`. * If no callback is set, the default value is that of `is_front_page()`. */ return apply_filters( 'is_header_video_active', $show_video ); } /** * Retrieves the markup for a custom header. * * The container div will always be returned in the Customizer preview. * * @since 4.7.0 * * @return string The markup for a custom header on success. */ function get_custom_header_markup() { if ( ! has_custom_header() && ! is_customize_preview() ) { return ''; } return sprintf( '<div id="wp-custom-header" class="wp-custom-header">%s</div>', get_header_image_tag() ); } /** * Prints the markup for a custom header. * * A container div will always be printed in the Customizer preview. * * @since 4.7.0 */ function the_custom_header_markup() { $custom_header = get_custom_header_markup(); if ( empty( $custom_header ) ) { return; } echo $custom_header; if ( is_header_video_active() && ( has_header_video() || is_customize_preview() ) ) { wp_enqueue_script( 'wp-custom-header' ); wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() ); } } /** * Retrieves background image for custom background. * * @since 3.0.0 * * @return string */ function get_background_image() { return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); } /** * Displays background image path. * * @since 3.0.0 */ function background_image() { echo get_background_image(); } /** * Retrieves value for custom background color. * * @since 3.0.0 * * @return string */ function get_background_color() { return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); } /** * Displays background color value. * * @since 3.0.0 */ function background_color() { echo get_background_color(); } /** * Default custom background callback. * * @since 3.0.0 */ function _custom_background_cb() { // $background is the saved custom image, or the default image. $background = set_url_scheme( get_background_image() ); /* * $color is the saved custom color. * A default has to be specified in style.css. It will not be printed here. */ $color = get_background_color(); if ( get_theme_support( 'custom-background', 'default-color' ) === $color ) { $color = false; } $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; if ( ! $background && ! $color ) { if ( is_customize_preview() ) { printf( '<style%s id="custom-background-css"></style>', $type_attr ); } return; } $style = $color ? 'background-color: ' . maybe_hash_hex_color( $color ) . ';' : ''; if ( $background ) { $image = ' background-image: url("' . sanitize_url( $background ) . '");'; // Background Position. $position_x = get_theme_mod( 'background_position_x', get_theme_support( 'custom-background', 'default-position-x' ) ); $position_y = get_theme_mod( 'background_position_y', get_theme_support( 'custom-background', 'default-position-y' ) ); if ( ! in_array( $position_x, array( 'left', 'center', 'right' ), true ) ) { $position_x = 'left'; } if ( ! in_array( $position_y, array( 'top', 'center', 'bottom' ), true ) ) { $position_y = 'top'; } $position = " background-position: $position_x $position_y;"; // Background Size. $size = get_theme_mod( 'background_size', get_theme_support( 'custom-background', 'default-size' ) ); if ( ! in_array( $size, array( 'auto', 'contain', 'cover' ), true ) ) { $size = 'auto'; } $size = " background-size: $size;"; // Background Repeat. $repeat = get_theme_mod( 'background_repeat', get_theme_support( 'custom-background', 'default-repeat' ) ); if ( ! in_array( $repeat, array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat' ), true ) ) { $repeat = 'repeat'; } $repeat = " background-repeat: $repeat;"; // Background Scroll. $attachment = get_theme_mod( 'background_attachment', get_theme_support( 'custom-background', 'default-attachment' ) ); if ( 'fixed' !== $attachment ) { $attachment = 'scroll'; } $attachment = " background-attachment: $attachment;"; $style .= $image . $position . $size . $repeat . $attachment; } ?> <style<?php echo $type_attr; ?> id="custom-background-css"> body.custom-background { <?php echo trim( $style ); ?> } </style> <?php } /** * Renders the Custom CSS style element. * * @since 4.7.0 */ function wp_custom_css_cb() { $styles = wp_get_custom_css(); if ( $styles || is_customize_preview() ) : $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?> <style<?php echo $type_attr; ?> id="wp-custom-css"> <?php // Note that esc_html() cannot be used because `div > span` is not interpreted properly. echo strip_tags( $styles ); ?> </style> <?php endif; } /** * Fetches the `custom_css` post for a given theme. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return WP_Post|null The custom_css post or null if none exists. */ function wp_get_custom_css_post( $stylesheet = '' ) { if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } $custom_css_query_vars = array( 'post_type' => 'custom_css', 'post_status' => get_post_stati(), 'name' => sanitize_title( $stylesheet ), 'posts_per_page' => 1, 'no_found_rows' => true, 'cache_results' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'lazy_load_term_meta' => false, ); $post = null; if ( get_stylesheet() === $stylesheet ) { $post_id = get_theme_mod( 'custom_css_post_id' ); if ( $post_id > 0 && get_post( $post_id ) ) { $post = get_post( $post_id ); } // `-1` indicates no post exists; no query necessary. if ( ! $post && -1 !== $post_id ) { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; /* * Cache the lookup. See wp_update_custom_css_post(). * @todo This should get cleared if a custom_css post is added/removed. */ set_theme_mod( 'custom_css_post_id', $post ? $post->ID : -1 ); } } else { $query = new WP_Query( $custom_css_query_vars ); $post = $query->post; } return $post; } /** * Fetches the saved Custom CSS content for rendering. * * @since 4.7.0 * * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme. * @return string The Custom CSS Post content. */ function wp_get_custom_css( $stylesheet = '' ) { $css = ''; if ( empty( $stylesheet ) ) { $stylesheet = get_stylesheet(); } $post = wp_get_custom_css_post( $stylesheet ); if ( $post ) { $css = $post->post_content; } /** * Filters the custom CSS output into the head element. * * @since 4.7.0 * * @param string $css CSS pulled in from the Custom CSS post type. * @param string $stylesheet The theme stylesheet name. */ $css = apply_filters( 'wp_get_custom_css', $css, $stylesheet ); return $css; } /** * Updates the `custom_css` post for a given theme. * * Inserts a `custom_css` post when one doesn't yet exist. * * @since 4.7.0 * * @param string $css CSS, stored in `post_content`. * @param array $args { * Args. * * @type string $preprocessed Optional. Pre-processed CSS, stored in `post_content_filtered`. * Normally empty string. * @type string $stylesheet Optional. Stylesheet (child theme) to update. * Defaults to active theme/stylesheet. * } * @return WP_Post|WP_Error Post on success, error on failure. */ function wp_update_custom_css_post( $css, $args = array() ) { $args = wp_parse_args( $args, array( 'preprocessed' => '', 'stylesheet' => get_stylesheet(), ) ); $data = array( 'css' => $css, 'preprocessed' => $args['preprocessed'], ); /** * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args * for a `custom_css` post being updated. * * This filter can be used by plugin that offer CSS pre-processors, to store the original * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`. * When used in this way, the `post_content_filtered` should be supplied as the setting value * instead of `post_content` via a the `customize_value_custom_css` filter, for example: * * <code> * add_filter( 'customize_value_custom_css', function( $value, $setting ) { * $post = wp_get_custom_css_post( $setting->stylesheet ); * if ( $post && ! empty( $post->post_content_filtered ) ) { * $css = $post->post_content_filtered; * } * return $css; * }, 10, 2 ); * </code> * * @since 4.7.0 * @param array $data { * Custom CSS data. * * @type string $css CSS stored in `post_content`. * @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. * Normally empty string. * } * @param array $args { * The args passed into `wp_update_custom_css_post()` merged with defaults. * * @type string $css The original CSS passed in to be updated. * @type string $preprocessed The original preprocessed CSS passed in to be updated. * @type string $stylesheet The stylesheet (theme) being updated. * } */ $data = apply_filters( 'update_custom_css_data', $data, array_merge( $args, compact( 'css' ) ) ); $post_data = array( 'post_title' => $args['stylesheet'], 'post_name' => sanitize_title( $args['stylesheet'] ), 'post_type' => 'custom_css', 'post_status' => 'publish', 'post_content' => $data['css'], 'post_content_filtered' => $data['preprocessed'], ); // Update post if it already exists, otherwise create a new one. $post = wp_get_custom_css_post( $args['stylesheet'] ); if ( $post ) { $post_data['ID'] = $post->ID; $r = wp_update_post( wp_slash( $post_data ), true ); } else { $r = wp_insert_post( wp_slash( $post_data ), true ); if ( ! is_wp_error( $r ) ) { if ( get_stylesheet() === $args['stylesheet'] ) { set_theme_mod( 'custom_css_post_id', $r ); } // Trigger creation of a revision. This should be removed once #30854 is resolved. $revisions = wp_get_latest_revision_id_and_total_count( $r ); if ( ! is_wp_error( $revisions ) && 0 === $revisions['count'] ) { wp_save_post_revision( $r ); } } } if ( is_wp_error( $r ) ) { return $r; } return get_post( $r ); } /** * Adds callback for custom TinyMCE editor stylesheets. * * The parameter $stylesheet is the name of the stylesheet, relative to * the theme root. It also accepts an array of stylesheets. * It is optional and defaults to 'editor-style.css'. * * This function automatically adds another stylesheet with -rtl prefix, e.g. editor-style-rtl.css. * If that file doesn't exist, it is removed before adding the stylesheet(s) to TinyMCE. * If an array of stylesheets is passed to add_editor_style(), * RTL is only added for the first stylesheet. * * Since version 3.4 the TinyMCE body has .rtl CSS class. * It is a better option to use that class and add any RTL styles to the main stylesheet. * * @since 3.0.0 * * @global array $editor_styles * * @param array|string $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. * Defaults to 'editor-style.css' */ function add_editor_style( $stylesheet = 'editor-style.css' ) { global $editor_styles; add_theme_support( 'editor-style' ); $editor_styles = (array) $editor_styles; $stylesheet = (array) $stylesheet; if ( is_rtl() ) { $rtl_stylesheet = str_replace( '.css', '-rtl.css', $stylesheet[0] ); $stylesheet[] = $rtl_stylesheet; } $editor_styles = array_merge( $editor_styles, $stylesheet ); } /** * Removes all visual editor stylesheets. * * @since 3.1.0 * * @global array $editor_styles * * @return bool True on success, false if there were no stylesheets to remove. */ function remove_editor_styles() { if ( ! current_theme_supports( 'editor-style' ) ) { return false; } _remove_theme_support( 'editor-style' ); if ( is_admin() ) { $GLOBALS['editor_styles'] = array(); } return true; } /** * Retrieves any registered editor stylesheet URLs. * * @since 4.0.0 * * @global array $editor_styles Registered editor stylesheets * * @return string[] If registered, a list of editor stylesheet URLs. */ function get_editor_stylesheets() { $stylesheets = array(); // Load editor_style.css if the active theme supports it. if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) { $editor_styles = $GLOBALS['editor_styles']; $editor_styles = array_unique( array_filter( $editor_styles ) ); $style_uri = get_stylesheet_directory_uri(); $style_dir = get_stylesheet_directory(); // Support externally referenced styles (like, say, fonts). foreach ( $editor_styles as $key => $file ) { if ( preg_match( '~^(https?:)?//~', $file ) ) { $stylesheets[] = sanitize_url( $file ); unset( $editor_styles[ $key ] ); } } // Look in a parent theme first, that way child theme CSS overrides. if ( is_child_theme() ) { $template_uri = get_template_directory_uri(); $template_dir = get_template_directory(); foreach ( $editor_styles as $key => $file ) { if ( $file && file_exists( "$template_dir/$file" ) ) { $stylesheets[] = "$template_uri/$file"; } } } foreach ( $editor_styles as $file ) { if ( $file && file_exists( "$style_dir/$file" ) ) { $stylesheets[] = "$style_uri/$file"; } } } /** * Filters the array of URLs of stylesheets applied to the editor. * * @since 4.3.0 * * @param string[] $stylesheets Array of URLs of stylesheets to be applied to the editor. */ return apply_filters( 'editor_stylesheets', $stylesheets ); } /** * Expands a theme's starter content configuration using core-provided data. * * @since 4.7.0 * * @return array Array of starter content. */ function get_theme_starter_content() { $theme_support = get_theme_support( 'starter-content' ); if ( is_array( $theme_support ) && ! empty( $theme_support[0] ) && is_array( $theme_support[0] ) ) { $config = $theme_support[0]; } else { $config = array(); } $core_content = array( 'widgets' => array( 'text_business_info' => array( 'text', array( 'title' => _x( 'Find Us', 'Theme starter content' ), 'text' => implode( '', array( '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", _x( '123 Main Street', 'Theme starter content' ) . "\n", _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", _x( 'Monday–Friday: 9:00AM–5:00PM', 'Theme starter content' ) . "\n", _x( 'Saturday & Sunday: 11:00AM–3:00PM', 'Theme starter content' ), ) ), 'filter' => true, 'visual' => true, ), ), 'text_about' => array( 'text', array( 'title' => _x( 'About This Site', 'Theme starter content' ), 'text' => _x( 'This may be a good place to introduce yourself and your site or include some credits.', 'Theme starter content' ), 'filter' => true, 'visual' => true, ), ), 'archives' => array( 'archives', array( 'title' => _x( 'Archives', 'Theme starter content' ), ), ), 'calendar' => array( 'calendar', array( 'title' => _x( 'Calendar', 'Theme starter content' ), ), ), 'categories' => array( 'categories', array( 'title' => _x( 'Categories', 'Theme starter content' ), ), ), 'meta' => array( 'meta', array( 'title' => _x( 'Meta', 'Theme starter content' ), ), ), 'recent-comments' => array( 'recent-comments', array( 'title' => _x( 'Recent Comments', 'Theme starter content' ), ), ), 'recent-posts' => array( 'recent-posts', array( 'title' => _x( 'Recent Posts', 'Theme starter content' ), ), ), 'search' => array( 'search', array( 'title' => _x( 'Search', 'Theme starter content' ), ), ), ), 'nav_menus' => array( 'link_home' => array( 'type' => 'custom', 'title' => _x( 'Home', 'Theme starter content' ), 'url' => home_url( '/' ), ), 'page_home' => array( // Deprecated in favor of 'link_home'. 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{home}}', ), 'page_about' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{about}}', ), 'page_blog' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{blog}}', ), 'page_news' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{news}}', ), 'page_contact' => array( 'type' => 'post_type', 'object' => 'page', 'object_id' => '{{contact}}', ), 'link_email' => array( 'title' => _x( 'Email', 'Theme starter content' ), 'url' => 'mailto:wordpress@example.com', ), 'link_facebook' => array( 'title' => _x( 'Facebook', 'Theme starter content' ), 'url' => 'https://www.facebook.com/wordpress', ), 'link_foursquare' => array( 'title' => _x( 'Foursquare', 'Theme starter content' ), 'url' => 'https://foursquare.com/', ), 'link_github' => array( 'title' => _x( 'GitHub', 'Theme starter content' ), 'url' => 'https://github.com/wordpress/', ), 'link_instagram' => array( 'title' => _x( 'Instagram', 'Theme starter content' ), 'url' => 'https://www.instagram.com/explore/tags/wordcamp/', ), 'link_linkedin' => array( 'title' => _x( 'LinkedIn', 'Theme starter content' ), 'url' => 'https://www.linkedin.com/company/1089783', ), 'link_pinterest' => array( 'title' => _x( 'Pinterest', 'Theme starter content' ), 'url' => 'https://www.pinterest.com/', ), 'link_twitter' => array( 'title' => _x( 'Twitter', 'Theme starter content' ), 'url' => 'https://twitter.com/wordpress', ), 'link_yelp' => array( 'title' => _x( 'Yelp', 'Theme starter content' ), 'url' => 'https://www.yelp.com', ), 'link_youtube' => array( 'title' => _x( 'YouTube', 'Theme starter content' ), 'url' => 'https://www.youtube.com/channel/UCdof4Ju7amm1chz1gi1T2ZA', ), ), 'posts' => array( 'home' => array( 'post_type' => 'page', 'post_title' => _x( 'Home', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'Welcome to your site! This is your homepage, which is what most visitors will see when they come to your site for the first time.', 'Theme starter content' ) ), ), 'about' => array( 'post_type' => 'page', 'post_title' => _x( 'About', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'You might be an artist who would like to introduce yourself and your work here or maybe you are a business with a mission to describe.', 'Theme starter content' ) ), ), 'contact' => array( 'post_type' => 'page', 'post_title' => _x( 'Contact', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'This is a page with some basic contact information, such as an address and phone number. You might also try a plugin to add a contact form.', 'Theme starter content' ) ), ), 'blog' => array( 'post_type' => 'page', 'post_title' => _x( 'Blog', 'Theme starter content' ), ), 'news' => array( 'post_type' => 'page', 'post_title' => _x( 'News', 'Theme starter content' ), ), 'homepage-section' => array( 'post_type' => 'page', 'post_title' => _x( 'A homepage section', 'Theme starter content' ), 'post_content' => sprintf( "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", _x( 'This is an example of a homepage section. Homepage sections can be any page other than the homepage itself, including the page that shows your latest blog posts.', 'Theme starter content' ) ), ), ), ); $content = array(); foreach ( $config as $type => $args ) { switch ( $type ) { // Use options and theme_mods as-is. case 'options': case 'theme_mods': $content[ $type ] = $config[ $type ]; break; // Widgets are grouped into sidebars. case 'widgets': foreach ( $config[ $type ] as $sidebar_id => $widgets ) { foreach ( $widgets as $id => $widget ) { if ( is_array( $widget ) ) { // Item extends core content. if ( ! empty( $core_content[ $type ][ $id ] ) ) { $widget = array( $core_content[ $type ][ $id ][0], array_merge( $core_content[ $type ][ $id ][1], $widget ), ); } $content[ $type ][ $sidebar_id ][] = $widget; } elseif ( is_string( $widget ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $widget ] ) ) { $content[ $type ][ $sidebar_id ][] = $core_content[ $type ][ $widget ]; } } } break; // And nav menu items are grouped into nav menus. case 'nav_menus': foreach ( $config[ $type ] as $nav_menu_location => $nav_menu ) { // Ensure nav menus get a name. if ( empty( $nav_menu['name'] ) ) { $nav_menu['name'] = $nav_menu_location; } $content[ $type ][ $nav_menu_location ]['name'] = $nav_menu['name']; foreach ( $nav_menu['items'] as $id => $nav_menu_item ) { if ( is_array( $nav_menu_item ) ) { // Item extends core content. if ( ! empty( $core_content[ $type ][ $id ] ) ) { $nav_menu_item = array_merge( $core_content[ $type ][ $id ], $nav_menu_item ); } $content[ $type ][ $nav_menu_location ]['items'][] = $nav_menu_item; } elseif ( is_string( $nav_menu_item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $nav_menu_item ] ) ) { $content[ $type ][ $nav_menu_location ]['items'][] = $core_content[ $type ][ $nav_menu_item ]; } } } break; // Attachments are posts but have special treatment. case 'attachments': foreach ( $config[ $type ] as $id => $item ) { if ( ! empty( $item['file'] ) ) { $content[ $type ][ $id ] = $item; } } break; /* * All that's left now are posts (besides attachments). * Not a default case for the sake of clarity and future work. */ case 'posts': foreach ( $config[ $type ] as $id => $item ) { if ( is_array( $item ) ) { // Item extends core content. if ( ! empty( $core_content[ $type ][ $id ] ) ) { $item = array_merge( $core_content[ $type ][ $id ], $item ); } // Enforce a subset of fields. $content[ $type ][ $id ] = wp_array_slice_assoc( $item, array( 'post_type', 'post_title', 'post_excerpt', 'post_name', 'post_content', 'menu_order', 'comment_status', 'thumbnail', 'template', ) ); } elseif ( is_string( $item ) && ! empty( $core_content[ $type ][ $item ] ) ) { $content[ $type ][ $item ] = $core_content[ $type ][ $item ]; } } break; } } /** * Filters the expanded array of starter content. * * @since 4.7.0 * * @param array $content Array of starter content. * @param array $config Array of theme-specific starter content configuration. */ return apply_filters( 'get_theme_starter_content', $content, $config ); } /** * Registers theme support for a given feature. * * Must be called in the theme's functions.php file to work. * If attached to a hook, it must be {@see 'after_setup_theme'}. * The {@see 'init'} hook may be too late for some features. * * Example usage: * * add_theme_support( 'title-tag' ); * add_theme_support( 'custom-logo', array( * 'height' => 480, * 'width' => 720, * ) ); * * @since 2.9.0 * @since 3.4.0 The `custom-header-uploads` feature was deprecated. * @since 3.6.0 The `html5` feature was added. * @since 3.6.1 The `html5` feature requires an array of types to be passed. Defaults to * 'comment-list', 'comment-form', 'search-form' for backward compatibility. * @since 3.9.0 The `html5` feature now also accepts 'gallery' and 'caption'. * @since 4.1.0 The `title-tag` feature was added. * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added. * @since 4.7.0 The `starter-content` feature was added. * @since 5.0.0 The `responsive-embeds`, `align-wide`, `dark-editor-style`, `disable-custom-colors`, * `disable-custom-font-sizes`, `editor-color-palette`, `editor-font-sizes`, * `editor-styles`, and `wp-block-styles` features were added. * @since 5.3.0 The `html5` feature now also accepts 'script' and 'style'. * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * @since 5.4.0 The `disable-custom-gradients` feature limits to default gradients or gradients added * through `editor-gradient-presets` theme support. * @since 5.5.0 The `core-block-patterns` feature was added and is enabled by default. * @since 5.5.0 The `custom-logo` feature now also accepts 'unlink-homepage-logo'. * @since 5.6.0 The `post-formats` feature warns if no array is passed as the second parameter. * @since 5.8.0 The `widgets-block-editor` feature enables the Widgets block editor. * @since 5.8.0 The `block-templates` feature indicates whether a theme uses block-based templates. * @since 6.0.0 The `html5` feature warns if no array is passed as the second parameter. * @since 6.1.0 The `block-template-parts` feature allows to edit any reusable template part from site editor. * @since 6.1.0 The `disable-layout-styles` feature disables the default layout styles. * @since 6.3.0 The `link-color` feature allows to enable the link color setting. * @since 6.3.0 The `border` feature allows themes without theme.json to add border styles to blocks. * @since 6.5.0 The `appearance-tools` feature enables a few design tools for blocks, * see `WP_Theme_JSON::APPEARANCE_TOOLS_OPT_INS` for a complete list. * @since 6.6.0 The `editor-spacing-sizes` feature was added. * * @global array $_wp_theme_features * * @param string $feature The feature being added. Likely core values include: * - 'admin-bar' * - 'align-wide' * - 'appearance-tools' * - 'automatic-feed-links' * - 'block-templates' * - 'block-template-parts' * - 'border' * - 'core-block-patterns' * - 'custom-background' * - 'custom-header' * - 'custom-line-height' * - 'custom-logo' * - 'customize-selective-refresh-widgets' * - 'custom-spacing' * - 'custom-units' * - 'dark-editor-style' * - 'disable-custom-colors' * - 'disable-custom-font-sizes' * - 'disable-custom-gradients' * - 'disable-layout-styles' * - 'editor-color-palette' * - 'editor-gradient-presets' * - 'editor-font-sizes' * - 'editor-spacing-sizes' * - 'editor-styles' * - 'featured-content' * - 'html5' * - 'link-color' * - 'menus' * - 'post-formats' * - 'post-thumbnails' * - 'responsive-embeds' * - 'starter-content' * - 'title-tag' * - 'widgets' * - 'widgets-block-editor' * - 'wp-block-styles' * @param mixed ...$args Optional extra arguments to pass along with certain features. * @return void|false Void on success, false on failure. */ function add_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! $args ) { $args = true; } switch ( $feature ) { case 'post-thumbnails': // All post types are already supported. if ( true === get_theme_support( 'post-thumbnails' ) ) { return; } /* * Merge post types with any that already declared their support * for post thumbnails. */ if ( isset( $args[0] ) && is_array( $args[0] ) && isset( $_wp_theme_features['post-thumbnails'] ) ) { $args[0] = array_unique( array_merge( $_wp_theme_features['post-thumbnails'][0], $args[0] ) ); } break; case 'post-formats': if ( isset( $args[0] ) && is_array( $args[0] ) ) { $post_formats = get_post_format_slugs(); unset( $post_formats['standard'] ); $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); } else { _doing_it_wrong( "add_theme_support( 'post-formats' )", __( 'You need to pass an array of post formats.' ), '5.6.0' ); return false; } break; case 'html5': // You can't just pass 'html5', you need to pass an array of types. if ( empty( $args[0] ) || ! is_array( $args[0] ) ) { _doing_it_wrong( "add_theme_support( 'html5' )", __( 'You need to pass an array of types.' ), '3.6.1' ); if ( ! empty( $args[0] ) && ! is_array( $args[0] ) ) { return false; } // Build an array of types for back-compat. $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); } // Calling 'html5' again merges, rather than overwrites. if ( isset( $_wp_theme_features['html5'] ) ) { $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] ); } break; case 'custom-logo': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'width' => null, 'height' => null, 'flex-width' => false, 'flex-height' => false, 'header-text' => '', 'unlink-homepage-logo' => false, ); $args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults ); // Allow full flexibility if no size is specified. if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) { $args[0]['flex-width'] = true; $args[0]['flex-height'] = true; } break; case 'custom-header-uploads': return add_theme_support( 'custom-header', array( 'uploads' => true ) ); case 'custom-header': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'default-image' => '', 'random-default' => false, 'width' => 0, 'height' => 0, 'flex-height' => false, 'flex-width' => false, 'default-text-color' => '', 'header-text' => true, 'uploads' => true, 'wp-head-callback' => '', 'admin-head-callback' => '', 'admin-preview-callback' => '', 'video' => false, 'video-active-callback' => 'is_front_page', ); $jit = isset( $args[0]['__jit'] ); unset( $args[0]['__jit'] ); /* * Merge in data from previous add_theme_support() calls. * The first value registered wins. (A child theme is set up first.) */ if ( isset( $_wp_theme_features['custom-header'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] ); } /* * Load in the defaults at the end, as we need to insure first one wins. * This will cause all constants to be defined, as each arg will then be set to the default. */ if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } /* * If a constant was defined, use that value. Otherwise, define the constant to ensure * the constant is always accurate (and is not defined later, overriding our value). * As stated above, the first value wins. * Once we get to wp_loaded (just-in-time), define any constants we haven't already. * Constants should be avoided. Don't reference them. This is just for backward compatibility. */ if ( defined( 'NO_HEADER_TEXT' ) ) { $args[0]['header-text'] = ! NO_HEADER_TEXT; } elseif ( isset( $args[0]['header-text'] ) ) { define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) ); } if ( defined( 'HEADER_IMAGE_WIDTH' ) ) { $args[0]['width'] = (int) HEADER_IMAGE_WIDTH; } elseif ( isset( $args[0]['width'] ) ) { define( 'HEADER_IMAGE_WIDTH', (int) $args[0]['width'] ); } if ( defined( 'HEADER_IMAGE_HEIGHT' ) ) { $args[0]['height'] = (int) HEADER_IMAGE_HEIGHT; } elseif ( isset( $args[0]['height'] ) ) { define( 'HEADER_IMAGE_HEIGHT', (int) $args[0]['height'] ); } if ( defined( 'HEADER_TEXTCOLOR' ) ) { $args[0]['default-text-color'] = HEADER_TEXTCOLOR; } elseif ( isset( $args[0]['default-text-color'] ) ) { define( 'HEADER_TEXTCOLOR', $args[0]['default-text-color'] ); } if ( defined( 'HEADER_IMAGE' ) ) { $args[0]['default-image'] = HEADER_IMAGE; } elseif ( isset( $args[0]['default-image'] ) ) { define( 'HEADER_IMAGE', $args[0]['default-image'] ); } if ( $jit && ! empty( $args[0]['default-image'] ) ) { $args[0]['random-default'] = false; } /* * If headers are supported, and we still don't have a defined width or height, * we have implicit flex sizes. */ if ( $jit ) { if ( empty( $args[0]['width'] ) && empty( $args[0]['flex-width'] ) ) { $args[0]['flex-width'] = true; } if ( empty( $args[0]['height'] ) && empty( $args[0]['flex-height'] ) ) { $args[0]['flex-height'] = true; } } break; case 'custom-background': if ( true === $args ) { $args = array( 0 => array() ); } $defaults = array( 'default-image' => '', 'default-preset' => 'default', 'default-position-x' => 'left', 'default-position-y' => 'top', 'default-size' => 'auto', 'default-repeat' => 'repeat', 'default-attachment' => 'scroll', 'default-color' => '', 'wp-head-callback' => '_custom_background_cb', 'admin-head-callback' => '', 'admin-preview-callback' => '', ); $jit = isset( $args[0]['__jit'] ); unset( $args[0]['__jit'] ); // Merge in data from previous add_theme_support() calls. The first value registered wins. if ( isset( $_wp_theme_features['custom-background'] ) ) { $args[0] = wp_parse_args( $_wp_theme_features['custom-background'][0], $args[0] ); } if ( $jit ) { $args[0] = wp_parse_args( $args[0], $defaults ); } if ( defined( 'BACKGROUND_COLOR' ) ) { $args[0]['default-color'] = BACKGROUND_COLOR; } elseif ( isset( $args[0]['default-color'] ) || $jit ) { define( 'BACKGROUND_COLOR', $args[0]['default-color'] ); } if ( defined( 'BACKGROUND_IMAGE' ) ) { $args[0]['default-image'] = BACKGROUND_IMAGE; } elseif ( isset( $args[0]['default-image'] ) || $jit ) { define( 'BACKGROUND_IMAGE', $args[0]['default-image'] ); } break; // Ensure that 'title-tag' is accessible in the admin. case 'title-tag': // Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php. if ( did_action( 'wp_loaded' ) ) { _doing_it_wrong( "add_theme_support( 'title-tag' )", sprintf( /* translators: 1: title-tag, 2: wp_loaded */ __( 'Theme support for %1$s should be registered before the %2$s hook.' ), '<code>title-tag</code>', '<code>wp_loaded</code>' ), '4.1.0' ); return false; } } $_wp_theme_features[ $feature ] = $args; } /** * Registers the internal custom header and background routines. * * @since 3.4.0 * @access private * * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background */ function _custom_header_background_just_in_time() { global $custom_image_header, $custom_background; if ( current_theme_supports( 'custom-header' ) ) { // In case any constants were defined after an add_custom_image_header() call, re-run. add_theme_support( 'custom-header', array( '__jit' => true ) ); $args = get_theme_support( 'custom-header' ); if ( $args[0]['wp-head-callback'] ) { add_action( 'wp_head', $args[0]['wp-head-callback'] ); } if ( is_admin() ) { require_once ABSPATH . 'wp-admin/includes/class-custom-image-header.php'; $custom_image_header = new Custom_Image_Header( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); } } if ( current_theme_supports( 'custom-background' ) ) { // In case any constants were defined after an add_custom_background() call, re-run. add_theme_support( 'custom-background', array( '__jit' => true ) ); $args = get_theme_support( 'custom-background' ); add_action( 'wp_head', $args[0]['wp-head-callback'] ); if ( is_admin() ) { require_once ABSPATH . 'wp-admin/includes/class-custom-background.php'; $custom_background = new Custom_Background( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); } } } /** * Adds CSS to hide header text for custom logo, based on Customizer setting. * * @since 4.5.0 * @access private */ function _custom_logo_header_styles() { if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) { $classes = (array) get_theme_support( 'custom-logo', 'header-text' ); $classes = array_map( 'sanitize_html_class', $classes ); $classes = '.' . implode( ', .', $classes ); $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; ?> <!-- Custom Logo: hide header text --> <style id="custom-logo-css"<?php echo $type_attr; ?>> <?php echo $classes; ?> { position: absolute; clip-path: inset(50%); } </style> <?php } } /** * Gets the theme support arguments passed when registering that support. * * Example usage: * * get_theme_support( 'custom-logo' ); * get_theme_support( 'custom-header', 'width' ); * * @since 3.1.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature to check. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return mixed The array of extra arguments or the value for the registered feature. */ function get_theme_support( $feature, ...$args ) { global $_wp_theme_features; if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } if ( ! $args ) { return $_wp_theme_features[ $feature ]; } switch ( $feature ) { case 'custom-logo': case 'custom-header': case 'custom-background': if ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) ) { return $_wp_theme_features[ $feature ][0][ $args[0] ]; } return false; default: return $_wp_theme_features[ $feature ]; } } /** * Allows a theme to de-register its support of a certain feature * * Should be called in the theme's functions.php file. Generally would * be used for child themes to override support from the parent theme. * * @since 3.0.0 * * @see add_theme_support() * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool|void Whether feature was removed. */ function remove_theme_support( $feature ) { // Do not remove internal registrations that are not used directly by themes. if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ), true ) ) { return false; } return _remove_theme_support( $feature ); } /** * Do not use. Removes theme support internally without knowledge of those not used * by themes directly. * * @access private * @since 3.1.0 * @global array $_wp_theme_features * @global Custom_Image_Header $custom_image_header * @global Custom_Background $custom_background * * @param string $feature The feature being removed. See add_theme_support() for the list * of possible values. * @return bool True if support was removed, false if the feature was not registered. */ function _remove_theme_support( $feature ) { global $_wp_theme_features; switch ( $feature ) { case 'custom-header-uploads': if ( ! isset( $_wp_theme_features['custom-header'] ) ) { return false; } add_theme_support( 'custom-header', array( 'uploads' => false ) ); return; // Do not continue - custom-header-uploads no longer exists. } if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } switch ( $feature ) { case 'custom-header': if ( ! did_action( 'wp_loaded' ) ) { break; } $support = get_theme_support( 'custom-header' ); if ( isset( $support[0]['wp-head-callback'] ) ) { remove_action( 'wp_head', $support[0]['wp-head-callback'] ); } if ( isset( $GLOBALS['custom_image_header'] ) ) { remove_action( 'admin_menu', array( $GLOBALS['custom_image_header'], 'init' ) ); unset( $GLOBALS['custom_image_header'] ); } break; case 'custom-background': if ( ! did_action( 'wp_loaded' ) ) { break; } $support = get_theme_support( 'custom-background' ); if ( isset( $support[0]['wp-head-callback'] ) ) { remove_action( 'wp_head', $support[0]['wp-head-callback'] ); } remove_action( 'admin_menu', array( $GLOBALS['custom_background'], 'init' ) ); unset( $GLOBALS['custom_background'] ); break; } unset( $_wp_theme_features[ $feature ] ); return true; } /** * Checks a theme's support for a given feature. * * Example usage: * * current_theme_supports( 'custom-logo' ); * current_theme_supports( 'html5', 'comment-form' ); * * @since 2.9.0 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter * by adding it to the function signature. * * @global array $_wp_theme_features * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param mixed ...$args Optional extra arguments to be checked against certain features. * @return bool True if the active theme supports the feature, false otherwise. */ function current_theme_supports( $feature, ...$args ) { global $_wp_theme_features; if ( 'custom-header-uploads' === $feature ) { return current_theme_supports( 'custom-header', 'uploads' ); } if ( ! isset( $_wp_theme_features[ $feature ] ) ) { return false; } // If no args passed then no extra checks need to be performed. if ( ! $args ) { /** This filter is documented in wp-includes/theme.php */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } switch ( $feature ) { case 'post-thumbnails': /* * post-thumbnails can be registered for only certain content/post types * by passing an array of types to add_theme_support(). * If no array was passed, then any type is accepted. */ if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types. return true; } $content_type = $args[0]; return in_array( $content_type, $_wp_theme_features[ $feature ][0], true ); case 'html5': case 'post-formats': /* * Specific post formats can be registered by passing an array of types * to add_theme_support(). * * Specific areas of HTML5 support *must* be passed via an array to add_theme_support(). */ $type = $args[0]; return in_array( $type, $_wp_theme_features[ $feature ][0], true ); case 'custom-logo': case 'custom-header': case 'custom-background': // Specific capabilities can be registered by passing an array to add_theme_support(). return ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) && $_wp_theme_features[ $feature ][0][ $args[0] ] ); } /** * Filters whether the active theme supports a specific feature. * * The dynamic portion of the hook name, `$feature`, refers to the specific * theme feature. See add_theme_support() for the list of possible values. * * @since 3.4.0 * * @param bool $supports Whether the active theme supports the given feature. Default true. * @param array $args Array of arguments for the feature. * @param string $feature The theme feature. */ return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } /** * Checks a theme's support for a given feature before loading the functions which implement it. * * @since 2.9.0 * * @param string $feature The feature being checked. See add_theme_support() for the list * of possible values. * @param string $file Path to the file. * @return bool True if the active theme supports the supplied feature, false otherwise. */ function require_if_theme_supports( $feature, $file ) { if ( current_theme_supports( $feature ) ) { require $file; return true; } return false; } /** * Registers a theme feature for use in add_theme_support(). * * This does not indicate that the active theme supports the feature, it only describes * the feature's supported options. * * @since 5.5.0 * * @see add_theme_support() * * @global array $_wp_registered_theme_features * * @param string $feature The name uniquely identifying the feature. See add_theme_support() * for the list of possible values. * @param array $args { * Data used to describe the theme. * * @type string $type The type of data associated with this feature. * Valid values are 'string', 'boolean', 'integer', * 'number', 'array', and 'object'. Defaults to 'boolean'. * @type bool $variadic Does this feature utilize the variadic support * of add_theme_support(), or are all arguments specified * as the second parameter. Must be used with the "array" type. * @type string $description A short description of the feature. Included in * the Themes REST API schema. Intended for developers. * @type bool|array $show_in_rest { * Whether this feature should be included in the Themes REST API endpoint. * Defaults to not being included. When registering an 'array' or 'object' type, * this argument must be an array with the 'schema' key. * * @type array $schema Specifies the JSON Schema definition describing * the feature. If any objects in the schema do not include * the 'additionalProperties' keyword, it is set to false. * @type string $name An alternate name to be used as the property name * in the REST API. * @type callable $prepare_callback A function used to format the theme support in the REST API. * Receives the raw theme support value. * } * } * @return true|WP_Error True if the theme feature was successfully registered, a WP_Error object if not. */ function register_theme_feature( $feature, $args = array() ) { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { $_wp_registered_theme_features = array(); } $defaults = array( 'type' => 'boolean', 'variadic' => false, 'description' => '', 'show_in_rest' => false, ); $args = wp_parse_args( $args, $defaults ); if ( true === $args['show_in_rest'] ) { $args['show_in_rest'] = array(); } if ( is_array( $args['show_in_rest'] ) ) { $args['show_in_rest'] = wp_parse_args( $args['show_in_rest'], array( 'schema' => array(), 'name' => $feature, 'prepare_callback' => null, ) ); } if ( ! in_array( $args['type'], array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { return new WP_Error( 'invalid_type', __( 'The feature "type" is not valid JSON Schema type.' ) ); } if ( true === $args['variadic'] && 'array' !== $args['type'] ) { return new WP_Error( 'variadic_must_be_array', __( 'When registering a "variadic" theme feature, the "type" must be an "array".' ) ); } if ( false !== $args['show_in_rest'] && in_array( $args['type'], array( 'array', 'object' ), true ) ) { if ( ! is_array( $args['show_in_rest'] ) || empty( $args['show_in_rest']['schema'] ) ) { return new WP_Error( 'missing_schema', __( 'When registering an "array" or "object" feature to show in the REST API, the feature\'s schema must also be defined.' ) ); } if ( 'array' === $args['type'] && ! isset( $args['show_in_rest']['schema']['items'] ) ) { return new WP_Error( 'missing_schema_items', __( 'When registering an "array" feature, the feature\'s schema must include the "items" keyword.' ) ); } if ( 'object' === $args['type'] && ! isset( $args['show_in_rest']['schema']['properties'] ) ) { return new WP_Error( 'missing_schema_properties', __( 'When registering an "object" feature, the feature\'s schema must include the "properties" keyword.' ) ); } } if ( is_array( $args['show_in_rest'] ) ) { if ( isset( $args['show_in_rest']['prepare_callback'] ) && ! is_callable( $args['show_in_rest']['prepare_callback'] ) ) { return new WP_Error( 'invalid_rest_prepare_callback', sprintf( /* translators: %s: prepare_callback */ __( 'The "%s" must be a callable function.' ), 'prepare_callback' ) ); } $args['show_in_rest']['schema'] = wp_parse_args( $args['show_in_rest']['schema'], array( 'description' => $args['description'], 'type' => $args['type'], 'default' => false, ) ); if ( is_bool( $args['show_in_rest']['schema']['default'] ) && ! in_array( 'boolean', (array) $args['show_in_rest']['schema']['type'], true ) ) { // Automatically include the "boolean" type when the default value is a boolean. $args['show_in_rest']['schema']['type'] = (array) $args['show_in_rest']['schema']['type']; array_unshift( $args['show_in_rest']['schema']['type'], 'boolean' ); } $args['show_in_rest']['schema'] = rest_default_additional_properties_to_false( $args['show_in_rest']['schema'] ); } $_wp_registered_theme_features[ $feature ] = $args; return true; } /** * Gets the list of registered theme features. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @return array[] List of theme features, keyed by their name. */ function get_registered_theme_features() { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return array(); } return $_wp_registered_theme_features; } /** * Gets the registration config for a theme feature. * * @since 5.5.0 * * @global array $_wp_registered_theme_features * * @param string $feature The feature name. See add_theme_support() for the list * of possible values. * @return array|null The registration args, or null if the feature was not registered. */ function get_registered_theme_feature( $feature ) { global $_wp_registered_theme_features; if ( ! is_array( $_wp_registered_theme_features ) ) { return null; } return isset( $_wp_registered_theme_features[ $feature ] ) ? $_wp_registered_theme_features[ $feature ] : null; } /** * Checks an attachment being deleted to see if it's a header or background image. * * If true it removes the theme modification which would be pointing at the deleted * attachment. * * @access private * @since 3.0.0 * @since 4.3.0 Also removes `header_image_data`. * @since 4.5.0 Also removes custom logo theme mods. * @since 6.6.0 Also removes `site_logo` option set by the site logo block. * * @param int $id The attachment ID. */ function _delete_attachment_theme_mod( $id ) { $attachment_image = wp_get_attachment_url( $id ); $header_image = get_header_image(); $background_image = get_background_image(); $custom_logo_id = (int) get_theme_mod( 'custom_logo' ); $site_logo_id = (int) get_option( 'site_logo' ); if ( $custom_logo_id && $custom_logo_id === $id ) { remove_theme_mod( 'custom_logo' ); remove_theme_mod( 'header_text' ); } if ( $site_logo_id && $site_logo_id === $id ) { delete_option( 'site_logo' ); } if ( $header_image && $header_image === $attachment_image ) { remove_theme_mod( 'header_image' ); remove_theme_mod( 'header_image_data' ); } if ( $background_image && $background_image === $attachment_image ) { remove_theme_mod( 'background_image' ); } } /** * Checks if a theme has been changed and runs 'after_switch_theme' hook on the next WP load. * * See {@see 'after_switch_theme'}. * * @since 3.3.0 */ function check_theme_switched() { $stylesheet = get_option( 'theme_switched' ); if ( $stylesheet ) { $old_theme = wp_get_theme( $stylesheet ); // Prevent widget & menu mapping from running since Customizer already called it up front. if ( get_option( 'theme_switched_via_customizer' ) ) { remove_action( 'after_switch_theme', '_wp_menus_changed' ); remove_action( 'after_switch_theme', '_wp_sidebars_changed' ); update_option( 'theme_switched_via_customizer', false ); } if ( $old_theme->exists() ) { /** * Fires on the next WP load after the theme has been switched. * * The parameters differ according to whether the old theme exists or not. * If the old theme is missing, the old name will instead be the slug * of the old theme. * * See {@see 'switch_theme'}. * * @since 3.3.0 * * @param string $old_name Old theme name. * @param WP_Theme $old_theme WP_Theme instance of the old theme. */ do_action( 'after_switch_theme', $old_theme->get( 'Name' ), $old_theme ); } else { /** This action is documented in wp-includes/theme.php */ do_action( 'after_switch_theme', $stylesheet, $old_theme ); } flush_rewrite_rules(); update_option( 'theme_switched', false ); } } /** * Includes and instantiates the WP_Customize_Manager class. * * Loads the Customizer at plugins_loaded when accessing the customize.php admin * page or when any request includes a wp_customize=on param or a customize_changeset * param (a UUID). This param is a signal for whether to bootstrap the Customizer when * WordPress is loading, especially in the Customizer preview * or when making Customizer Ajax requests for widgets or menus. * * @since 3.4.0 * * @global WP_Customize_Manager $wp_customize */ function _wp_customize_include() { $is_customize_admin_page = ( is_admin() && 'customize.php' === basename( $_SERVER['PHP_SELF'] ) ); $should_include = ( $is_customize_admin_page || ( isset( $_REQUEST['wp_customize'] ) && 'on' === $_REQUEST['wp_customize'] ) || ( ! empty( $_GET['customize_changeset_uuid'] ) || ! empty( $_POST['customize_changeset_uuid'] ) ) ); if ( ! $should_include ) { return; } /* * Note that wp_unslash() is not being used on the input vars because it is * called before wp_magic_quotes() gets called. Besides this fact, none of * the values should contain any characters needing slashes anyway. */ $keys = array( 'changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel', 'customize_autosaved', ); $input_vars = array_merge( wp_array_slice_assoc( $_GET, $keys ), wp_array_slice_assoc( $_POST, $keys ) ); $theme = null; $autosaved = null; $messenger_channel = null; /* * Value false indicates UUID should be determined after_setup_theme * to either re-use existing saved changeset or else generate a new UUID if none exists. */ $changeset_uuid = false; /* * Set initially to false since defaults to true for back-compat; * can be overridden via the customize_changeset_branching filter. */ $branching = false; if ( $is_customize_admin_page && isset( $input_vars['changeset_uuid'] ) ) { $changeset_uuid = sanitize_key( $input_vars['changeset_uuid'] ); } elseif ( ! empty( $input_vars['customize_changeset_uuid'] ) ) { $changeset_uuid = sanitize_key( $input_vars['customize_changeset_uuid'] ); } // Note that theme will be sanitized via WP_Theme. if ( $is_customize_admin_page && isset( $input_vars['theme'] ) ) { $theme = $input_vars['theme']; } elseif ( isset( $input_vars['customize_theme'] ) ) { $theme = $input_vars['customize_theme']; } if ( ! empty( $input_vars['customize_autosaved'] ) ) { $autosaved = true; } if ( isset( $input_vars['customize_messenger_channel'] ) ) { $messenger_channel = sanitize_key( $input_vars['customize_messenger_channel'] ); } /* * Note that settings must be previewed even outside the customizer preview * and also in the customizer pane itself. This is to enable loading an existing * changeset into the customizer. Previewing the settings only has to be prevented * here in the case of a customize_save action because this will cause WP to think * there is nothing changed that needs to be saved. */ $is_customize_save_action = ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && 'customize_save' === wp_unslash( $_REQUEST['action'] ) ); $settings_previewed = ! $is_customize_save_action; require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; $GLOBALS['wp_customize'] = new WP_Customize_Manager( compact( 'changeset_uuid', 'theme', 'messenger_channel', 'settings_previewed', 'autosaved', 'branching' ) ); } /** * Publishes a snapshot's changes. * * @since 4.7.0 * @access private * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @param string $new_status New post status. * @param string $old_status Old post status. * @param WP_Post $changeset_post Changeset post object. */ function _wp_customize_publish_changeset( $new_status, $old_status, $changeset_post ) { global $wp_customize; $is_publishing_changeset = ( 'customize_changeset' === $changeset_post->post_type && 'publish' === $new_status && 'publish' !== $old_status ); if ( ! $is_publishing_changeset ) { return; } if ( empty( $wp_customize ) ) { require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; $wp_customize = new WP_Customize_Manager( array( 'changeset_uuid' => $changeset_post->post_name, 'settings_previewed' => false, ) ); } if ( ! did_action( 'customize_register' ) ) { /* * When running from CLI or Cron, the customize_register action will need * to be triggered in order for core, themes, and plugins to register their * settings. Normally core will add_action( 'customize_register' ) at * priority 10 to register the core settings, and if any themes/plugins * also add_action( 'customize_register' ) at the same priority, they * will have a $wp_customize with those settings registered since they * call add_action() afterward, normally. However, when manually doing * the customize_register action after the setup_theme, then the order * will be reversed for two actions added at priority 10, resulting in * the core settings no longer being available as expected to themes/plugins. * So the following manually calls the method that registers the core * settings up front before doing the action. */ remove_action( 'customize_register', array( $wp_customize, 'register_controls' ) ); $wp_customize->register_controls(); /** This filter is documented in wp-includes/class-wp-customize-manager.php */ do_action( 'customize_register', $wp_customize ); } $wp_customize->_publish_changeset_values( $changeset_post->ID ); /* * Trash the changeset post if revisions are not enabled. Unpublished * changesets by default get garbage collected due to the auto-draft status. * When a changeset post is published, however, it would no longer get cleaned * out. This is a problem when the changeset posts are never displayed anywhere, * since they would just be endlessly piling up. So here we use the revisions * feature to indicate whether or not a published changeset should get trashed * and thus garbage collected. */ if ( ! wp_revisions_enabled( $changeset_post ) ) { $wp_customize->trash_changeset_post( $changeset_post->ID ); } } /** * Filters changeset post data upon insert to ensure post_name is intact. * * This is needed to prevent the post_name from being dropped when the post is * transitioned into pending status by a contributor. * * @since 4.7.0 * * @see wp_insert_post() * * @param array $post_data An array of slashed post data. * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data. * @return array Filtered data. */ function _wp_customize_changeset_filter_insert_post_data( $post_data, $supplied_post_data ) { if ( isset( $post_data['post_type'] ) && 'customize_changeset' === $post_data['post_type'] ) { // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending. if ( empty( $post_data['post_name'] ) && ! empty( $supplied_post_data['post_name'] ) ) { $post_data['post_name'] = $supplied_post_data['post_name']; } } return $post_data; } /** * Adds settings for the customize-loader script. * * @since 3.4.0 */ function _wp_customize_loader_settings() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $cross_domain = ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) ); $browser = array( 'mobile' => wp_is_mobile(), 'ios' => wp_is_mobile() && preg_match( '/iPad|iPod|iPhone/', $_SERVER['HTTP_USER_AGENT'] ), ); $settings = array( 'url' => esc_url( admin_url( 'customize.php' ) ), 'isCrossDomain' => $cross_domain, 'browser' => $browser, 'l10n' => array( 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.' ), 'mainIframeTitle' => __( 'Customizer' ), ), ); $script = 'var _wpCustomizeLoaderSettings = ' . wp_json_encode( $settings ) . ';'; $wp_scripts = wp_scripts(); $data = $wp_scripts->get_data( 'customize-loader', 'data' ); if ( $data ) { $script = "$data\n$script"; } $wp_scripts->add_data( 'customize-loader', 'data', $script ); } /** * Returns a URL to load the Customizer. * * @since 3.4.0 * * @param string $stylesheet Optional. Theme to customize. Defaults to active theme. * The theme's stylesheet will be urlencoded if necessary. * @return string */ function wp_customize_url( $stylesheet = '' ) { $url = admin_url( 'customize.php' ); if ( $stylesheet ) { $url .= '?theme=' . urlencode( $stylesheet ); } return esc_url( $url ); } /** * Prints a script to check whether or not the Customizer is supported, * and apply either the no-customize-support or customize-support class * to the body. * * This function MUST be called inside the body tag. * * Ideally, call this function immediately after the body tag is opened. * This prevents a flash of unstyled content. * * It is also recommended that you add the "no-customize-support" class * to the body tag by default. * * @since 3.4.0 * @since 4.7.0 Support for IE8 and below is explicitly removed via conditional comments. * @since 5.5.0 IE8 and older are no longer supported. */ function wp_customize_support_script() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $cross_domain = ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) ); ob_start(); ?> <script> (function() { var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)'); <?php if ( $cross_domain ) : ?> request = (function(){ var xhr = new XMLHttpRequest(); return ('withCredentials' in xhr); })(); <?php else : ?> request = true; <?php endif; ?> b[c] = b[c].replace( rcs, ' ' ); // The customizer requires postMessage and CORS (if the site is cross domain). b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs; }()); </script> <?php wp_print_inline_script_tag( wp_remove_surrounding_empty_script_tags( ob_get_clean() ) ); } /** * Whether the site is being previewed in the Customizer. * * @since 4.0.0 * * @global WP_Customize_Manager $wp_customize Customizer instance. * * @return bool True if the site is being previewed in the Customizer, false otherwise. */ function is_customize_preview() { global $wp_customize; return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); } /** * Makes sure that auto-draft posts get their post_date bumped or status changed * to draft to prevent premature garbage-collection. * * When a changeset is updated but remains an auto-draft, ensure the post_date * for the auto-draft posts remains the same so that it will be * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, * if the changeset is updated to be a draft then update the posts * to have a far-future post_date so that they will never be garbage collected * unless the changeset post itself is deleted. * * When a changeset is updated to be a persistent draft or to be scheduled for * publishing, then transition any dependent auto-drafts to a draft status so * that they likewise will not be garbage-collected but also so that they can * be edited in the admin before publishing since there is not yet a post/page * editing flow in the Customizer. See #39752. * * @link https://core.trac.wordpress.org/ticket/39752 * * @since 4.8.0 * @access private * @see wp_delete_auto_drafts() * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $new_status Transition to this post status. * @param string $old_status Previous post status. * @param \WP_Post $post Post data. */ function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { global $wpdb; unset( $old_status ); // Short-circuit if not a changeset or if the changeset was published. if ( 'customize_changeset' !== $post->post_type || 'publish' === $new_status ) { return; } $data = json_decode( $post->post_content, true ); if ( empty( $data['nav_menus_created_posts']['value'] ) ) { return; } /* * Actually, in lieu of keeping alive, trash any customization drafts here if the changeset itself is * getting trashed. This is needed because when a changeset transitions to a draft, then any of the * dependent auto-draft post/page stubs will also get transitioned to customization drafts which * are then visible in the WP Admin. We cannot wait for the deletion of the changeset in which * _wp_delete_customize_changeset_dependent_auto_drafts() will be called, since they need to be * trashed to remove from visibility immediately. */ if ( 'trash' === $new_status ) { foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { if ( ! empty( $post_id ) && 'draft' === get_post_status( $post_id ) ) { wp_trash_post( $post_id ); } } return; } $post_args = array(); if ( 'auto-draft' === $new_status ) { /* * Keep the post date for the post matching the changeset * so that it will not be garbage-collected before the changeset. */ $post_args['post_date'] = $post->post_date; // Note wp_delete_auto_drafts() only looks at this date. } else { /* * Since the changeset no longer has an auto-draft (and it is not published) * it is now a persistent changeset, a long-lived draft, and so any * associated auto-draft posts should likewise transition into having a draft * status. These drafts will be treated differently than regular drafts in * that they will be tied to the given changeset. The publish meta box is * replaced with a notice about how the post is part of a set of customized changes * which will be published when the changeset is published. */ $post_args['post_status'] = 'draft'; } foreach ( $data['nav_menus_created_posts']['value'] as $post_id ) { if ( empty( $post_id ) || 'auto-draft' !== get_post_status( $post_id ) ) { continue; } $wpdb->update( $wpdb->posts, $post_args, array( 'ID' => $post_id ) ); clean_post_cache( $post_id ); } } /** * Creates the initial theme features when the 'setup_theme' action is fired. * * See {@see 'setup_theme'}. * * @since 5.5.0 * @since 6.0.1 The `block-templates` feature was added. */ function create_initial_theme_features() { register_theme_feature( 'align-wide', array( 'description' => __( 'Whether theme opts in to wide alignment CSS class.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'automatic-feed-links', array( 'description' => __( 'Whether posts and comments RSS feed links are added to head.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'block-templates', array( 'description' => __( 'Whether a theme uses block-based templates.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'block-template-parts', array( 'description' => __( 'Whether a theme uses block-based template parts.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'custom-background', array( 'description' => __( 'Custom background if defined by the theme.' ), 'type' => 'object', 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'default-image' => array( 'type' => 'string', 'format' => 'uri', ), 'default-preset' => array( 'type' => 'string', 'enum' => array( 'default', 'fill', 'fit', 'repeat', 'custom', ), ), 'default-position-x' => array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', ), ), 'default-position-y' => array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', ), ), 'default-size' => array( 'type' => 'string', 'enum' => array( 'auto', 'contain', 'cover', ), ), 'default-repeat' => array( 'type' => 'string', 'enum' => array( 'repeat-x', 'repeat-y', 'repeat', 'no-repeat', ), ), 'default-attachment' => array( 'type' => 'string', 'enum' => array( 'scroll', 'fixed', ), ), 'default-color' => array( 'type' => 'string', ), ), ), ), ) ); register_theme_feature( 'custom-header', array( 'description' => __( 'Custom header if defined by the theme.' ), 'type' => 'object', 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'default-image' => array( 'type' => 'string', 'format' => 'uri', ), 'random-default' => array( 'type' => 'boolean', ), 'width' => array( 'type' => 'integer', ), 'height' => array( 'type' => 'integer', ), 'flex-height' => array( 'type' => 'boolean', ), 'flex-width' => array( 'type' => 'boolean', ), 'default-text-color' => array( 'type' => 'string', ), 'header-text' => array( 'type' => 'boolean', ), 'uploads' => array( 'type' => 'boolean', ), 'video' => array( 'type' => 'boolean', ), ), ), ), ) ); register_theme_feature( 'custom-logo', array( 'type' => 'object', 'description' => __( 'Custom logo if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'properties' => array( 'width' => array( 'type' => 'integer', ), 'height' => array( 'type' => 'integer', ), 'flex-width' => array( 'type' => 'boolean', ), 'flex-height' => array( 'type' => 'boolean', ), 'header-text' => array( 'type' => 'array', 'items' => array( 'type' => 'string', ), ), 'unlink-homepage-logo' => array( 'type' => 'boolean', ), ), ), ), ) ); register_theme_feature( 'customize-selective-refresh-widgets', array( 'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'dark-editor-style', array( 'description' => __( 'Whether theme opts in to the dark editor style UI.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-colors', array( 'description' => __( 'Whether the theme disables custom colors.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-font-sizes', array( 'description' => __( 'Whether the theme disables custom font sizes.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-custom-gradients', array( 'description' => __( 'Whether the theme disables custom gradients.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'disable-layout-styles', array( 'description' => __( 'Whether the theme disables generated layout styles.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'editor-color-palette', array( 'type' => 'array', 'description' => __( 'Custom color palette if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), 'color' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-font-sizes', array( 'type' => 'array', 'description' => __( 'Custom font sizes if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'size' => array( 'type' => 'number', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-gradient-presets', array( 'type' => 'array', 'description' => __( 'Custom gradient presets if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'gradient' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-spacing-sizes', array( 'type' => 'array', 'description' => __( 'Custom spacing sizes if defined by the theme.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'type' => 'string', ), 'size' => array( 'type' => 'string', ), 'slug' => array( 'type' => 'string', ), ), ), ), ), ) ); register_theme_feature( 'editor-styles', array( 'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'html5', array( 'type' => 'array', 'description' => __( 'Allows use of HTML5 markup for search forms, comment forms, comment lists, gallery, and caption.' ), 'show_in_rest' => array( 'schema' => array( 'items' => array( 'type' => 'string', 'enum' => array( 'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'script', 'style', ), ), ), ), ) ); register_theme_feature( 'post-formats', array( 'type' => 'array', 'description' => __( 'Post formats supported.' ), 'show_in_rest' => array( 'name' => 'formats', 'schema' => array( 'items' => array( 'type' => 'string', 'enum' => get_post_format_slugs(), ), 'default' => array( 'standard' ), ), 'prepare_callback' => static function ( $formats ) { $formats = is_array( $formats ) ? array_values( $formats[0] ) : array(); $formats = array_merge( array( 'standard' ), $formats ); return $formats; }, ), ) ); register_theme_feature( 'post-thumbnails', array( 'type' => 'array', 'description' => __( 'The post types that support thumbnails or true if all post types are supported.' ), 'show_in_rest' => array( 'type' => array( 'boolean', 'array' ), 'schema' => array( 'items' => array( 'type' => 'string', ), ), ), ) ); register_theme_feature( 'responsive-embeds', array( 'description' => __( 'Whether the theme supports responsive embedded content.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'title-tag', array( 'description' => __( 'Whether the theme can manage the document title tag.' ), 'show_in_rest' => true, ) ); register_theme_feature( 'wp-block-styles', array( 'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ), 'show_in_rest' => true, ) ); } /** * Returns whether the active theme is a block-based theme or not. * * @since 5.9.0 * * @return bool Whether the active theme is a block-based theme or not. */ function wp_is_block_theme() { if ( empty( $GLOBALS['wp_theme_directories'] ) ) { _doing_it_wrong( __FUNCTION__, __( 'This function should not be called before the theme directory is registered.' ), '6.8.0' ); return false; } return wp_get_theme()->is_block_theme(); } /** * Given an element name, returns a class name. * * Alias of WP_Theme_JSON::get_element_class_name. * * @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 ) { return WP_Theme_JSON::get_element_class_name( $element ); } /** * Adds default theme supports for block themes when the 'after_setup_theme' action fires. * * See {@see 'after_setup_theme'}. * * @since 5.9.0 * @access private */ function _add_default_theme_supports() { if ( ! wp_is_block_theme() ) { return; } add_theme_support( 'post-thumbnails' ); add_theme_support( 'responsive-embeds' ); add_theme_support( 'editor-styles' ); /* * Makes block themes support HTML5 by default for the comment block and search form * (which use default template functions) and `[caption]` and `[gallery]` shortcodes. * Other blocks contain their own HTML5 markup. */ add_theme_support( 'html5', array( 'comment-form', 'comment-list', 'search-form', 'gallery', 'caption', 'style', 'script' ) ); add_theme_support( 'automatic-feed-links' ); add_filter( 'should_load_separate_core_block_assets', '__return_true' ); add_filter( 'should_load_block_assets_on_demand', '__return_true' ); /* * Remove the Customizer's Menus panel when block theme is active. */ add_filter( 'customize_panel_active', static function ( $active, WP_Customize_Panel $panel ) { if ( 'nav_menus' === $panel->id && ! current_theme_supports( 'menus' ) && ! current_theme_supports( 'widgets' ) ) { $active = false; } return $active; }, 10, 2 ); } <?php /** * Class for a set of entries for translation and their associated headers * * @version $Id: translations.php 1157 2015-11-20 04:30:11Z dd32 $ * @package pomo * @subpackage translations * @since 2.8.0 */ require_once __DIR__ . '/plural-forms.php'; require_once __DIR__ . '/entry.php'; if ( ! class_exists( 'Translations', false ) ) : /** * Translations class. * * @since 2.8.0 */ #[AllowDynamicProperties] class Translations { /** * List of translation entries. * * @since 2.8.0 * * @var Translation_Entry[] */ public $entries = array(); /** * List of translation headers. * * @since 2.8.0 * * @var array<string, string> */ public $headers = array(); /** * Adds an entry to the PO structure. * * @since 2.8.0 * * @param array|Translation_Entry $entry * @return bool True on success, false if the entry doesn't have a key. */ public function add_entry( $entry ) { if ( is_array( $entry ) ) { $entry = new Translation_Entry( $entry ); } $key = $entry->key(); if ( false === $key ) { return false; } $this->entries[ $key ] = &$entry; return true; } /** * Adds or merges an entry to the PO structure. * * @since 2.8.0 * * @param array|Translation_Entry $entry * @return bool True on success, false if the entry doesn't have a key. */ public function add_entry_or_merge( $entry ) { if ( is_array( $entry ) ) { $entry = new Translation_Entry( $entry ); } $key = $entry->key(); if ( false === $key ) { return false; } if ( isset( $this->entries[ $key ] ) ) { $this->entries[ $key ]->merge_with( $entry ); } else { $this->entries[ $key ] = &$entry; } return true; } /** * Sets $header PO header to $value * * If the header already exists, it will be overwritten * * TODO: this should be out of this class, it is gettext specific * * @since 2.8.0 * * @param string $header header name, without trailing : * @param string $value header value, without trailing \n */ public function set_header( $header, $value ) { $this->headers[ $header ] = $value; } /** * Sets translation headers. * * @since 2.8.0 * * @param array $headers Associative array of headers. */ public function set_headers( $headers ) { foreach ( $headers as $header => $value ) { $this->set_header( $header, $value ); } } /** * Returns a given translation header. * * @since 2.8.0 * * @param string $header * @return string|false Header if it exists, false otherwise. */ public function get_header( $header ) { return isset( $this->headers[ $header ] ) ? $this->headers[ $header ] : false; } /** * Returns a given translation entry. * * @since 2.8.0 * * @param Translation_Entry $entry Translation entry. * @return Translation_Entry|false Translation entry if it exists, false otherwise. */ public function translate_entry( &$entry ) { $key = $entry->key(); return isset( $this->entries[ $key ] ) ? $this->entries[ $key ] : false; } /** * Translates a singular string. * * @since 2.8.0 * * @param string $singular * @param string $context * @return string */ public function translate( $singular, $context = null ) { $entry = new Translation_Entry( array( 'singular' => $singular, 'context' => $context, ) ); $translated = $this->translate_entry( $entry ); return ( $translated && ! empty( $translated->translations ) ) ? $translated->translations[0] : $singular; } /** * Given the number of items, returns the 0-based index of the plural form to use * * Here, in the base Translations class, the common logic for English is implemented: * 0 if there is one element, 1 otherwise * * This function should be overridden by the subclasses. For example MO/PO can derive the logic * from their headers. * * @since 2.8.0 * * @param int $count Number of items. * @return int Plural form to use. */ public function select_plural_form( $count ) { return 1 === (int) $count ? 0 : 1; } /** * Returns the plural forms count. * * @since 2.8.0 * * @return int Plural forms count. */ public function get_plural_forms_count() { return 2; } /** * Translates a plural string. * * @since 2.8.0 * * @param string $singular * @param string $plural * @param int $count * @param string $context * @return string */ public function translate_plural( $singular, $plural, $count, $context = null ) { $entry = new Translation_Entry( array( 'singular' => $singular, 'plural' => $plural, 'context' => $context, ) ); $translated = $this->translate_entry( $entry ); $index = $this->select_plural_form( $count ); $total_plural_forms = $this->get_plural_forms_count(); if ( $translated && 0 <= $index && $index < $total_plural_forms && is_array( $translated->translations ) && isset( $translated->translations[ $index ] ) ) { return $translated->translations[ $index ]; } else { return 1 === (int) $count ? $singular : $plural; } } /** * Merges other translations into the current one. * * @since 2.8.0 * * @param Translations $other Another Translation object, whose translations will be merged in this one (passed by reference). */ public function merge_with( &$other ) { foreach ( $other->entries as $entry ) { $this->entries[ $entry->key() ] = $entry; } } /** * Merges originals with existing entries. * * @since 2.8.0 * * @param Translations $other */ public function merge_originals_with( &$other ) { foreach ( $other->entries as $entry ) { if ( ! isset( $this->entries[ $entry->key() ] ) ) { $this->entries[ $entry->key() ] = $entry; } else { $this->entries[ $entry->key() ]->merge_with( $entry ); } } } } /** * Gettext_Translations class. * * @since 2.8.0 */ class Gettext_Translations extends Translations { /** * Number of plural forms. * * @var int * * @since 2.8.0 */ public $_nplurals; /** * Callback to retrieve the plural form. * * @var callable * * @since 2.8.0 */ public $_gettext_select_plural_form; /** * The gettext implementation of select_plural_form. * * It lives in this class, because there are more than one descendant, which will use it and * they can't share it effectively. * * @since 2.8.0 * * @param int $count Plural forms count. * @return int Plural form to use. */ public function gettext_select_plural_form( $count ) { if ( ! isset( $this->_gettext_select_plural_form ) || is_null( $this->_gettext_select_plural_form ) ) { list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) ); $this->_nplurals = $nplurals; $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression ); } return call_user_func( $this->_gettext_select_plural_form, $count ); } /** * Returns the nplurals and plural forms expression from the Plural-Forms header. * * @since 2.8.0 * * @param string $header * @return array{0: int, 1: string} */ public function nplurals_and_expression_from_header( $header ) { if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) { $nplurals = (int) $matches[1]; $expression = trim( $matches[2] ); return array( $nplurals, $expression ); } else { return array( 2, 'n != 1' ); } } /** * Makes a function, which will return the right translation index, according to the * plural forms header. * * @since 2.8.0 * * @param int $nplurals * @param string $expression * @return callable */ public function make_plural_form_function( $nplurals, $expression ) { try { $handler = new Plural_Forms( rtrim( $expression, ';' ) ); return array( $handler, 'get' ); } catch ( Exception $e ) { // Fall back to default plural-form function. return $this->make_plural_form_function( 2, 'n != 1' ); } } /** * Adds parentheses to the inner parts of ternary operators in * plural expressions, because PHP evaluates ternary operators from left to right * * @since 2.8.0 * @deprecated 6.5.0 Use the Plural_Forms class instead. * * @see Plural_Forms * * @param string $expression the expression without parentheses * @return string the expression with parentheses added */ public function parenthesize_plural_exression( $expression ) { $expression .= ';'; $res = ''; $depth = 0; for ( $i = 0; $i < strlen( $expression ); ++$i ) { $char = $expression[ $i ]; switch ( $char ) { case '?': $res .= ' ? ('; ++$depth; break; case ':': $res .= ') : ('; break; case ';': $res .= str_repeat( ')', $depth ) . ';'; $depth = 0; break; default: $res .= $char; } } return rtrim( $res, ';' ); } /** * Prepare translation headers. * * @since 2.8.0 * * @param string $translation * @return array<string, string> Translation headers */ public function make_headers( $translation ) { $headers = array(); // Sometimes \n's are used instead of real new lines. $translation = str_replace( '\n', "\n", $translation ); $lines = explode( "\n", $translation ); foreach ( $lines as $line ) { $parts = explode( ':', $line, 2 ); if ( ! isset( $parts[1] ) ) { continue; } $headers[ trim( $parts[0] ) ] = trim( $parts[1] ); } return $headers; } /** * Sets translation headers. * * @since 2.8.0 * * @param string $header * @param string $value */ public function set_header( $header, $value ) { parent::set_header( $header, $value ); if ( 'Plural-Forms' === $header ) { list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) ); $this->_nplurals = $nplurals; $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression ); } } } endif; if ( ! class_exists( 'NOOP_Translations', false ) ) : /** * Provides the same interface as Translations, but doesn't do anything. * * @since 2.8.0 */ #[AllowDynamicProperties] class NOOP_Translations { /** * List of translation entries. * * @since 2.8.0 * * @var Translation_Entry[] */ public $entries = array(); /** * List of translation headers. * * @since 2.8.0 * * @var array<string, string> */ public $headers = array(); public function add_entry( $entry ) { return true; } /** * Sets a translation header. * * @since 2.8.0 * * @param string $header * @param string $value */ public function set_header( $header, $value ) { } /** * Sets translation headers. * * @since 2.8.0 * * @param array $headers */ public function set_headers( $headers ) { } /** * Returns a translation header. * * @since 2.8.0 * * @param string $header * @return false */ public function get_header( $header ) { return false; } /** * Returns a given translation entry. * * @since 2.8.0 * * @param Translation_Entry $entry * @return false */ public function translate_entry( &$entry ) { return false; } /** * Translates a singular string. * * @since 2.8.0 * * @param string $singular * @param string $context */ public function translate( $singular, $context = null ) { return $singular; } /** * Returns the plural form to use. * * @since 2.8.0 * * @param int $count * @return int */ public function select_plural_form( $count ) { return 1 === (int) $count ? 0 : 1; } /** * Returns the plural forms count. * * @since 2.8.0 * * @return int */ public function get_plural_forms_count() { return 2; } /** * Translates a plural string. * * @since 2.8.0 * * @param string $singular * @param string $plural * @param int $count * @param string $context * @return string */ public function translate_plural( $singular, $plural, $count, $context = null ) { return 1 === (int) $count ? $singular : $plural; } /** * Merges other translations into the current one. * * @since 2.8.0 * * @param Translations $other */ public function merge_with( &$other ) { } } endif; <?php /** * Script Modules API: Script Module functions * * @since 6.5.0 * * @package WordPress * @subpackage Script Modules */ /** * Retrieves the main WP_Script_Modules instance. * * This function provides access to the WP_Script_Modules instance, creating one * if it doesn't exist yet. * * @since 6.5.0 * * @global WP_Script_Modules $wp_script_modules * * @return WP_Script_Modules The main WP_Script_Modules instance. */ function wp_script_modules(): WP_Script_Modules { global $wp_script_modules; if ( ! ( $wp_script_modules instanceof WP_Script_Modules ) ) { $wp_script_modules = new WP_Script_Modules(); } return $wp_script_modules; } /** * Registers the script module if no script module with that script module * identifier has already been registered. * * @since 6.5.0 * * @param string $id The identifier of the script module. Should be unique. It will be used in the * final import map. * @param string $src Optional. Full URL of the script module, or path of the script module relative * to the WordPress root directory. If it is provided and the script module has * not been registered yet, it will be registered. * @param array $deps { * Optional. List of dependencies. * * @type string|array ...$0 { * An array of script module identifiers of the dependencies of this script * module. The dependencies can be strings or arrays. If they are arrays, * they need an `id` key with the script module identifier, and can contain * an `import` key with either `static` or `dynamic`. By default, * dependencies that don't contain an `import` key are considered static. * * @type string $id The script module identifier. * @type string $import Optional. Import type. May be either `static` or * `dynamic`. Defaults to `static`. * } * } * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false. * It is added to the URL as a query string for cache busting purposes. If $version * is set to false, the version number is the currently installed WordPress version. * If $version is set to null, no version is added. */ function wp_register_script_module( string $id, string $src, array $deps = array(), $version = false ) { wp_script_modules()->register( $id, $src, $deps, $version ); } /** * Marks the script module to be enqueued in the page. * * If a src is provided and the script module has not been registered yet, it * will be registered. * * @since 6.5.0 * * @param string $id The identifier of the script module. Should be unique. It will be used in the * final import map. * @param string $src Optional. Full URL of the script module, or path of the script module relative * to the WordPress root directory. If it is provided and the script module has * not been registered yet, it will be registered. * @param array $deps { * Optional. List of dependencies. * * @type string|array ...$0 { * An array of script module identifiers of the dependencies of this script * module. The dependencies can be strings or arrays. If they are arrays, * they need an `id` key with the script module identifier, and can contain * an `import` key with either `static` or `dynamic`. By default, * dependencies that don't contain an `import` key are considered static. * * @type string $id The script module identifier. * @type string $import Optional. Import type. May be either `static` or * `dynamic`. Defaults to `static`. * } * } * @param string|false|null $version Optional. String specifying the script module version number. Defaults to false. * It is added to the URL as a query string for cache busting purposes. If $version * is set to false, the version number is the currently installed WordPress version. * If $version is set to null, no version is added. */ function wp_enqueue_script_module( string $id, string $src = '', array $deps = array(), $version = false ) { wp_script_modules()->enqueue( $id, $src, $deps, $version ); } /** * Unmarks the script module so it is no longer enqueued in the page. * * @since 6.5.0 * * @param string $id The identifier of the script module. */ function wp_dequeue_script_module( string $id ) { wp_script_modules()->dequeue( $id ); } /** * Deregisters the script module. * * @since 6.5.0 * * @param string $id The identifier of the script module. */ function wp_deregister_script_module( string $id ) { wp_script_modules()->deregister( $id ); } /** * Registers all the default WordPress Script Modules. * * @since 6.7.0 */ function wp_default_script_modules() { $suffix = defined( 'WP_RUN_CORE_TESTS' ) ? '.min' : wp_scripts_get_suffix(); /* * Expects multidimensional array like: * * 'interactivity/index.min.js' => array('dependencies' => array(…), 'version' => '…'), * 'interactivity/debug.min.js' => array('dependencies' => array(…), 'version' => '…'), * 'interactivity-router/index.min.js' => … */ $assets = include ABSPATH . WPINC . "/assets/script-modules-packages{$suffix}.php"; foreach ( $assets as $file_name => $script_module_data ) { /* * Build the WordPress Script Module ID from the file name. * Prepend `@wordpress/` and remove extensions and `/index` if present: * - interactivity/index.min.js => @wordpress/interactivity * - interactivity/debug.min.js => @wordpress/interactivity/debug * - block-library/query/view.js => @wordpress/block-library/query/view */ $script_module_id = '@wordpress/' . preg_replace( '~(?:/index)?(?:\.min)?\.js$~D', '', $file_name, 1 ); switch ( $script_module_id ) { /* * Interactivity exposes two entrypoints, "/index" and "/debug". * "/debug" should replace "/index" in development. */ case '@wordpress/interactivity/debug': if ( ! SCRIPT_DEBUG ) { continue 2; } $script_module_id = '@wordpress/interactivity'; break; case '@wordpress/interactivity': if ( SCRIPT_DEBUG ) { continue 2; } break; } $path = includes_url( "js/dist/script-modules/{$file_name}" ); wp_register_script_module( $script_module_id, $path, $script_module_data['dependencies'], $script_module_data['version'] ); } } <?php /** * Link/Bookmark API * * @package WordPress * @subpackage Bookmark */ /** * Retrieves bookmark data. * * @since 2.1.0 * * @global object $link Current link object. * @global wpdb $wpdb WordPress database abstraction object. * * @param int|stdClass $bookmark * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which * correspond to an stdClass object, an associative array, or a numeric array, * respectively. Default OBJECT. * @param string $filter Optional. How to sanitize bookmark fields. Default 'raw'. * @return array|object|null Type returned depends on $output value. */ function get_bookmark( $bookmark, $output = OBJECT, $filter = 'raw' ) { global $wpdb; if ( empty( $bookmark ) ) { if ( isset( $GLOBALS['link'] ) ) { $_bookmark = & $GLOBALS['link']; } else { $_bookmark = null; } } elseif ( is_object( $bookmark ) ) { wp_cache_add( $bookmark->link_id, $bookmark, 'bookmark' ); $_bookmark = $bookmark; } else { if ( isset( $GLOBALS['link'] ) && ( $GLOBALS['link']->link_id === $bookmark ) ) { $_bookmark = & $GLOBALS['link']; } else { $_bookmark = wp_cache_get( $bookmark, 'bookmark' ); if ( ! $_bookmark ) { $_bookmark = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->links WHERE link_id = %d LIMIT 1", $bookmark ) ); if ( $_bookmark ) { $_bookmark->link_category = array_unique( wp_get_object_terms( $_bookmark->link_id, 'link_category', array( 'fields' => 'ids' ) ) ); wp_cache_add( $_bookmark->link_id, $_bookmark, 'bookmark' ); } } } } if ( ! $_bookmark ) { return $_bookmark; } $_bookmark = sanitize_bookmark( $_bookmark, $filter ); if ( OBJECT === $output ) { return $_bookmark; } elseif ( ARRAY_A === $output ) { return get_object_vars( $_bookmark ); } elseif ( ARRAY_N === $output ) { return array_values( get_object_vars( $_bookmark ) ); } else { return $_bookmark; } } /** * Retrieves single bookmark data item or field. * * @since 2.3.0 * * @param string $field The name of the data field to return. * @param int $bookmark The bookmark ID to get field. * @param string $context Optional. The context of how the field will be used. Default 'display'. * @return string|WP_Error */ function get_bookmark_field( $field, $bookmark, $context = 'display' ) { $bookmark = (int) $bookmark; $bookmark = get_bookmark( $bookmark ); if ( is_wp_error( $bookmark ) ) { return $bookmark; } if ( ! is_object( $bookmark ) ) { return ''; } if ( ! isset( $bookmark->$field ) ) { return ''; } return sanitize_bookmark_field( $field, $bookmark->$field, $bookmark->link_id, $context ); } /** * Retrieves the list of bookmarks. * * Attempts to retrieve from the cache first based on MD5 hash of arguments. If * that fails, then the query will be built from the arguments and executed. The * results will be stored to the cache. * * @since 2.1.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string|array $args { * Optional. String or array of arguments to retrieve bookmarks. * * @type string $orderby How to order the links by. Accepts 'id', 'link_id', 'name', 'link_name', * 'url', 'link_url', 'visible', 'link_visible', 'rating', 'link_rating', * 'owner', 'link_owner', 'updated', 'link_updated', 'notes', 'link_notes', * 'description', 'link_description', 'length' and 'rand'. * When `$orderby` is 'length', orders by the character length of * 'link_name'. Default 'name'. * @type string $order Whether to order bookmarks in ascending or descending order. * Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'. * @type int $limit Amount of bookmarks to display. Accepts any positive number or * -1 for all. Default -1. * @type string $category Comma-separated list of category IDs to include links from. * Default empty. * @type string $category_name Category to retrieve links for by name. Default empty. * @type int|bool $hide_invisible Whether to show or hide links marked as 'invisible'. Accepts * 1|true or 0|false. Default 1|true. * @type int|bool $show_updated Whether to display the time the bookmark was last updated. * Accepts 1|true or 0|false. Default 0|false. * @type string $include Comma-separated list of bookmark IDs to include. Default empty. * @type string $exclude Comma-separated list of bookmark IDs to exclude. Default empty. * @type string $search Search terms. Will be SQL-formatted with wildcards before and after * and searched in 'link_url', 'link_name' and 'link_description'. * Default empty. * } * @return object[] List of bookmark row objects. */ function get_bookmarks( $args = '' ) { global $wpdb; $defaults = array( 'orderby' => 'name', 'order' => 'ASC', 'limit' => -1, 'category' => '', 'category_name' => '', 'hide_invisible' => 1, 'show_updated' => 0, 'include' => '', 'exclude' => '', 'search' => '', ); $parsed_args = wp_parse_args( $args, $defaults ); $key = md5( serialize( $parsed_args ) ); $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ); if ( 'rand' !== $parsed_args['orderby'] && $cache ) { if ( is_array( $cache ) && isset( $cache[ $key ] ) ) { $bookmarks = $cache[ $key ]; /** * Filters the returned list of bookmarks. * * The first time the hook is evaluated in this file, it returns the cached * bookmarks list. The second evaluation returns a cached bookmarks list if the * link category is passed but does not exist. The third evaluation returns * the full cached results. * * @since 2.1.0 * * @see get_bookmarks() * * @param array $bookmarks List of the cached bookmarks. * @param array $parsed_args An array of bookmark query arguments. */ return apply_filters( 'get_bookmarks', $bookmarks, $parsed_args ); } } if ( ! is_array( $cache ) ) { $cache = array(); } $inclusions = ''; if ( ! empty( $parsed_args['include'] ) ) { $parsed_args['exclude'] = ''; // Ignore exclude, category, and category_name params if using include. $parsed_args['category'] = ''; $parsed_args['category_name'] = ''; $inclinks = wp_parse_id_list( $parsed_args['include'] ); if ( count( $inclinks ) ) { foreach ( $inclinks as $inclink ) { if ( empty( $inclusions ) ) { $inclusions = ' AND ( link_id = ' . $inclink . ' '; } else { $inclusions .= ' OR link_id = ' . $inclink . ' '; } } } } if ( ! empty( $inclusions ) ) { $inclusions .= ')'; } $exclusions = ''; if ( ! empty( $parsed_args['exclude'] ) ) { $exlinks = wp_parse_id_list( $parsed_args['exclude'] ); if ( count( $exlinks ) ) { foreach ( $exlinks as $exlink ) { if ( empty( $exclusions ) ) { $exclusions = ' AND ( link_id <> ' . $exlink . ' '; } else { $exclusions .= ' AND link_id <> ' . $exlink . ' '; } } } } if ( ! empty( $exclusions ) ) { $exclusions .= ')'; } if ( ! empty( $parsed_args['category_name'] ) ) { $parsed_args['category'] = get_term_by( 'name', $parsed_args['category_name'], 'link_category' ); if ( $parsed_args['category'] ) { $parsed_args['category'] = $parsed_args['category']->term_id; } else { $cache[ $key ] = array(); wp_cache_set( 'get_bookmarks', $cache, 'bookmark' ); /** This filter is documented in wp-includes/bookmark.php */ return apply_filters( 'get_bookmarks', array(), $parsed_args ); } } $search = ''; if ( ! empty( $parsed_args['search'] ) ) { $like = '%' . $wpdb->esc_like( $parsed_args['search'] ) . '%'; $search = $wpdb->prepare( ' AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ', $like, $like, $like ); } $category_query = ''; $join = ''; if ( ! empty( $parsed_args['category'] ) ) { $incategories = wp_parse_id_list( $parsed_args['category'] ); if ( count( $incategories ) ) { foreach ( $incategories as $incat ) { if ( empty( $category_query ) ) { $category_query = ' AND ( tt.term_id = ' . $incat . ' '; } else { $category_query .= ' OR tt.term_id = ' . $incat . ' '; } } } } if ( ! empty( $category_query ) ) { $category_query .= ") AND taxonomy = 'link_category'"; $join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id"; } if ( $parsed_args['show_updated'] ) { $recently_updated_test = ', IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated '; } else { $recently_updated_test = ''; } $get_updated = ( $parsed_args['show_updated'] ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : ''; $orderby = strtolower( $parsed_args['orderby'] ); $length = ''; switch ( $orderby ) { case 'length': $length = ', CHAR_LENGTH(link_name) AS length'; break; case 'rand': $orderby = 'rand()'; break; case 'link_id': $orderby = "$wpdb->links.link_id"; break; default: $orderparams = array(); $keys = array( 'link_id', 'link_name', 'link_url', 'link_visible', 'link_rating', 'link_owner', 'link_updated', 'link_notes', 'link_description' ); foreach ( explode( ',', $orderby ) as $ordparam ) { $ordparam = trim( $ordparam ); if ( in_array( 'link_' . $ordparam, $keys, true ) ) { $orderparams[] = 'link_' . $ordparam; } elseif ( in_array( $ordparam, $keys, true ) ) { $orderparams[] = $ordparam; } } $orderby = implode( ',', $orderparams ); } if ( empty( $orderby ) ) { $orderby = 'link_name'; } $order = strtoupper( $parsed_args['order'] ); if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ), true ) ) { $order = 'ASC'; } $visible = ''; if ( $parsed_args['hide_invisible'] ) { $visible = "AND link_visible = 'Y'"; } $query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query"; $query .= " $exclusions $inclusions $search"; $query .= " ORDER BY $orderby $order"; if ( -1 !== $parsed_args['limit'] ) { $query .= ' LIMIT ' . absint( $parsed_args['limit'] ); } $results = $wpdb->get_results( $query ); if ( 'rand()' !== $orderby ) { $cache[ $key ] = $results; wp_cache_set( 'get_bookmarks', $cache, 'bookmark' ); } /** This filter is documented in wp-includes/bookmark.php */ return apply_filters( 'get_bookmarks', $results, $parsed_args ); } /** * Sanitizes all bookmark fields. * * @since 2.3.0 * * @param stdClass|array $bookmark Bookmark row. * @param string $context Optional. How to filter the fields. Default 'display'. * @return stdClass|array Same type as $bookmark but with fields sanitized. */ function sanitize_bookmark( $bookmark, $context = 'display' ) { $fields = array( 'link_id', 'link_url', 'link_name', 'link_image', 'link_target', 'link_category', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_updated', 'link_rel', 'link_notes', 'link_rss', ); if ( is_object( $bookmark ) ) { $do_object = true; $link_id = $bookmark->link_id; } else { $do_object = false; $link_id = $bookmark['link_id']; } foreach ( $fields as $field ) { if ( $do_object ) { if ( isset( $bookmark->$field ) ) { $bookmark->$field = sanitize_bookmark_field( $field, $bookmark->$field, $link_id, $context ); } } else { if ( isset( $bookmark[ $field ] ) ) { $bookmark[ $field ] = sanitize_bookmark_field( $field, $bookmark[ $field ], $link_id, $context ); } } } return $bookmark; } /** * Sanitizes a bookmark field. * * Sanitizes the bookmark fields based on what the field name is. If the field * has a strict value set, then it will be tested for that, else a more generic * filtering is applied. After the more strict filter is applied, if the `$context` * is 'raw' then the value is immediately return. * * Hooks exist for the more generic cases. With the 'edit' context, the {@see 'edit_$field'} * filter will be called and passed the `$value` and `$bookmark_id` respectively. * * With the 'db' context, the {@see 'pre_$field'} filter is called and passed the value. * The 'display' context is the final context and has the `$field` has the filter name * and is passed the `$value`, `$bookmark_id`, and `$context`, respectively. * * @since 2.3.0 * * @param string $field The bookmark field. * @param mixed $value The bookmark field value. * @param int $bookmark_id Bookmark ID. * @param string $context How to filter the field value. Accepts 'raw', 'edit', 'db', * 'display', 'attribute', or 'js'. Default 'display'. * @return mixed The filtered value. */ function sanitize_bookmark_field( $field, $value, $bookmark_id, $context ) { $int_fields = array( 'link_id', 'link_rating' ); if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } switch ( $field ) { case 'link_category': // array( ints ) $value = array_map( 'absint', (array) $value ); /* * We return here so that the categories aren't filtered. * The 'link_category' filter is for the name of a link category, not an array of a link's link categories. */ return $value; case 'link_visible': // bool stored as Y|N $value = preg_replace( '/[^YNyn]/', '', $value ); break; case 'link_target': // "enum" $targets = array( '_top', '_blank' ); if ( ! in_array( $value, $targets, true ) ) { $value = ''; } break; } if ( 'raw' === $context ) { return $value; } if ( 'edit' === $context ) { /** This filter is documented in wp-includes/post.php */ $value = apply_filters( "edit_{$field}", $value, $bookmark_id ); if ( 'link_notes' === $field ) { $value = esc_html( $value ); // textarea_escaped } else { $value = esc_attr( $value ); } } elseif ( 'db' === $context ) { /** This filter is documented in wp-includes/post.php */ $value = apply_filters( "pre_{$field}", $value ); } else { /** This filter is documented in wp-includes/post.php */ $value = apply_filters( "{$field}", $value, $bookmark_id, $context ); if ( 'attribute' === $context ) { $value = esc_attr( $value ); } elseif ( 'js' === $context ) { $value = esc_js( $value ); } } // Restore the type for integer fields after esc_attr(). if ( in_array( $field, $int_fields, true ) ) { $value = (int) $value; } return $value; } /** * Deletes the bookmark cache. * * @since 2.7.0 * * @param int $bookmark_id Bookmark ID. */ function clean_bookmark_cache( $bookmark_id ) { wp_cache_delete( $bookmark_id, 'bookmark' ); wp_cache_delete( 'get_bookmarks', 'bookmark' ); clean_object_term_cache( $bookmark_id, 'link' ); } <?php /** * WP_Theme_JSON_Data class * * @package WordPress * @subpackage Theme * @since 6.1.0 */ /** * Class to provide access to update a theme.json structure. */ #[AllowDynamicProperties] class WP_Theme_JSON_Data { /** * Container of the data to update. * * @since 6.1.0 * @var WP_Theme_JSON */ private $theme_json = null; /** * The origin of the data: default, theme, user, etc. * * @since 6.1.0 * @var string */ private $origin = ''; /** * Constructor. * * @since 6.1.0 * * @link https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/ * * @param array $data Array following the theme.json specification. * @param string $origin The origin of the data: default, theme, user. */ public function __construct( $data = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA ), $origin = 'theme' ) { $this->origin = $origin; $this->theme_json = new WP_Theme_JSON( $data, $this->origin ); } /** * Updates the theme.json with the the given data. * * @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 ) { $this->theme_json->merge( new WP_Theme_JSON( $new_data, $this->origin ) ); return $this; } /** * Returns an array containing the underlying data * following the theme.json specification. * * @since 6.1.0 * * @return array */ public function get_data() { return $this->theme_json->get_raw_data(); } /** * Returns theme JSON object. * * @since 6.6.0 * * @return WP_Theme_JSON The theme JSON structure stored in this data object. */ public function get_theme_json() { return $this->theme_json; } } <?php /** * WP_Navigation_Fallback class * * Manages fallback behavior for Navigation menus. * * @package WordPress * @subpackage Navigation * @since 6.3.0 */ /** * Manages fallback behavior for Navigation menus. * * @access public * @since 6.3.0 */ class WP_Navigation_Fallback { /** * Updates the wp_navigation custom post type schema, in order to expose * additional fields in the embeddable links of WP_REST_Navigation_Fallback_Controller. * * The Navigation Fallback endpoint may embed the full Navigation Menu object * into the response as the `self` link. By default, the Posts Controller * will only expose a limited subset of fields but the editor requires * additional fields to be available in order to utilize the menu. * * Used with the `rest_wp_navigation_item_schema` hook. * * @since 6.4.0 * * @param array $schema The schema for the `wp_navigation` post. * @return array The modified schema. */ public static function update_wp_navigation_post_schema( $schema ) { // Expose top level fields. $schema['properties']['status']['context'] = array_merge( $schema['properties']['status']['context'], array( 'embed' ) ); $schema['properties']['content']['context'] = array_merge( $schema['properties']['content']['context'], array( 'embed' ) ); /* * Exposes sub properties of content field. * These sub properties aren't exposed by the posts controller by default, * for requests where context is `embed`. * * @see WP_REST_Posts_Controller::get_item_schema() */ $schema['properties']['content']['properties']['raw']['context'] = array_merge( $schema['properties']['content']['properties']['raw']['context'], array( 'embed' ) ); $schema['properties']['content']['properties']['rendered']['context'] = array_merge( $schema['properties']['content']['properties']['rendered']['context'], array( 'embed' ) ); $schema['properties']['content']['properties']['block_version']['context'] = array_merge( $schema['properties']['content']['properties']['block_version']['context'], array( 'embed' ) ); /* * Exposes sub properties of title field. * These sub properties aren't exposed by the posts controller by default, * for requests where context is `embed`. * * @see WP_REST_Posts_Controller::get_item_schema() */ $schema['properties']['title']['properties']['raw']['context'] = array_merge( $schema['properties']['title']['properties']['raw']['context'], array( 'embed' ) ); return $schema; } /** * Gets (and/or creates) an appropriate fallback Navigation Menu. * * @since 6.3.0 * * @return WP_Post|null the fallback Navigation Post or null. */ public static function get_fallback() { /** * Filters whether or not a fallback should be created. * * @since 6.3.0 * * @param bool $create Whether to create a fallback navigation menu. Default true. */ $should_create_fallback = apply_filters( 'wp_navigation_should_create_fallback', true ); $fallback = static::get_most_recently_published_navigation(); if ( $fallback || ! $should_create_fallback ) { return $fallback; } $fallback = static::create_classic_menu_fallback(); if ( $fallback && ! is_wp_error( $fallback ) ) { // Return the newly created fallback post object which will now be the most recently created navigation menu. return $fallback instanceof WP_Post ? $fallback : static::get_most_recently_published_navigation(); } $fallback = static::create_default_fallback(); if ( $fallback && ! is_wp_error( $fallback ) ) { // Return the newly created fallback post object which will now be the most recently created navigation menu. return $fallback instanceof WP_Post ? $fallback : static::get_most_recently_published_navigation(); } return null; } /** * Finds the most recently published `wp_navigation` post type. * * @since 6.3.0 * * @return WP_Post|null the first non-empty Navigation or null. */ private static function get_most_recently_published_navigation() { $parsed_args = array( 'post_type' => 'wp_navigation', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'order' => 'DESC', 'orderby' => 'date', 'post_status' => 'publish', 'posts_per_page' => 1, ); $navigation_post = new WP_Query( $parsed_args ); if ( count( $navigation_post->posts ) > 0 ) { return $navigation_post->posts[0]; } return null; } /** * Creates a Navigation Menu post from a Classic Menu. * * @since 6.3.0 * * @return int|WP_Error The post ID of the default fallback menu or a WP_Error object. */ private static function create_classic_menu_fallback() { // See if we have a classic menu. $classic_nav_menu = static::get_fallback_classic_menu(); if ( ! $classic_nav_menu ) { return new WP_Error( 'no_classic_menus', __( 'No Classic Menus found.' ) ); } // If there is a classic menu then convert it to blocks. $classic_nav_menu_blocks = WP_Classic_To_Block_Menu_Converter::convert( $classic_nav_menu ); if ( is_wp_error( $classic_nav_menu_blocks ) ) { return $classic_nav_menu_blocks; } if ( empty( $classic_nav_menu_blocks ) ) { return new WP_Error( 'cannot_convert_classic_menu', __( 'Unable to convert Classic Menu to blocks.' ) ); } // Create a new navigation menu from the classic menu. $classic_menu_fallback = wp_insert_post( array( 'post_content' => $classic_nav_menu_blocks, 'post_title' => $classic_nav_menu->name, 'post_name' => $classic_nav_menu->slug, 'post_status' => 'publish', 'post_type' => 'wp_navigation', ), true // So that we can check whether the result is an error. ); return $classic_menu_fallback; } /** * Determines the most appropriate classic navigation menu to use as a fallback. * * @since 6.3.0 * * @return WP_Term|null The most appropriate classic navigation menu to use as a fallback. */ private static function get_fallback_classic_menu() { $classic_nav_menus = wp_get_nav_menus(); if ( ! $classic_nav_menus || is_wp_error( $classic_nav_menus ) ) { return null; } $nav_menu = static::get_nav_menu_at_primary_location(); if ( $nav_menu ) { return $nav_menu; } $nav_menu = static::get_nav_menu_with_primary_slug( $classic_nav_menus ); if ( $nav_menu ) { return $nav_menu; } return static::get_most_recently_created_nav_menu( $classic_nav_menus ); } /** * Sorts the classic menus and returns the most recently created one. * * @since 6.3.0 * * @param WP_Term[] $classic_nav_menus Array of classic nav menu term objects. * @return WP_Term The most recently created classic nav menu. */ private static function get_most_recently_created_nav_menu( $classic_nav_menus ) { usort( $classic_nav_menus, static function ( $a, $b ) { return $b->term_id - $a->term_id; } ); return $classic_nav_menus[0]; } /** * Returns the classic menu with the slug `primary` if it exists. * * @since 6.3.0 * * @param WP_Term[] $classic_nav_menus Array of classic nav menu term objects. * @return WP_Term|null The classic nav menu with the slug `primary` or null. */ private static function get_nav_menu_with_primary_slug( $classic_nav_menus ) { foreach ( $classic_nav_menus as $classic_nav_menu ) { if ( 'primary' === $classic_nav_menu->slug ) { return $classic_nav_menu; } } return null; } /** * Gets the classic menu assigned to the `primary` navigation menu location * if it exists. * * @since 6.3.0 * * @return WP_Term|null The classic nav menu assigned to the `primary` location or null. */ private static function get_nav_menu_at_primary_location() { $locations = get_nav_menu_locations(); if ( isset( $locations['primary'] ) ) { $primary_menu = wp_get_nav_menu_object( $locations['primary'] ); if ( $primary_menu ) { return $primary_menu; } } return null; } /** * Creates a default Navigation Block Menu fallback. * * @since 6.3.0 * * @return int|WP_Error The post ID of the default fallback menu or a WP_Error object. */ private static function create_default_fallback() { $default_blocks = static::get_default_fallback_blocks(); // Create a new navigation menu from the fallback blocks. $default_fallback = wp_insert_post( array( 'post_content' => $default_blocks, 'post_title' => _x( 'Navigation', 'Title of a Navigation menu' ), 'post_name' => 'navigation', 'post_status' => 'publish', 'post_type' => 'wp_navigation', ), true // So that we can check whether the result is an error. ); return $default_fallback; } /** * Gets the rendered markup for the default fallback blocks. * * @since 6.3.0 * * @return string default blocks markup to use a the fallback. */ private static function get_default_fallback_blocks() { $registry = WP_Block_Type_Registry::get_instance(); // If `core/page-list` is not registered then use empty blocks. return $registry->is_registered( 'core/page-list' ) ? '<!-- wp:page-list /-->' : ''; } } <?php /** * Taxonomy API: Walker_Category class * * @package WordPress * @subpackage Template * @since 4.4.0 */ /** * Core class used to create an HTML list of categories. * * @since 2.1.0 * * @see Walker */ class Walker_Category extends Walker { /** * What the class handles. * * @since 2.1.0 * @var string * * @see Walker::$tree_type */ public $tree_type = 'category'; /** * Database fields to use. * * @since 2.1.0 * @var string[] * * @see Walker::$db_fields * @todo Decouple this */ public $db_fields = array( 'parent' => 'parent', 'id' => 'term_id', ); /** * Starts the list before the elements are added. * * @since 2.1.0 * * @see Walker::start_lvl() * * @param string $output Used to append additional content. Passed by reference. * @param int $depth Optional. Depth of category. Used for tab indentation. Default 0. * @param array $args Optional. An array of arguments. Will only append content if style argument * value is 'list'. See wp_list_categories(). Default empty array. */ public function start_lvl( &$output, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $indent = str_repeat( "\t", $depth ); $output .= "$indent<ul class='children'>\n"; } /** * Ends the list of after the elements are added. * * @since 2.1.0 * * @see Walker::end_lvl() * * @param string $output Used to append additional content. Passed by reference. * @param int $depth Optional. Depth of category. Used for tab indentation. Default 0. * @param array $args Optional. An array of arguments. Will only append content if style argument * value is 'list'. See wp_list_categories(). Default empty array. */ public function end_lvl( &$output, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $indent = str_repeat( "\t", $depth ); $output .= "$indent</ul>\n"; } /** * Starts the element output. * * @since 2.1.0 * @since 5.9.0 Renamed `$category` to `$data_object` and `$id` to `$current_object_id` * to match parent class for PHP 8 named parameter support. * * @see Walker::start_el() * * @param string $output Used to append additional content (passed by reference). * @param WP_Term $data_object Category data object. * @param int $depth Optional. Depth of category in reference to parents. Default 0. * @param array $args Optional. An array of arguments. See wp_list_categories(). * Default empty array. * @param int $current_object_id Optional. ID of the current category. Default 0. */ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { // Restores the more descriptive, specific name for use within this method. $category = $data_object; /** This filter is documented in wp-includes/category-template.php */ $cat_name = apply_filters( 'list_cats', esc_attr( $category->name ), $category ); // Don't generate an element if the category name is empty. if ( '' === $cat_name ) { return; } $atts = array(); $atts['href'] = get_term_link( $category ); if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) { /** * Filters the category description for display. * * @since 1.2.0 * * @param string $description Category description. * @param WP_Term $category Category object. */ $atts['title'] = strip_tags( apply_filters( 'category_description', $category->description, $category ) ); } /** * Filters the HTML attributes applied to a category list item's anchor element. * * @since 5.2.0 * * @param array $atts { * The HTML attributes applied to the list item's `<a>` element, empty strings are ignored. * * @type string $href The href attribute. * @type string $title The title attribute. * } * @param WP_Term $category Term data object. * @param int $depth Depth of category, used for padding. * @param array $args An array of arguments. * @param int $current_object_id ID of the current category. */ $atts = apply_filters( 'category_list_link_attributes', $atts, $category, $depth, $args, $current_object_id ); $attributes = ''; foreach ( $atts as $attr => $value ) { if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } } $link = sprintf( '<a%s>%s</a>', $attributes, $cat_name ); if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) { $link .= ' '; if ( empty( $args['feed_image'] ) ) { $link .= '('; } $link .= '<a href="' . esc_url( get_term_feed_link( $category, $category->taxonomy, $args['feed_type'] ) ) . '"'; if ( empty( $args['feed'] ) ) { /* translators: %s: Category name. */ $alt = ' alt="' . sprintf( __( 'Feed for all posts filed under %s' ), $cat_name ) . '"'; } else { $alt = ' alt="' . $args['feed'] . '"'; $name = $args['feed']; $link .= empty( $args['title'] ) ? '' : $args['title']; } $link .= '>'; if ( empty( $args['feed_image'] ) ) { $link .= $name; } else { $link .= "<img src='" . esc_url( $args['feed_image'] ) . "'$alt" . ' />'; } $link .= '</a>'; if ( empty( $args['feed_image'] ) ) { $link .= ')'; } } if ( ! empty( $args['show_count'] ) ) { $link .= ' (' . number_format_i18n( $category->count ) . ')'; } if ( 'list' === $args['style'] ) { $output .= "\t<li"; $css_classes = array( 'cat-item', 'cat-item-' . $category->term_id, ); if ( ! empty( $args['current_category'] ) ) { // 'current_category' can be an array, so we use `get_terms()`. $_current_terms = get_terms( array( 'taxonomy' => $category->taxonomy, 'include' => $args['current_category'], 'hide_empty' => false, ) ); foreach ( $_current_terms as $_current_term ) { if ( $category->term_id === $_current_term->term_id ) { $css_classes[] = 'current-cat'; $link = str_replace( '<a', '<a aria-current="page"', $link ); } elseif ( $category->term_id === $_current_term->parent ) { $css_classes[] = 'current-cat-parent'; } while ( $_current_term->parent ) { if ( $category->term_id === $_current_term->parent ) { $css_classes[] = 'current-cat-ancestor'; break; } $_current_term = get_term( $_current_term->parent, $category->taxonomy ); } } } /** * Filters the list of CSS classes to include with each category in the list. * * @since 4.2.0 * * @see wp_list_categories() * * @param string[] $css_classes An array of CSS classes to be applied to each list item. * @param WP_Term $category Category data object. * @param int $depth Depth of page, used for padding. * @param array $args An array of wp_list_categories() arguments. */ $css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) ); $css_classes = $css_classes ? ' class="' . esc_attr( $css_classes ) . '"' : ''; $output .= $css_classes; $output .= ">$link\n"; } elseif ( isset( $args['separator'] ) ) { $output .= "\t$link" . $args['separator'] . "\n"; } else { $output .= "\t$link<br />\n"; } } /** * Ends the element output, if needed. * * @since 2.1.0 * @since 5.9.0 Renamed `$page` to `$data_object` to match parent class for PHP 8 named parameter support. * * @see Walker::end_el() * * @param string $output Used to append additional content (passed by reference). * @param object $data_object Category data object. Not used. * @param int $depth Optional. Depth of category. Not used. * @param array $args Optional. An array of arguments. Only uses 'list' for whether should * append to output. See wp_list_categories(). Default empty array. */ public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { if ( 'list' !== $args['style'] ) { return; } $output .= "</li>\n"; } } <?php /** * Block Serialization Parser * * @package WordPress */ /** * Class WP_Block_Parser_Block * * Holds the block structure in memory * * @since 5.0.0 */ class WP_Block_Parser_Block { /** * Name of block * * @example "core/paragraph" * * @since 5.0.0 * @var string */ public $blockName; // phpcs:ignore WordPress.NamingConventions.ValidVariableName /** * Optional set of attributes from block comment delimiters * * @example null * @example array( 'columns' => 3 ) * * @since 5.0.0 * @var array|null */ public $attrs; /** * List of inner blocks (of this same class) * * @since 5.0.0 * @var WP_Block_Parser_Block[] */ public $innerBlocks; // phpcs:ignore WordPress.NamingConventions.ValidVariableName /** * Resultant HTML from inside block comment delimiters * after removing inner blocks * * @example "...Just <!-- wp:test /--> testing..." -> "Just testing..." * * @since 5.0.0 * @var string */ public $innerHTML; // phpcs:ignore WordPress.NamingConventions.ValidVariableName /** * List of string fragments and null markers where inner blocks were found * * @example array( * 'innerHTML' => 'BeforeInnerAfter', * 'innerBlocks' => array( block, block ), * 'innerContent' => array( 'Before', null, 'Inner', null, 'After' ), * ) * * @since 4.2.0 * @var array */ public $innerContent; // phpcs:ignore WordPress.NamingConventions.ValidVariableName /** * Constructor. * * Will populate object properties from the provided arguments. * * @since 5.0.0 * * @param string $name Name of block. * @param array $attrs Optional set of attributes from block comment delimiters. * @param array $inner_blocks List of inner blocks (of this same class). * @param string $inner_html Resultant HTML from inside block comment delimiters after removing inner blocks. * @param array $inner_content List of string fragments and null markers where inner blocks were found. */ public function __construct( $name, $attrs, $inner_blocks, $inner_html, $inner_content ) { $this->blockName = $name; // phpcs:ignore WordPress.NamingConventions.ValidVariableName $this->attrs = $attrs; $this->innerBlocks = $inner_blocks; // phpcs:ignore WordPress.NamingConventions.ValidVariableName $this->innerHTML = $inner_html; // phpcs:ignore WordPress.NamingConventions.ValidVariableName $this->innerContent = $inner_content; // phpcs:ignore WordPress.NamingConventions.ValidVariableName } } <?php /** * Object Cache API functions missing from 3rd party object caches. * * @link https://developer.wordpress.org/reference/classes/wp_object_cache/ * * @package WordPress * @subpackage Cache */ if ( ! function_exists( 'wp_cache_add_multiple' ) ) : /** * Adds multiple values to the cache in one call, if the cache keys don't already exist. * * Compat function to mimic wp_cache_add_multiple(). * * @ignore * @since 6.0.0 * * @see wp_cache_add_multiple() * * @param array $data Array of keys and values to be added. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool[] Array of return values, grouped by key. Each value is either * true on success, or false if cache key and group already exist. */ function wp_cache_add_multiple( array $data, $group = '', $expire = 0 ) { $values = array(); foreach ( $data as $key => $value ) { $values[ $key ] = wp_cache_add( $key, $value, $group, $expire ); } return $values; } endif; if ( ! function_exists( 'wp_cache_set_multiple' ) ) : /** * Sets multiple values to the cache in one call. * * Differs from wp_cache_add_multiple() in that it will always write data. * * Compat function to mimic wp_cache_set_multiple(). * * @ignore * @since 6.0.0 * * @see wp_cache_set_multiple() * * @param array $data Array of keys and values to be set. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool[] Array of return values, grouped by key. Each value is either * true on success, or false on failure. */ function wp_cache_set_multiple( array $data, $group = '', $expire = 0 ) { $values = array(); foreach ( $data as $key => $value ) { $values[ $key ] = wp_cache_set( $key, $value, $group, $expire ); } return $values; } endif; if ( ! function_exists( 'wp_cache_get_multiple' ) ) : /** * Retrieves multiple values from the cache in one call. * * Compat function to mimic wp_cache_get_multiple(). * * @ignore * @since 5.5.0 * * @see wp_cache_get_multiple() * * @param array $keys Array of keys under which the cache contents are stored. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @param bool $force Optional. Whether to force an update of the local cache * from the persistent cache. Default false. * @return array Array of return values, grouped by key. Each value is either * the cache contents on success, or false on failure. */ function wp_cache_get_multiple( $keys, $group = '', $force = false ) { $values = array(); foreach ( $keys as $key ) { $values[ $key ] = wp_cache_get( $key, $group, $force ); } return $values; } endif; if ( ! function_exists( 'wp_cache_delete_multiple' ) ) : /** * Deletes multiple values from the cache in one call. * * Compat function to mimic wp_cache_delete_multiple(). * * @ignore * @since 6.0.0 * * @see wp_cache_delete_multiple() * * @param array $keys Array of keys under which the cache to deleted. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @return bool[] Array of return values, grouped by key. Each value is either * true on success, or false if the contents were not deleted. */ function wp_cache_delete_multiple( array $keys, $group = '' ) { $values = array(); foreach ( $keys as $key ) { $values[ $key ] = wp_cache_delete( $key, $group ); } return $values; } endif; if ( ! function_exists( 'wp_cache_flush_runtime' ) ) : /** * Removes all cache items from the in-memory runtime cache. * * Compat function to mimic wp_cache_flush_runtime(). * * @ignore * @since 6.0.0 * * @see wp_cache_flush_runtime() * * @return bool True on success, false on failure. */ function wp_cache_flush_runtime() { if ( ! wp_cache_supports( 'flush_runtime' ) ) { _doing_it_wrong( __FUNCTION__, __( 'Your object cache implementation does not support flushing the in-memory runtime cache.' ), '6.1.0' ); return false; } return wp_cache_flush(); } endif; if ( ! function_exists( 'wp_cache_flush_group' ) ) : /** * Removes all cache items in a group, if the object cache implementation supports it. * * Before calling this function, always check for group flushing support using the * `wp_cache_supports( 'flush_group' )` function. * * @since 6.1.0 * * @see WP_Object_Cache::flush_group() * @global WP_Object_Cache $wp_object_cache Object cache global instance. * * @param string $group Name of group to remove from cache. * @return bool True if group was flushed, false otherwise. */ function wp_cache_flush_group( $group ) { global $wp_object_cache; if ( ! wp_cache_supports( 'flush_group' ) ) { _doing_it_wrong( __FUNCTION__, __( 'Your object cache implementation does not support flushing individual groups.' ), '6.1.0' ); return false; } return $wp_object_cache->flush_group( $group ); } endif; if ( ! function_exists( 'wp_cache_supports' ) ) : /** * Determines whether the object cache implementation supports a particular feature. * * @since 6.1.0 * * @param string $feature Name of the feature to check for. Possible values include: * 'add_multiple', 'set_multiple', 'get_multiple', 'delete_multiple', * 'flush_runtime', 'flush_group'. * @return bool True if the feature is supported, false otherwise. */ function wp_cache_supports( $feature ) { return false; } endif; <?php /** * HTTP API: WP_Http_Encoding class * * @package WordPress * @subpackage HTTP * @since 4.4.0 */ /** * Core class used to implement deflate and gzip transfer encoding support for HTTP requests. * * Includes RFC 1950, RFC 1951, and RFC 1952. * * @since 2.8.0 */ #[AllowDynamicProperties] class WP_Http_Encoding { /** * Compress raw string using the deflate format. * * Supports the RFC 1951 standard. * * @since 2.8.0 * * @param string $raw String to compress. * @param int $level Optional. Compression level, 9 is highest. Default 9. * @param string $supports Optional, not used. When implemented it will choose * the right compression based on what the server supports. * @return string|false Compressed string on success, false on failure. */ public static function compress( $raw, $level = 9, $supports = null ) { return gzdeflate( $raw, $level ); } /** * Decompression of deflated string. * * Will attempt to decompress using the RFC 1950 standard, and if that fails * then the RFC 1951 standard deflate will be attempted. Finally, the RFC * 1952 standard gzip decode will be attempted. If all fail, then the * original compressed string will be returned. * * @since 2.8.0 * * @param string $compressed String to decompress. * @param int $length The optional length of the compressed data. * @return string|false Decompressed string on success, false on failure. */ public static function decompress( $compressed, $length = null ) { if ( empty( $compressed ) ) { return $compressed; } $decompressed = @gzinflate( $compressed ); if ( false !== $decompressed ) { return $decompressed; } $decompressed = self::compatible_gzinflate( $compressed ); if ( false !== $decompressed ) { return $decompressed; } $decompressed = @gzuncompress( $compressed ); if ( false !== $decompressed ) { return $decompressed; } if ( function_exists( 'gzdecode' ) ) { $decompressed = @gzdecode( $compressed ); if ( false !== $decompressed ) { return $decompressed; } } return $compressed; } /** * Decompression of deflated string while staying compatible with the majority of servers. * * Certain Servers will return deflated data with headers which PHP's gzinflate() * function cannot handle out of the box. The following function has been created from * various snippets on the gzinflate() PHP documentation. * * Warning: Magic numbers within. Due to the potential different formats that the compressed * data may be returned in, some "magic offsets" are needed to ensure proper decompression * takes place. For a simple pragmatic way to determine the magic offset in use, see: * https://core.trac.wordpress.org/ticket/18273 * * @since 2.8.1 * * @link https://core.trac.wordpress.org/ticket/18273 * @link https://www.php.net/manual/en/function.gzinflate.php#70875 * @link https://www.php.net/manual/en/function.gzinflate.php#77336 * * @param string $gz_data String to decompress. * @return string|false Decompressed string on success, false on failure. */ public static function compatible_gzinflate( $gz_data ) { // Compressed data might contain a full header, if so strip it for gzinflate(). if ( str_starts_with( $gz_data, "\x1f\x8b\x08" ) ) { $i = 10; $flg = ord( substr( $gz_data, 3, 1 ) ); if ( $flg > 0 ) { if ( $flg & 4 ) { list($xlen) = unpack( 'v', substr( $gz_data, $i, 2 ) ); $i = $i + 2 + $xlen; } if ( $flg & 8 ) { $i = strpos( $gz_data, "\0", $i ) + 1; } if ( $flg & 16 ) { $i = strpos( $gz_data, "\0", $i ) + 1; } if ( $flg & 2 ) { $i = $i + 2; } } $decompressed = @gzinflate( substr( $gz_data, $i, -8 ) ); if ( false !== $decompressed ) { return $decompressed; } } // Compressed data from java.util.zip.Deflater amongst others. $decompressed = @gzinflate( substr( $gz_data, 2 ) ); if ( false !== $decompressed ) { return $decompressed; } return false; } /** * What encoding types to accept and their priority values. * * @since 2.8.0 * * @param string $url * @param array $args * @return string Types of encoding to accept. */ public static function accept_encoding( $url, $args ) { $type = array(); $compression_enabled = self::is_available(); if ( ! $args['decompress'] ) { // Decompression specifically disabled. $compression_enabled = false; } elseif ( $args['stream'] ) { // Disable when streaming to file. $compression_enabled = false; } elseif ( isset( $args['limit_response_size'] ) ) { // If only partial content is being requested, we won't be able to decompress it. $compression_enabled = false; } if ( $compression_enabled ) { if ( function_exists( 'gzinflate' ) ) { $type[] = 'deflate;q=1.0'; } if ( function_exists( 'gzuncompress' ) ) { $type[] = 'compress;q=0.5'; } if ( function_exists( 'gzdecode' ) ) { $type[] = 'gzip;q=0.5'; } } /** * Filters the allowed encoding types. * * @since 3.6.0 * * @param string[] $type Array of what encoding types to accept and their priority values. * @param string $url URL of the HTTP request. * @param array $args HTTP request arguments. */ $type = apply_filters( 'wp_http_accept_encoding', $type, $url, $args ); return implode( ', ', $type ); } /** * What encoding the content used when it was compressed to send in the headers. * * @since 2.8.0 * * @return string Content-Encoding string to send in the header. */ public static function content_encoding() { return 'deflate'; } /** * Whether the content be decoded based on the headers. * * @since 2.8.0 * * @param array|string $headers All of the available headers. * @return bool */ public static function should_decode( $headers ) { if ( is_array( $headers ) ) { if ( array_key_exists( 'content-encoding', $headers ) && ! empty( $headers['content-encoding'] ) ) { return true; } } elseif ( is_string( $headers ) ) { return ( stripos( $headers, 'content-encoding:' ) !== false ); } return false; } /** * Whether decompression and compression are supported by the PHP version. * * Each function is tested instead of checking for the zlib extension, to * ensure that the functions all exist in the PHP version and aren't * disabled. * * @since 2.8.0 * * @return bool */ public static function is_available() { return ( function_exists( 'gzuncompress' ) || function_exists( 'gzdeflate' ) || function_exists( 'gzinflate' ) ); } } <?php /** * HTTP API: WP_Http_Streams class * * @package WordPress * @subpackage HTTP * @since 4.4.0 */ /** * Core class used to integrate PHP Streams as an HTTP transport. * * @since 2.7.0 * @since 3.7.0 Combined with the fsockopen transport and switched to `stream_socket_client()`. * @deprecated 6.4.0 Use WP_Http * @see WP_Http */ #[AllowDynamicProperties] class WP_Http_Streams { /** * Send a HTTP request to a URI using PHP Streams. * * @see WP_Http::request() For default options descriptions. * * @since 2.7.0 * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client(). * * @param string $url The request URL. * @param string|array $args Optional. Override the defaults. * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error */ public function request( $url, $args = array() ) { $defaults = array( 'method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array(), 'decompress' => false, 'stream' => false, 'filename' => null, ); $parsed_args = wp_parse_args( $args, $defaults ); if ( isset( $parsed_args['headers']['User-Agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['User-Agent']; unset( $parsed_args['headers']['User-Agent'] ); } elseif ( isset( $parsed_args['headers']['user-agent'] ) ) { $parsed_args['user-agent'] = $parsed_args['headers']['user-agent']; unset( $parsed_args['headers']['user-agent'] ); } // Construct Cookie: header if any cookies are set. WP_Http::buildCookieHeader( $parsed_args ); $parsed_url = parse_url( $url ); $connect_host = $parsed_url['host']; $secure_transport = ( 'ssl' === $parsed_url['scheme'] || 'https' === $parsed_url['scheme'] ); if ( ! isset( $parsed_url['port'] ) ) { if ( 'ssl' === $parsed_url['scheme'] || 'https' === $parsed_url['scheme'] ) { $parsed_url['port'] = 443; $secure_transport = true; } else { $parsed_url['port'] = 80; } } // Always pass a path, defaulting to the root in cases such as http://example.com. if ( ! isset( $parsed_url['path'] ) ) { $parsed_url['path'] = '/'; } if ( isset( $parsed_args['headers']['Host'] ) || isset( $parsed_args['headers']['host'] ) ) { if ( isset( $parsed_args['headers']['Host'] ) ) { $parsed_url['host'] = $parsed_args['headers']['Host']; } else { $parsed_url['host'] = $parsed_args['headers']['host']; } unset( $parsed_args['headers']['Host'], $parsed_args['headers']['host'] ); } /* * Certain versions of PHP have issues with 'localhost' and IPv6, It attempts to connect * to ::1, which fails when the server is not set up for it. For compatibility, always * connect to the IPv4 address. */ if ( 'localhost' === strtolower( $connect_host ) ) { $connect_host = '127.0.0.1'; } $connect_host = $secure_transport ? 'ssl://' . $connect_host : 'tcp://' . $connect_host; $is_local = isset( $parsed_args['local'] ) && $parsed_args['local']; $ssl_verify = isset( $parsed_args['sslverify'] ) && $parsed_args['sslverify']; if ( $is_local ) { /** * Filters whether SSL should be verified for local HTTP API requests. * * @since 2.8.0 * @since 5.1.0 The `$url` parameter was added. * * @param bool|string $ssl_verify Boolean to control whether to verify the SSL connection * or path to an SSL certificate. * @param string $url The request URL. */ $ssl_verify = apply_filters( 'https_local_ssl_verify', $ssl_verify, $url ); } elseif ( ! $is_local ) { /** This filter is documented in wp-includes/class-wp-http.php */ $ssl_verify = apply_filters( 'https_ssl_verify', $ssl_verify, $url ); } $proxy = new WP_HTTP_Proxy(); $context = stream_context_create( array( 'ssl' => array( 'verify_peer' => $ssl_verify, // 'CN_match' => $parsed_url['host'], // This is handled by self::verify_ssl_certificate(). 'capture_peer_cert' => $ssl_verify, 'SNI_enabled' => true, 'cafile' => $parsed_args['sslcertificates'], 'allow_self_signed' => ! $ssl_verify, ), ) ); $timeout = (int) floor( $parsed_args['timeout'] ); $utimeout = 0; if ( $timeout !== (int) $parsed_args['timeout'] ) { $utimeout = 1000000 * $parsed_args['timeout'] % 1000000; } $connect_timeout = max( $timeout, 1 ); // Store error number. $connection_error = null; // Store error string. $connection_error_str = null; if ( ! WP_DEBUG ) { // In the event that the SSL connection fails, silence the many PHP warnings. if ( $secure_transport ) { $error_reporting = error_reporting( 0 ); } if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged $handle = @stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } else { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged $handle = @stream_socket_client( $connect_host . ':' . $parsed_url['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } if ( $secure_transport ) { error_reporting( $error_reporting ); } } else { if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { $handle = stream_socket_client( 'tcp://' . $proxy->host() . ':' . $proxy->port(), $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } else { $handle = stream_socket_client( $connect_host . ':' . $parsed_url['port'], $connection_error, $connection_error_str, $connect_timeout, STREAM_CLIENT_CONNECT, $context ); } } if ( false === $handle ) { // SSL connection failed due to expired/invalid cert, or, OpenSSL configuration is broken. if ( $secure_transport && 0 === $connection_error && '' === $connection_error_str ) { return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); } return new WP_Error( 'http_request_failed', $connection_error . ': ' . $connection_error_str ); } // Verify that the SSL certificate is valid for this request. if ( $secure_transport && $ssl_verify && ! $proxy->is_enabled() ) { if ( ! self::verify_ssl_certificate( $handle, $parsed_url['host'] ) ) { return new WP_Error( 'http_request_failed', __( 'The SSL certificate for the host could not be verified.' ) ); } } stream_set_timeout( $handle, $timeout, $utimeout ); if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) { // Some proxies require full URL in this field. $request_path = $url; } else { $request_path = $parsed_url['path'] . ( isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '' ); } $headers = strtoupper( $parsed_args['method'] ) . ' ' . $request_path . ' HTTP/' . $parsed_args['httpversion'] . "\r\n"; $include_port_in_host_header = ( ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) || ( 'http' === $parsed_url['scheme'] && 80 !== $parsed_url['port'] ) || ( 'https' === $parsed_url['scheme'] && 443 !== $parsed_url['port'] ) ); if ( $include_port_in_host_header ) { $headers .= 'Host: ' . $parsed_url['host'] . ':' . $parsed_url['port'] . "\r\n"; } else { $headers .= 'Host: ' . $parsed_url['host'] . "\r\n"; } if ( isset( $parsed_args['user-agent'] ) ) { $headers .= 'User-agent: ' . $parsed_args['user-agent'] . "\r\n"; } if ( is_array( $parsed_args['headers'] ) ) { foreach ( (array) $parsed_args['headers'] as $header => $header_value ) { $headers .= $header . ': ' . $header_value . "\r\n"; } } else { $headers .= $parsed_args['headers']; } if ( $proxy->use_authentication() ) { $headers .= $proxy->authentication_header() . "\r\n"; } $headers .= "\r\n"; if ( ! is_null( $parsed_args['body'] ) ) { $headers .= $parsed_args['body']; } fwrite( $handle, $headers ); if ( ! $parsed_args['blocking'] ) { stream_set_blocking( $handle, 0 ); fclose( $handle ); return array( 'headers' => array(), 'body' => '', 'response' => array( 'code' => false, 'message' => false, ), 'cookies' => array(), ); } $response = ''; $body_started = false; $keep_reading = true; $block_size = 4096; if ( isset( $parsed_args['limit_response_size'] ) ) { $block_size = min( $block_size, $parsed_args['limit_response_size'] ); } // If streaming to a file setup the file handle. if ( $parsed_args['stream'] ) { if ( ! WP_DEBUG ) { $stream_handle = @fopen( $parsed_args['filename'], 'w+' ); } else { $stream_handle = fopen( $parsed_args['filename'], 'w+' ); } if ( ! $stream_handle ) { return new WP_Error( 'http_request_failed', sprintf( /* translators: 1: fopen(), 2: File name. */ __( 'Could not open handle for %1$s to %2$s.' ), 'fopen()', $parsed_args['filename'] ) ); } $bytes_written = 0; while ( ! feof( $handle ) && $keep_reading ) { $block = fread( $handle, $block_size ); if ( ! $body_started ) { $response .= $block; if ( strpos( $response, "\r\n\r\n" ) ) { $processed_response = WP_Http::processResponse( $response ); $body_started = true; $block = $processed_response['body']; unset( $response ); $processed_response['body'] = ''; } } $this_block_size = strlen( $block ); if ( isset( $parsed_args['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $parsed_args['limit_response_size'] ) { $this_block_size = ( $parsed_args['limit_response_size'] - $bytes_written ); $block = substr( $block, 0, $this_block_size ); } $bytes_written_to_file = fwrite( $stream_handle, $block ); if ( $bytes_written_to_file !== $this_block_size ) { fclose( $handle ); fclose( $stream_handle ); return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) ); } $bytes_written += $bytes_written_to_file; $keep_reading = ( ! isset( $parsed_args['limit_response_size'] ) || $bytes_written < $parsed_args['limit_response_size'] ); } fclose( $stream_handle ); } else { $header_length = 0; while ( ! feof( $handle ) && $keep_reading ) { $block = fread( $handle, $block_size ); $response .= $block; if ( ! $body_started && strpos( $response, "\r\n\r\n" ) ) { $header_length = strpos( $response, "\r\n\r\n" ) + 4; $body_started = true; } $keep_reading = ( ! $body_started || ! isset( $parsed_args['limit_response_size'] ) || strlen( $response ) < ( $header_length + $parsed_args['limit_response_size'] ) ); } $processed_response = WP_Http::processResponse( $response ); unset( $response ); } fclose( $handle ); $processed_headers = WP_Http::processHeaders( $processed_response['headers'], $url ); $response = array( 'headers' => $processed_headers['headers'], // Not yet processed. 'body' => null, 'response' => $processed_headers['response'], 'cookies' => $processed_headers['cookies'], 'filename' => $parsed_args['filename'], ); // Handle redirects. $redirect_response = WP_Http::handle_redirects( $url, $parsed_args, $response ); if ( false !== $redirect_response ) { return $redirect_response; } // If the body was chunk encoded, then decode it. if ( ! empty( $processed_response['body'] ) && isset( $processed_headers['headers']['transfer-encoding'] ) && 'chunked' === $processed_headers['headers']['transfer-encoding'] ) { $processed_response['body'] = WP_Http::chunkTransferDecode( $processed_response['body'] ); } if ( true === $parsed_args['decompress'] && true === WP_Http_Encoding::should_decode( $processed_headers['headers'] ) ) { $processed_response['body'] = WP_Http_Encoding::decompress( $processed_response['body'] ); } if ( isset( $parsed_args['limit_response_size'] ) && strlen( $processed_response['body'] ) > $parsed_args['limit_response_size'] ) { $processed_response['body'] = substr( $processed_response['body'], 0, $parsed_args['limit_response_size'] ); } $response['body'] = $processed_response['body']; return $response; } /** * Verifies the received SSL certificate against its Common Names and subjectAltName fields. * * PHP's SSL verifications only verify that it's a valid Certificate, it doesn't verify if * the certificate is valid for the hostname which was requested. * This function verifies the requested hostname against certificate's subjectAltName field, * if that is empty, or contains no DNS entries, a fallback to the Common Name field is used. * * IP Address support is included if the request is being made to an IP address. * * @since 3.7.0 * * @param resource $stream The PHP Stream which the SSL request is being made over * @param string $host The hostname being requested * @return bool If the certificate presented in $stream is valid for $host */ public static function verify_ssl_certificate( $stream, $host ) { $context_options = stream_context_get_options( $stream ); if ( empty( $context_options['ssl']['peer_certificate'] ) ) { return false; } $cert = openssl_x509_parse( $context_options['ssl']['peer_certificate'] ); if ( ! $cert ) { return false; } /* * If the request is being made to an IP address, we'll validate against IP fields * in the cert (if they exist) */ $host_type = ( WP_Http::is_ip_address( $host ) ? 'ip' : 'dns' ); $certificate_hostnames = array(); if ( ! empty( $cert['extensions']['subjectAltName'] ) ) { $match_against = preg_split( '/,\s*/', $cert['extensions']['subjectAltName'] ); foreach ( $match_against as $match ) { list( $match_type, $match_host ) = explode( ':', $match ); if ( strtolower( trim( $match_type ) ) === $host_type ) { // IP: or DNS: $certificate_hostnames[] = strtolower( trim( $match_host ) ); } } } elseif ( ! empty( $cert['subject']['CN'] ) ) { // Only use the CN when the certificate includes no subjectAltName extension. $certificate_hostnames[] = strtolower( $cert['subject']['CN'] ); } // Exact hostname/IP matches. if ( in_array( strtolower( $host ), $certificate_hostnames, true ) ) { return true; } // IP's can't be wildcards, Stop processing. if ( 'ip' === $host_type ) { return false; } // Test to see if the domain is at least 2 deep for wildcard support. if ( substr_count( $host, '.' ) < 2 ) { return false; } // Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com. $wildcard_host = preg_replace( '/^[^.]+\./', '*.', $host ); return in_array( strtolower( $wildcard_host ), $certificate_hostnames, true ); } /** * Determines whether this class can be used for retrieving a URL. * * @since 2.7.0 * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client(). * * @param array $args Optional. Array of request arguments. Default empty array. * @return bool False means this class can not be used, true means it can. */ public static function test( $args = array() ) { if ( ! function_exists( 'stream_socket_client' ) ) { return false; } $is_ssl = isset( $args['ssl'] ) && $args['ssl']; if ( $is_ssl ) { if ( ! extension_loaded( 'openssl' ) ) { return false; } if ( ! function_exists( 'openssl_x509_parse' ) ) { return false; } } /** * Filters whether streams can be used as a transport for retrieving a URL. * * @since 2.7.0 * * @param bool $use_class Whether the class can be used. Default true. * @param array $args Request arguments. */ return apply_filters( 'use_streams_transport', true, $args ); } } /** * Deprecated HTTP Transport method which used fsockopen. * * This class is not used, and is included for backward compatibility only. * All code should make use of WP_Http directly through its API. * * @see WP_HTTP::request * * @since 2.7.0 * @deprecated 3.7.0 Please use WP_HTTP::request() directly */ class WP_HTTP_Fsockopen extends WP_Http_Streams { // For backward compatibility for users who are using the class directly. } <?php /** * Widget API: Default core widgets * * @package WordPress * @subpackage Widgets * @since 2.8.0 */ // Don't load directly. if ( ! defined( 'ABSPATH' ) ) { die( '-1' ); } /** WP_Widget_Pages class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-pages.php'; /** WP_Widget_Links class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-links.php'; /** WP_Widget_Search class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-search.php'; /** WP_Widget_Archives class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-archives.php'; /** WP_Widget_Media class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-media.php'; /** WP_Widget_Media_Audio class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-media-audio.php'; /** WP_Widget_Media_Image class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-media-image.php'; /** WP_Widget_Media_Video class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-media-video.php'; /** WP_Widget_Media_Gallery class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-media-gallery.php'; /** WP_Widget_Meta class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-meta.php'; /** WP_Widget_Calendar class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-calendar.php'; /** WP_Widget_Text class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-text.php'; /** WP_Widget_Categories class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-categories.php'; /** WP_Widget_Recent_Posts class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-recent-posts.php'; /** WP_Widget_Recent_Comments class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-recent-comments.php'; /** WP_Widget_RSS class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-rss.php'; /** WP_Widget_Tag_Cloud class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-tag-cloud.php'; /** WP_Nav_Menu_Widget class */ require_once ABSPATH . WPINC . '/widgets/class-wp-nav-menu-widget.php'; /** WP_Widget_Custom_HTML class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-custom-html.php'; /** WP_Widget_Block class */ require_once ABSPATH . WPINC . '/widgets/class-wp-widget-block.php'; <?php /** * HTML API: WP_HTML_Stack_Event class * * @package WordPress * @subpackage HTML-API * @since 6.6.0 */ /** * Core class used by the HTML Processor as a record for stack operations. * * This class is for internal usage of the WP_HTML_Processor class. * * @access private * @since 6.6.0 * * @see WP_HTML_Processor */ class WP_HTML_Stack_Event { /** * Refers to popping an element off of the stack of open elements. * * @since 6.6.0 */ const POP = 'pop'; /** * Refers to pushing an element onto the stack of open elements. * * @since 6.6.0 */ const PUSH = 'push'; /** * References the token associated with the stack push event, * even if this is a pop event for that element. * * @since 6.6.0 * * @var WP_HTML_Token */ public $token; /** * Indicates which kind of stack operation this event represents. * * May be one of the class constants. * * @since 6.6.0 * * @see self::POP * @see self::PUSH * * @var string */ public $operation; /** * Indicates if the stack element is a real or virtual node. * * @since 6.6.0 * * @var string */ public $provenance; /** * Constructor function. * * @since 6.6.0 * * @param WP_HTML_Token $token Token associated with stack event, always an opening token. * @param string $operation One of self::PUSH or self::POP. * @param string $provenance "virtual" or "real". */ public function __construct( WP_HTML_Token $token, string $operation, string $provenance ) { $this->token = $token; $this->operation = $operation; $this->provenance = $provenance; } } [09-Oct-2025 09:41:46 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php:143 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php on line 143 [09-Oct-2025 09:41:46 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php:143 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php on line 143 [09-Oct-2025 09:41:57 UTC] PHP Fatal error: Uncaught Error: Class "WP_Token_Map" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php:38 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php on line 38 [09-Oct-2025 09:41:58 UTC] PHP Fatal error: Uncaught Error: Class "WP_Token_Map" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php:38 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php on line 38 [09-Oct-2025 09:55:53 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php:143 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php on line 143 [09-Oct-2025 09:55:54 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php:143 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/class-wp-html-processor.php on line 143 [09-Oct-2025 09:56:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Token_Map" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php:38 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php on line 38 [09-Oct-2025 09:56:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_Token_Map" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php:38 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/html-api/html5-named-character-references.php on line 38 <?php /** * HTML API: WP_HTML_Text_Replacement class * * @package WordPress * @subpackage HTML-API * @since 6.2.0 */ /** * Core class used by the HTML tag processor as a data structure for replacing * existing content from start to end, allowing to drastically improve performance. * * This class is for internal usage of the WP_HTML_Tag_Processor class. * * @access private * @since 6.2.0 * @since 6.5.0 Replace `end` with `length` to more closely match `substr()`. * * @see WP_HTML_Tag_Processor */ class WP_HTML_Text_Replacement { /** * Byte offset into document where replacement span begins. * * @since 6.2.0 * * @var int */ public $start; /** * Byte length of span being replaced. * * @since 6.5.0 * * @var int */ public $length; /** * Span of text to insert in document to replace existing content from start to end. * * @since 6.2.0 * * @var string */ public $text; /** * Constructor. * * @since 6.2.0 * * @param int $start Byte offset into document where replacement span begins. * @param int $length Byte length of span in document being replaced. * @param string $text Span of text to insert in document to replace existing content from start to end. */ public function __construct( int $start, int $length, string $text ) { $this->start = $start; $this->length = $length; $this->text = $text; } } <?php /** * HTML API: WP_HTML_Active_Formatting_Elements class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used by the HTML processor during HTML parsing * for managing the stack of active formatting elements. * * This class is designed for internal use by the HTML processor. * * > Initially, the list of active formatting elements is empty. * > It is used to handle mis-nested formatting element tags. * > * > The list contains elements in the formatting category, and markers. * > The markers are inserted when entering applet, object, marquee, * > template, td, th, and caption elements, and are used to prevent * > formatting from "leaking" into applet, object, marquee, template, * > td, th, and caption elements. * > * > In addition, each element in the list of active formatting elements * > is associated with the token for which it was created, so that * > further elements can be created for that token if necessary. * * @since 6.4.0 * * @access private * * @see https://html.spec.whatwg.org/#list-of-active-formatting-elements * @see WP_HTML_Processor */ class WP_HTML_Active_Formatting_Elements { /** * Holds the stack of active formatting element references. * * @since 6.4.0 * * @var WP_HTML_Token[] */ private $stack = array(); /** * Reports if a specific node is in the stack of active formatting elements. * * @since 6.4.0 * * @param WP_HTML_Token $token Look for this node in the stack. * @return bool Whether the referenced node is in the stack of active formatting elements. */ public function contains_node( WP_HTML_Token $token ) { foreach ( $this->walk_up() as $item ) { if ( $token->bookmark_name === $item->bookmark_name ) { return true; } } return false; } /** * Returns how many nodes are currently in the stack of active formatting elements. * * @since 6.4.0 * * @return int How many node are in the stack of active formatting elements. */ public function count() { return count( $this->stack ); } /** * Returns the node at the end of the stack of active formatting elements, * if one exists. If the stack is empty, returns null. * * @since 6.4.0 * * @return WP_HTML_Token|null Last node in the stack of active formatting elements, if one exists, otherwise null. */ public function current_node() { $current_node = end( $this->stack ); return $current_node ? $current_node : null; } /** * Inserts a "marker" at the end of the list of active formatting elements. * * > The markers are inserted when entering applet, object, marquee, * > template, td, th, and caption elements, and are used to prevent * > formatting from "leaking" into applet, object, marquee, template, * > td, th, and caption elements. * * @see https://html.spec.whatwg.org/#concept-parser-marker * * @since 6.7.0 */ public function insert_marker(): void { $this->push( new WP_HTML_Token( null, 'marker', false ) ); } /** * Pushes a node onto the stack of active formatting elements. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#push-onto-the-list-of-active-formatting-elements * * @param WP_HTML_Token $token Push this node onto the stack. */ public function push( WP_HTML_Token $token ) { /* * > If there are already three elements in the list of active formatting elements after the last marker, * > if any, or anywhere in the list if there are no markers, that have the same tag name, namespace, and * > attributes as element, then remove the earliest such element from the list of active formatting * > elements. For these purposes, the attributes must be compared as they were when the elements were * > created by the parser; two elements have the same attributes if all their parsed attributes can be * > paired such that the two attributes in each pair have identical names, namespaces, and values * > (the order of the attributes does not matter). * * @todo Implement the "Noah's Ark clause" to only add up to three of any given kind of formatting elements to the stack. */ // > Add element to the list of active formatting elements. $this->stack[] = $token; } /** * Removes a node from the stack of active formatting elements. * * @since 6.4.0 * * @param WP_HTML_Token $token Remove this node from the stack, if it's there already. * @return bool Whether the node was found and removed from the stack of active formatting elements. */ public function remove_node( WP_HTML_Token $token ) { foreach ( $this->walk_up() as $position_from_end => $item ) { if ( $token->bookmark_name !== $item->bookmark_name ) { continue; } $position_from_start = $this->count() - $position_from_end - 1; array_splice( $this->stack, $position_from_start, 1 ); return true; } return false; } /** * Steps through the stack of active formatting elements, starting with the * top element (added first) and walking downwards to the one added last. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $html = '<em><strong><a>We are here'; * foreach ( $stack->walk_down() as $node ) { * echo "{$node->node_name} -> "; * } * > EM -> STRONG -> A -> * * To start with the most-recently added element and walk towards the top, * see WP_HTML_Active_Formatting_Elements::walk_up(). * * @since 6.4.0 */ public function walk_down() { $count = count( $this->stack ); for ( $i = 0; $i < $count; $i++ ) { yield $this->stack[ $i ]; } } /** * Steps through the stack of active formatting elements, starting with the * bottom element (added last) and walking upwards to the one added first. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $html = '<em><strong><a>We are here'; * foreach ( $stack->walk_up() as $node ) { * echo "{$node->node_name} -> "; * } * > A -> STRONG -> EM -> * * To start with the first added element and walk towards the bottom, * see WP_HTML_Active_Formatting_Elements::walk_down(). * * @since 6.4.0 */ public function walk_up() { for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { yield $this->stack[ $i ]; } } /** * Clears the list of active formatting elements up to the last marker. * * > When the steps below require the UA to clear the list of active formatting elements up to * > the last marker, the UA must perform the following steps: * > * > 1. Let entry be the last (most recently added) entry in the list of active * > formatting elements. * > 2. Remove entry from the list of active formatting elements. * > 3. If entry was a marker, then stop the algorithm at this point. * > The list has been cleared up to the last marker. * > 4. Go to step 1. * * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker * * @since 6.7.0 */ public function clear_up_to_last_marker(): void { foreach ( $this->walk_up() as $item ) { array_pop( $this->stack ); if ( 'marker' === $item->node_name ) { break; } } } } <?php /** * HTML API: WP_HTML_Token class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used by the HTML processor during HTML parsing * for referring to tokens in the input HTML string. * * This class is designed for internal use by the HTML processor. * * @since 6.4.0 * * @access private * * @see WP_HTML_Processor */ class WP_HTML_Token { /** * Name of bookmark corresponding to source of token in input HTML string. * * Having a bookmark name does not imply that the token still exists. It * may be that the source token and underlying bookmark was wiped out by * some modification to the source HTML. * * @since 6.4.0 * * @var string */ public $bookmark_name = null; /** * Name of node; lowercase names such as "marker" are not HTML elements. * * For HTML elements/tags this value should come from WP_HTML_Processor::get_tag(). * * @since 6.4.0 * * @see WP_HTML_Processor::get_tag() * * @var string */ public $node_name = null; /** * Whether node contains the self-closing flag. * * A node may have a self-closing flag when it shouldn't. This value * only reports if the flag is present in the original HTML. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#self-closing-flag * * @var bool */ public $has_self_closing_flag = false; /** * Indicates if the element is an HTML element or if it's inside foreign content. * * @since 6.7.0 * * @var string 'html', 'svg', or 'math'. */ public $namespace = 'html'; /** * Indicates which kind of integration point the element is, if any. * * @since 6.7.0 * * @var string|null 'math', 'html', or null if not an integration point. */ public $integration_node_type = null; /** * Called when token is garbage-collected or otherwise destroyed. * * @var callable|null */ public $on_destroy = null; /** * Constructor - creates a reference to a token in some external HTML string. * * @since 6.4.0 * * @param string|null $bookmark_name Name of bookmark corresponding to location in HTML where token is found, * or `null` for markers and nodes without a bookmark. * @param string $node_name Name of node token represents; if uppercase, an HTML element; if lowercase, a special value like "marker". * @param bool $has_self_closing_flag Whether the source token contains the self-closing flag, regardless of whether it's valid. * @param callable|null $on_destroy Optional. Function to call when destroying token, useful for releasing the bookmark. */ public function __construct( ?string $bookmark_name, string $node_name, bool $has_self_closing_flag, ?callable $on_destroy = null ) { $this->bookmark_name = $bookmark_name; $this->namespace = 'html'; $this->node_name = $node_name; $this->has_self_closing_flag = $has_self_closing_flag; $this->on_destroy = $on_destroy; } /** * Destructor. * * @since 6.4.0 */ public function __destruct() { if ( is_callable( $this->on_destroy ) ) { call_user_func( $this->on_destroy, $this->bookmark_name ); } } /** * Wakeup magic method. * * @since 6.4.2 */ public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } } <?php /** * HTML API: WP_HTML_Attribute_Token class * * @package WordPress * @subpackage HTML-API * @since 6.2.0 */ /** * Core class used by the HTML tag processor as a data structure for the attribute token, * allowing to drastically improve performance. * * This class is for internal usage of the WP_HTML_Tag_Processor class. * * @access private * @since 6.2.0 * @since 6.5.0 Replaced `end` with `length` to more closely match `substr()`. * * @see WP_HTML_Tag_Processor */ class WP_HTML_Attribute_Token { /** * Attribute name. * * @since 6.2.0 * * @var string */ public $name; /** * Attribute value. * * @since 6.2.0 * * @var int */ public $value_starts_at; /** * How many bytes the value occupies in the input HTML. * * @since 6.2.0 * * @var int */ public $value_length; /** * The string offset where the attribute name starts. * * @since 6.2.0 * * @var int */ public $start; /** * Byte length of text spanning the attribute inside a tag. * * This span starts at the first character of the attribute name * and it ends after one of three cases: * * - at the end of the attribute name for boolean attributes. * - at the end of the value for unquoted attributes. * - at the final single or double quote for quoted attributes. * * Example: * * <div class="post"> * ------------ length is 12, including quotes * * <input type="checked" checked id="selector"> * ------- length is 6 * * <a rel=noopener> * ------------ length is 11 * * @since 6.5.0 Replaced `end` with `length` to more closely match `substr()`. * * @var int */ public $length; /** * Whether the attribute is a boolean attribute with value `true`. * * @since 6.2.0 * * @var bool */ public $is_true; /** * Constructor. * * @since 6.2.0 * @since 6.5.0 Replaced `end` with `length` to more closely match `substr()`. * * @param string $name Attribute name. * @param int $value_start Attribute value. * @param int $value_length Number of bytes attribute value spans. * @param int $start The string offset where the attribute name starts. * @param int $length Byte length of the entire attribute name or name and value pair expression. * @param bool $is_true Whether the attribute is a boolean attribute with true value. */ public function __construct( $name, $value_start, $value_length, $start, $length, $is_true ) { $this->name = $name; $this->value_starts_at = $value_start; $this->value_length = $value_length; $this->start = $start; $this->length = $length; $this->is_true = $is_true; } } <?php /** * HTML API: WP_HTML_Doctype_Info class * * @package WordPress * @subpackage HTML-API * @since 6.7.0 */ /** * Core class used by the HTML API to represent a DOCTYPE declaration. * * This class parses DOCTYPE tokens for the full parser in the HTML Processor. * Most code interacting with HTML won't need to parse DOCTYPE declarations; * the HTML Processor is one exception. Consult the HTML Processor for proper * parsing of an HTML document. * * A DOCTYPE declaration may indicate its document compatibility mode, which impacts * the structure of the following HTML as well as the behavior of CSS class selectors. * There are three possible modes: * * - "no-quirks" and "limited-quirks" modes (also called "standards mode"). * - "quirks" mode. * * These modes mostly determine whether CSS class name selectors match values in the * HTML `class` attribute in an ASCII-case-insensitive way (quirks mode), or whether * they match only when byte-for-byte identical (no-quirks mode). * * All HTML documents should start with the standard HTML5 DOCTYPE: `<!DOCTYPE html>`. * * > DOCTYPEs are required for legacy reasons. When omitted, browsers tend to use a different * > rendering mode that is incompatible with some specifications. Including the DOCTYPE in a * > document ensures that the browser makes a best-effort attempt at following the * > relevant specifications. * * @see https://html.spec.whatwg.org/#the-doctype * * DOCTYPE declarations comprise four properties: a name, public identifier, system identifier, * and an indication of which document compatability mode they would imply if an HTML parser * hadn't already determined it from other information. * * @see https://html.spec.whatwg.org/#the-initial-insertion-mode * * Historically, the DOCTYPE declaration was used in SGML documents to instruct a parser how * to interpret the various tags and entities within a document. Its role in HTML diverged * from how it was used in SGML and no meaning should be back-read into HTML based on how it * is used in SGML, XML, or XHTML documents. * * @see https://www.iso.org/standard/16387.html * * @since 6.7.0 * * @see WP_HTML_Processor */ class WP_HTML_Doctype_Info { /** * Name of the DOCTYPE: should be "html" for HTML documents. * * This value should be considered "read only" and not modified. * * Historically the DOCTYPE name indicates name of the document's root element. * * <!DOCTYPE html> * ╰──┴── name is "html". * * @see https://html.spec.whatwg.org/#tokenization * * @since 6.7.0 * * @var string|null */ public $name = null; /** * Public identifier of the DOCTYPE. * * This value should be considered "read only" and not modified. * * The public identifier is optional and should not appear in HTML documents. * A `null` value indicates that no public identifier was present in the DOCTYPE. * * Historically the presence of the public identifier indicated that a document * was meant to be shared between computer systems and the value indicated to a * knowledgeable parser how to find the relevant document type definition (DTD). * * <!DOCTYPE html PUBLIC "public id goes here in quotes"> * │ │ ╰─── public identifier ─────╯ * ╰──┴── name is "html". * * @see https://html.spec.whatwg.org/#tokenization * * @since 6.7.0 * * @var string|null */ public $public_identifier = null; /** * System identifier of the DOCTYPE. * * This value should be considered "read only" and not modified. * * The system identifier is optional and should not appear in HTML documents. * A `null` value indicates that no system identifier was present in the DOCTYPE. * * Historically the system identifier specified where a relevant document type * declaration for the given document is stored and may be retrieved. * * <!DOCTYPE html SYSTEM "system id goes here in quotes"> * │ │ ╰──── system identifier ────╯ * ╰──┴── name is "html". * * If a public identifier were provided it would indicate to a knowledgeable * parser how to interpret the system identifier. * * <!DOCTYPE html PUBLIC "public id goes here in quotes" "system id goes here in quotes"> * │ │ ╰─── public identifier ─────╯ ╰──── system identifier ────╯ * ╰──┴── name is "html". * * @see https://html.spec.whatwg.org/#tokenization * * @since 6.7.0 * * @var string|null */ public $system_identifier = null; /** * Which document compatability mode this DOCTYPE declaration indicates. * * This value should be considered "read only" and not modified. * * When an HTML parser has not already set the document compatability mode, * (e.g. "quirks" or "no-quirks" mode), it will infer if from the properties * of the appropriate DOCTYPE declaration, if one exists. The DOCTYPE can * indicate one of three possible document compatability modes: * * - "no-quirks" and "limited-quirks" modes (also called "standards" mode). * - "quirks" mode (also called `CSS1Compat` mode). * * An appropriate DOCTYPE is one encountered in the "initial" insertion mode, * before the HTML element has been opened and before finding any other * DOCTYPE declaration tokens. * * @see https://html.spec.whatwg.org/#the-initial-insertion-mode * * @since 6.7.0 * * @var string One of "no-quirks", "limited-quirks", or "quirks". */ public $indicated_compatability_mode; /** * Constructor. * * This class should not be instantiated directly. * Use the static {@see self::from_doctype_token} method instead. * * The arguments to this constructor correspond to the "DOCTYPE token" * as defined in the HTML specification. * * > DOCTYPE tokens have a name, a public identifier, a system identifier, * > and a force-quirks flag. When a DOCTYPE token is created, its name, public identifier, * > and system identifier must be marked as missing (which is a distinct state from the * > empty string), and the force-quirks flag must be set to off (its other state is on). * * @see https://html.spec.whatwg.org/multipage/parsing.html#tokenization * * @since 6.7.0 * * @param string|null $name Name of the DOCTYPE. * @param string|null $public_identifier Public identifier of the DOCTYPE. * @param string|null $system_identifier System identifier of the DOCTYPE. * @param bool $force_quirks_flag Whether the force-quirks flag is set for the token. */ private function __construct( ?string $name, ?string $public_identifier, ?string $system_identifier, bool $force_quirks_flag ) { $this->name = $name; $this->public_identifier = $public_identifier; $this->system_identifier = $system_identifier; /* * > If the DOCTYPE token matches one of the conditions in the following list, * > then set the Document to quirks mode: */ /* * > The force-quirks flag is set to on. */ if ( $force_quirks_flag ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * Normative documents will contain the literal `<!DOCTYPE html>` with no * public or system identifiers; short-circuit to avoid extra parsing. */ if ( 'html' === $name && null === $public_identifier && null === $system_identifier ) { $this->indicated_compatability_mode = 'no-quirks'; return; } /* * > The name is not "html". * * The tokenizer must report the name in lower case even if provided in * the document in upper case; thus no conversion is required here. */ if ( 'html' !== $name ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * Set up some variables to handle the rest of the conditions. * * > set...the public identifier...to...the empty string if the public identifier was missing. * > set...the system identifier...to...the empty string if the system identifier was missing. * > * > The system identifier and public identifier strings must be compared... * > in an ASCII case-insensitive manner. * > * > A system identifier whose value is the empty string is not considered missing * > for the purposes of the conditions above. */ $system_identifier_is_missing = null === $system_identifier; $public_identifier = null === $public_identifier ? '' : strtolower( $public_identifier ); $system_identifier = null === $system_identifier ? '' : strtolower( $system_identifier ); /* * > The public identifier is set to… */ if ( '-//w3o//dtd w3 html strict 3.0//en//' === $public_identifier || '-/w3c/dtd html 4.0 transitional/en' === $public_identifier || 'html' === $public_identifier ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * > The system identifier is set to… */ if ( 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd' === $system_identifier ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * All of the following conditions depend on matching the public identifier. * If the public identifier is empty, none of the following conditions will match. */ if ( '' === $public_identifier ) { $this->indicated_compatability_mode = 'no-quirks'; return; } /* * > The public identifier starts with… * * @todo Optimize this matching. It shouldn't be a large overall performance issue, * however, as only a single DOCTYPE declaration token should ever be parsed, * and normative documents will have exited before reaching this condition. */ if ( str_starts_with( $public_identifier, '+//silmaril//dtd html pro v0r11 19970101//' ) || str_starts_with( $public_identifier, '-//as//dtd html 3.0 aswedit + extensions//' ) || str_starts_with( $public_identifier, '-//advasoft ltd//dtd html 3.0 aswedit + extensions//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 2.1e//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.2 final//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3.2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html level 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 0//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 1//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 2//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict level 3//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html strict//' ) || str_starts_with( $public_identifier, '-//ietf//dtd html//' ) || str_starts_with( $public_identifier, '-//metrius//dtd metrius presentational//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html strict//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 tables//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html strict//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html//' ) || str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 tables//' ) || str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd html//' ) || str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd strict html//' ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html 2.0//" ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended 1.0//" ) || str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended relaxed 1.0//" ) || str_starts_with( $public_identifier, '-//sq//dtd html 2.0 hotmetal + extensions//' ) || str_starts_with( $public_identifier, '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//' ) || str_starts_with( $public_identifier, '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//' ) || str_starts_with( $public_identifier, '-//spyglass//dtd html 2.0 extended//' ) || str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava html//' ) || str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava strict html//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3 1995-03-24//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 draft//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 final//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 3.2s draft//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 transitional//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html experimental 19960712//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html experimental 970421//' ) || str_starts_with( $public_identifier, '-//w3c//dtd w3 html//' ) || str_starts_with( $public_identifier, '-//w3o//dtd w3 html 3.0//' ) || str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html 2.0//' ) || str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html//' ) ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * > The system identifier is missing and the public identifier starts with… */ if ( $system_identifier_is_missing && ( str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' ) ) ) { $this->indicated_compatability_mode = 'quirks'; return; } /* * > Otherwise, if the DOCTYPE token matches one of the conditions in * > the following list, then set the Document to limited-quirks mode. */ /* * > The public identifier starts with… */ if ( str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 transitional//' ) ) { $this->indicated_compatability_mode = 'limited-quirks'; return; } /* * > The system identifier is not missing and the public identifier starts with… */ if ( ! $system_identifier_is_missing && ( str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) || str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' ) ) ) { $this->indicated_compatability_mode = 'limited-quirks'; return; } $this->indicated_compatability_mode = 'no-quirks'; } /** * Creates a WP_HTML_Doctype_Info instance by parsing a raw DOCTYPE declaration token. * * Use this method to parse a DOCTYPE declaration token and get access to its properties * via the returned WP_HTML_Doctype_Info class instance. The provided input must parse * properly as a DOCTYPE declaration, though it must not represent a valid DOCTYPE. * * Example: * * // Normative HTML DOCTYPE declaration. * $doctype = WP_HTML_Doctype_Info::from_doctype_token( '<!DOCTYPE html>' ); * 'no-quirks' === $doctype->indicated_compatability_mode; * * // A nonsensical DOCTYPE is still valid, and will indicate "quirks" mode. * $doctype = WP_HTML_Doctype_Info::from_doctype_token( '<!doctypeJSON SILLY "nonsense\'>' ); * 'quirks' === $doctype->indicated_compatability_mode; * * // Textual quirks present in raw HTML are handled appropriately. * $doctype = WP_HTML_Doctype_Info::from_doctype_token( "<!DOCTYPE\nhtml\n>" ); * 'no-quirks' === $doctype->indicated_compatability_mode; * * // Anything other than a proper DOCTYPE declaration token fails to parse. * null === WP_HTML_Doctype_Info::from_doctype_token( ' <!DOCTYPE>' ); * null === WP_HTML_Doctype_Info::from_doctype_token( '<!DOCTYPE ><p>' ); * null === WP_HTML_Doctype_Info::from_doctype_token( '<!TYPEDOC>' ); * null === WP_HTML_Doctype_Info::from_doctype_token( 'html' ); * null === WP_HTML_Doctype_Info::from_doctype_token( '<?xml version="1.0" encoding="UTF-8" ?>' ); * * @since 6.7.0 * * @param string $doctype_html The complete raw DOCTYPE HTML string, e.g. `<!DOCTYPE html>`. * * @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. */ public static function from_doctype_token( string $doctype_html ): ?self { $doctype_name = null; $doctype_public_id = null; $doctype_system_id = null; $end = strlen( $doctype_html ) - 1; /* * This parser combines the rules for parsing DOCTYPE tokens found in the HTML * specification for the DOCTYPE related tokenizer states. * * @see https://html.spec.whatwg.org/#doctype-state */ /* * - Valid DOCTYPE HTML token must be at least `<!DOCTYPE>` assuming a complete token not * ending in end-of-file. * - It must start with an ASCII case-insensitive match for `<!DOCTYPE`. * - The only occurrence of `>` must be the final byte in the HTML string. */ if ( $end < 9 || 0 !== substr_compare( $doctype_html, '<!DOCTYPE', 0, 9, true ) ) { return null; } $at = 9; // Is there one and only one `>`? if ( '>' !== $doctype_html[ $end ] || ( strcspn( $doctype_html, '>', $at ) + $at ) < $end ) { return null; } /* * Perform newline normalization and ensure the $end value is correct after normalization. * * @see https://html.spec.whatwg.org/#preprocessing-the-input-stream * @see https://infra.spec.whatwg.org/#normalize-newlines */ $doctype_html = str_replace( "\r\n", "\n", $doctype_html ); $doctype_html = str_replace( "\r", "\n", $doctype_html ); $end = strlen( $doctype_html ) - 1; /* * In this state, the doctype token has been found and its "content" optionally including the * name, public identifier, and system identifier is between the current position and the end. * * "<!DOCTYPE...declaration...>" * ╰─ $at ╰─ $end * * It's also possible that the declaration part is empty. * * ╭─ $at * "<!DOCTYPE>" * ╰─ $end * * Rules for parsing ">" which terminates the DOCTYPE do not need to be considered as they * have been handled above in the condition that the provided DOCTYPE HTML must contain * exactly one ">" character in the final position. */ /* * * Parsing effectively begins in "Before DOCTYPE name state". Ignore whitespace and * proceed to the next state. * * @see https://html.spec.whatwg.org/#before-doctype-name-state */ $at += strspn( $doctype_html, " \t\n\f\r", $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } $name_length = strcspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); $doctype_name = str_replace( "\0", "\u{FFFD}", strtolower( substr( $doctype_html, $at, $name_length ) ) ); $at += $name_length; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } /* * "After DOCTYPE name state" * * Find a case-insensitive match for "PUBLIC" or "SYSTEM" at this point. * Otherwise, set force-quirks and enter bogus DOCTYPE state (skip the rest of the doctype). * * @see https://html.spec.whatwg.org/#after-doctype-name-state */ if ( $at + 6 >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } /* * > If the six characters starting from the current input character are an ASCII * > case-insensitive match for the word "PUBLIC", then consume those characters * > and switch to the after DOCTYPE public keyword state. */ if ( 0 === substr_compare( $doctype_html, 'PUBLIC', $at, 6, true ) ) { $at += 6; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } goto parse_doctype_public_identifier; } /* * > Otherwise, if the six characters starting from the current input character are an ASCII * > case-insensitive match for the word "SYSTEM", then consume those characters and switch * > to the after DOCTYPE system keyword state. */ if ( 0 === substr_compare( $doctype_html, 'SYSTEM', $at, 6, true ) ) { $at += 6; $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } goto parse_doctype_system_identifier; } /* * > Otherwise, this is an invalid-character-sequence-after-doctype-name parse error. * > Set the current DOCTYPE token's force-quirks flag to on. Reconsume in the bogus * > DOCTYPE state. */ return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); parse_doctype_public_identifier: /* * The parser should enter "DOCTYPE public identifier (double-quoted) state" or * "DOCTYPE public identifier (single-quoted) state" by finding one of the valid quotes. * Anything else forces quirks mode and ignores the rest of the contents. * * @see https://html.spec.whatwg.org/#doctype-public-identifier-(double-quoted)-state * @see https://html.spec.whatwg.org/#doctype-public-identifier-(single-quoted)-state */ $closer_quote = $doctype_html[ $at ]; /* * > This is a missing-quote-before-doctype-public-identifier parse error. Set the * > current DOCTYPE token's force-quirks flag to on. Reconsume in the bogus DOCTYPE state. */ if ( '"' !== $closer_quote && "'" !== $closer_quote ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; $identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at ); $doctype_public_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) ); $at += $identifier_length; if ( $at >= $end || $closer_quote !== $doctype_html[ $at ] ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; /* * "Between DOCTYPE public and system identifiers state" * * Advance through whitespace between public and system identifiers. * * @see https://html.spec.whatwg.org/#between-doctype-public-and-system-identifiers-state */ $at += strspn( $doctype_html, " \t\n\f\r", $at, $end - $at ); if ( $at >= $end ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } parse_doctype_system_identifier: /* * The parser should enter "DOCTYPE system identifier (double-quoted) state" or * "DOCTYPE system identifier (single-quoted) state" by finding one of the valid quotes. * Anything else forces quirks mode and ignores the rest of the contents. * * @see https://html.spec.whatwg.org/#doctype-system-identifier-(double-quoted)-state * @see https://html.spec.whatwg.org/#doctype-system-identifier-(single-quoted)-state */ $closer_quote = $doctype_html[ $at ]; /* * > This is a missing-quote-before-doctype-system-identifier parse error. Set the * > current DOCTYPE token's force-quirks flag to on. Reconsume in the bogus DOCTYPE state. */ if ( '"' !== $closer_quote && "'" !== $closer_quote ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } ++$at; $identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at ); $doctype_system_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) ); $at += $identifier_length; if ( $at >= $end || $closer_quote !== $doctype_html[ $at ] ) { return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true ); } return new self( $doctype_name, $doctype_public_id, $doctype_system_id, false ); } } <?php /** * HTML API: WP_HTML_Span class * * @package WordPress * @subpackage HTML-API * @since 6.2.0 */ /** * Core class used by the HTML tag processor to represent a textual span * inside an HTML document. * * This is a two-tuple in disguise, used to avoid the memory overhead * involved in using an array for the same purpose. * * This class is for internal usage of the WP_HTML_Tag_Processor class. * * @access private * @since 6.2.0 * @since 6.5.0 Replaced `end` with `length` to more closely align with `substr()`. * * @see WP_HTML_Tag_Processor */ class WP_HTML_Span { /** * Byte offset into document where span begins. * * @since 6.2.0 * * @var int */ public $start; /** * Byte length of this span. * * @since 6.5.0 * * @var int */ public $length; /** * Constructor. * * @since 6.2.0 * * @param int $start Byte offset into document where replacement span begins. * @param int $length Byte length of span. */ public function __construct( int $start, int $length ) { $this->start = $start; $this->length = $length; } } <?php /** * HTML API: WP_HTML_Tag_Processor class * * Scans through an HTML document to find specific tags, then * transforms those tags by adding, removing, or updating the * values of the HTML attributes within that tag (opener). * * Does not fully parse HTML or _recurse_ into the HTML structure * Instead this scans linearly through a document and only parses * the HTML tag openers. * * ### Possible future direction for this module * * - Prune the whitespace when removing classes/attributes: e.g. "a b c" -> "c" not " c". * This would increase the size of the changes for some operations but leave more * natural-looking output HTML. * * @package WordPress * @subpackage HTML-API * @since 6.2.0 */ /** * Core class used to modify attributes in an HTML document for tags matching a query. * * ## Usage * * Use of this class requires three steps: * * 1. Create a new class instance with your input HTML document. * 2. Find the tag(s) you are looking for. * 3. Request changes to the attributes in those tag(s). * * Example: * * $tags = new WP_HTML_Tag_Processor( $html ); * if ( $tags->next_tag( 'option' ) ) { * $tags->set_attribute( 'selected', true ); * } * * ### Finding tags * * The `next_tag()` function moves the internal cursor through * your input HTML document until it finds a tag meeting any of * the supplied restrictions in the optional query argument. If * no argument is provided then it will find the next HTML tag, * regardless of what kind it is. * * If you want to _find whatever the next tag is_: * * $tags->next_tag(); * * | Goal | Query | * |-----------------------------------------------------------|---------------------------------------------------------------------------------| * | Find any tag. | `$tags->next_tag();` | * | Find next image tag. | `$tags->next_tag( array( 'tag_name' => 'img' ) );` | * | Find next image tag (without passing the array). | `$tags->next_tag( 'img' );` | * | Find next tag containing the `fullwidth` CSS class. | `$tags->next_tag( array( 'class_name' => 'fullwidth' ) );` | * | Find next image tag containing the `fullwidth` CSS class. | `$tags->next_tag( array( 'tag_name' => 'img', 'class_name' => 'fullwidth' ) );` | * * If a tag was found meeting your criteria then `next_tag()` * will return `true` and you can proceed to modify it. If it * returns `false`, however, it failed to find the tag and * moved the cursor to the end of the file. * * Once the cursor reaches the end of the file the processor * is done and if you want to reach an earlier tag you will * need to recreate the processor and start over, as it's * unable to back up or move in reverse. * * See the section on bookmarks for an exception to this * no-backing-up rule. * * #### Custom queries * * Sometimes it's necessary to further inspect an HTML tag than * the query syntax here permits. In these cases one may further * inspect the search results using the read-only functions * provided by the processor or external state or variables. * * Example: * * // Paint up to the first five DIV or SPAN tags marked with the "jazzy" style. * $remaining_count = 5; * while ( $remaining_count > 0 && $tags->next_tag() ) { * if ( * ( 'DIV' === $tags->get_tag() || 'SPAN' === $tags->get_tag() ) && * 'jazzy' === $tags->get_attribute( 'data-style' ) * ) { * $tags->add_class( 'theme-style-everest-jazz' ); * $remaining_count--; * } * } * * `get_attribute()` will return `null` if the attribute wasn't present * on the tag when it was called. It may return `""` (the empty string) * in cases where the attribute was present but its value was empty. * For boolean attributes, those whose name is present but no value is * given, it will return `true` (the only way to set `false` for an * attribute is to remove it). * * #### When matching fails * * When `next_tag()` returns `false` it could mean different things: * * - The requested tag wasn't found in the input document. * - The input document ended in the middle of an HTML syntax element. * * When a document ends in the middle of a syntax element it will pause * the processor. This is to make it possible in the future to extend the * input document and proceed - an important requirement for chunked * streaming parsing of a document. * * Example: * * $processor = new WP_HTML_Tag_Processor( 'This <div is="a" partial="token' ); * false === $processor->next_tag(); * * If a special element (see next section) is encountered but no closing tag * is found it will count as an incomplete tag. The parser will pause as if * the opening tag were incomplete. * * Example: * * $processor = new WP_HTML_Tag_Processor( '<style>// there could be more styling to come' ); * false === $processor->next_tag(); * * $processor = new WP_HTML_Tag_Processor( '<style>// this is everything</style><div>' ); * true === $processor->next_tag( 'DIV' ); * * #### Special self-contained elements * * Some HTML elements are handled in a special way; their start and end tags * act like a void tag. These are special because their contents can't contain * HTML markup. Everything inside these elements is handled in a special way * and content that _appears_ like HTML tags inside of them isn't. There can * be no nesting in these elements. * * In the following list, "raw text" means that all of the content in the HTML * until the matching closing tag is treated verbatim without any replacements * and without any parsing. * * - IFRAME allows no content but requires a closing tag. * - NOEMBED (deprecated) content is raw text. * - NOFRAMES (deprecated) content is raw text. * - SCRIPT content is plaintext apart from legacy rules allowing `</script>` inside an HTML comment. * - STYLE content is raw text. * - TITLE content is plain text but character references are decoded. * - TEXTAREA content is plain text but character references are decoded. * - XMP (deprecated) content is raw text. * * ### Modifying HTML attributes for a found tag * * Once you've found the start of an opening tag you can modify * any number of the attributes on that tag. You can set a new * value for an attribute, remove the entire attribute, or do * nothing and move on to the next opening tag. * * Example: * * if ( $tags->next_tag( array( 'class_name' => 'wp-group-block' ) ) ) { * $tags->set_attribute( 'title', 'This groups the contained content.' ); * $tags->remove_attribute( 'data-test-id' ); * } * * If `set_attribute()` is called for an existing attribute it will * overwrite the existing value. Similarly, calling `remove_attribute()` * for a non-existing attribute has no effect on the document. Both * of these methods are safe to call without knowing if a given attribute * exists beforehand. * * ### Modifying CSS classes for a found tag * * The tag processor treats the `class` attribute as a special case. * Because it's a common operation to add or remove CSS classes, this * interface adds helper methods to make that easier. * * As with attribute values, adding or removing CSS classes is a safe * operation that doesn't require checking if the attribute or class * exists before making changes. If removing the only class then the * entire `class` attribute will be removed. * * Example: * * // from `<span>Yippee!</span>` * // to `<span class="is-active">Yippee!</span>` * $tags->add_class( 'is-active' ); * * // from `<span class="excited">Yippee!</span>` * // to `<span class="excited is-active">Yippee!</span>` * $tags->add_class( 'is-active' ); * * // from `<span class="is-active heavy-accent">Yippee!</span>` * // to `<span class="is-active heavy-accent">Yippee!</span>` * $tags->add_class( 'is-active' ); * * // from `<input type="text" class="is-active rugby not-disabled" length="24">` * // to `<input type="text" class="is-active not-disabled" length="24"> * $tags->remove_class( 'rugby' ); * * // from `<input type="text" class="rugby" length="24">` * // to `<input type="text" length="24"> * $tags->remove_class( 'rugby' ); * * // from `<input type="text" length="24">` * // to `<input type="text" length="24"> * $tags->remove_class( 'rugby' ); * * When class changes are enqueued but a direct change to `class` is made via * `set_attribute` then the changes to `set_attribute` (or `remove_attribute`) * will take precedence over those made through `add_class` and `remove_class`. * * ### Bookmarks * * While scanning through the input HTMl document it's possible to set * a named bookmark when a particular tag is found. Later on, after * continuing to scan other tags, it's possible to `seek` to one of * the set bookmarks and then proceed again from that point forward. * * Because bookmarks create processing overhead one should avoid * creating too many of them. As a rule, create only bookmarks * of known string literal names; avoid creating "mark_{$index}" * and so on. It's fine from a performance standpoint to create a * bookmark and update it frequently, such as within a loop. * * $total_todos = 0; * while ( $p->next_tag( array( 'tag_name' => 'UL', 'class_name' => 'todo' ) ) ) { * $p->set_bookmark( 'list-start' ); * while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { * if ( 'UL' === $p->get_tag() && $p->is_tag_closer() ) { * $p->set_bookmark( 'list-end' ); * $p->seek( 'list-start' ); * $p->set_attribute( 'data-contained-todos', (string) $total_todos ); * $total_todos = 0; * $p->seek( 'list-end' ); * break; * } * * if ( 'LI' === $p->get_tag() && ! $p->is_tag_closer() ) { * $total_todos++; * } * } * } * * ## Tokens and finer-grained processing. * * It's possible to scan through every lexical token in the * HTML document using the `next_token()` function. This * alternative form takes no argument and provides no built-in * query syntax. * * Example: * * $title = '(untitled)'; * $text = ''; * while ( $processor->next_token() ) { * switch ( $processor->get_token_name() ) { * case '#text': * $text .= $processor->get_modifiable_text(); * break; * * case 'BR': * $text .= "\n"; * break; * * case 'TITLE': * $title = $processor->get_modifiable_text(); * break; * } * } * return trim( "# {$title}\n\n{$text}" ); * * ### Tokens and _modifiable text_. * * #### Special "atomic" HTML elements. * * Not all HTML elements are able to contain other elements inside of them. * For instance, the contents inside a TITLE element are plaintext (except * that character references like & will be decoded). This means that * if the string `<img>` appears inside a TITLE element, then it's not an * image tag, but rather it's text describing an image tag. Likewise, the * contents of a SCRIPT or STYLE element are handled entirely separately in * a browser than the contents of other elements because they represent a * different language than HTML. * * For these elements the Tag Processor treats the entire sequence as one, * from the opening tag, including its contents, through its closing tag. * This means that the it's not possible to match the closing tag for a * SCRIPT element unless it's unexpected; the Tag Processor already matched * it when it found the opening tag. * * The inner contents of these elements are that element's _modifiable text_. * * The special elements are: * - `SCRIPT` whose contents are treated as raw plaintext but supports a legacy * style of including JavaScript inside of HTML comments to avoid accidentally * closing the SCRIPT from inside a JavaScript string. E.g. `console.log( '</script>' )`. * - `TITLE` and `TEXTAREA` whose contents are treated as plaintext and then any * character references are decoded. E.g. `1 < 2 < 3` becomes `1 < 2 < 3`. * - `IFRAME`, `NOSCRIPT`, `NOEMBED`, `NOFRAME`, `STYLE` whose contents are treated as * raw plaintext and left as-is. E.g. `1 < 2 < 3` remains `1 < 2 < 3`. * * #### Other tokens with modifiable text. * * There are also non-elements which are void/self-closing in nature and contain * modifiable text that is part of that individual syntax token itself. * * - `#text` nodes, whose entire token _is_ the modifiable text. * - HTML comments and tokens that become comments due to some syntax error. The * text for these tokens is the portion of the comment inside of the syntax. * E.g. for `<!-- comment -->` the text is `" comment "` (note the spaces are included). * - `CDATA` sections, whose text is the content inside of the section itself. E.g. for * `<![CDATA[some content]]>` the text is `"some content"` (with restrictions [1]). * - "Funky comments," which are a special case of invalid closing tags whose name is * invalid. The text for these nodes is the text that a browser would transform into * an HTML comment when parsing. E.g. for `</%post_author>` the text is `%post_author`. * - `DOCTYPE` declarations like `<DOCTYPE html>` which have no closing tag. * - XML Processing instruction nodes like `<?wp __( "Like" ); ?>` (with restrictions [2]). * - The empty end tag `</>` which is ignored in the browser and DOM. * * [1]: There are no CDATA sections in HTML. When encountering `<![CDATA[`, everything * until the next `>` becomes a bogus HTML comment, meaning there can be no CDATA * section in an HTML document containing `>`. The Tag Processor will first find * all valid and bogus HTML comments, and then if the comment _would_ have been a * CDATA section _were they to exist_, it will indicate this as the type of comment. * * [2]: XML allows a broader range of characters in a processing instruction's target name * and disallows "xml" as a name, since it's special. The Tag Processor only recognizes * target names with an ASCII-representable subset of characters. It also exhibits the * same constraint as with CDATA sections, in that `>` cannot exist within the token * since Processing Instructions do no exist within HTML and their syntax transforms * into a bogus comment in the DOM. * * ## Design and limitations * * The Tag Processor is designed to linearly scan HTML documents and tokenize * HTML tags and their attributes. It's designed to do this as efficiently as * possible without compromising parsing integrity. Therefore it will be * slower than some methods of modifying HTML, such as those incorporating * over-simplified PCRE patterns, but will not introduce the defects and * failures that those methods bring in, which lead to broken page renders * and often to security vulnerabilities. On the other hand, it will be faster * than full-blown HTML parsers such as DOMDocument and use considerably * less memory. It requires a negligible memory overhead, enough to consider * it a zero-overhead system. * * The performance characteristics are maintained by avoiding tree construction * and semantic cleanups which are specified in HTML5. Because of this, for * example, it's not possible for the Tag Processor to associate any given * opening tag with its corresponding closing tag, or to return the inner markup * inside an element. Systems may be built on top of the Tag Processor to do * this, but the Tag Processor is and should be constrained so it can remain an * efficient, low-level, and reliable HTML scanner. * * The Tag Processor's design incorporates a "garbage-in-garbage-out" philosophy. * HTML5 specifies that certain invalid content be transformed into different forms * for display, such as removing null bytes from an input document and replacing * invalid characters with the Unicode replacement character `U+FFFD` (visually "�"). * Where errors or transformations exist within the HTML5 specification, the Tag Processor * leaves those invalid inputs untouched, passing them through to the final browser * to handle. While this implies that certain operations will be non-spec-compliant, * such as reading the value of an attribute with invalid content, it also preserves a * simplicity and efficiency for handling those error cases. * * Most operations within the Tag Processor are designed to minimize the difference * between an input and output document for any given change. For example, the * `add_class` and `remove_class` methods preserve whitespace and the class ordering * within the `class` attribute; and when encountering tags with duplicated attributes, * the Tag Processor will leave those invalid duplicate attributes where they are but * update the proper attribute which the browser will read for parsing its value. An * exception to this rule is that all attribute updates store their values as * double-quoted strings, meaning that attributes on input with single-quoted or * unquoted values will appear in the output with double-quotes. * * ### Scripting Flag * * The Tag Processor parses HTML with the "scripting flag" disabled. This means * that it doesn't run any scripts while parsing the page. In a browser with * JavaScript enabled, for example, the script can change the parse of the * document as it loads. On the server, however, evaluating JavaScript is not * only impractical, but also unwanted. * * Practically this means that the Tag Processor will descend into NOSCRIPT * elements and process its child tags. Were the scripting flag enabled, such * as in a typical browser, the contents of NOSCRIPT are skipped entirely. * * This allows the HTML API to process the content that will be presented in * a browser when scripting is disabled, but it offers a different view of a * page than most browser sessions will experience. E.g. the tags inside the * NOSCRIPT disappear. * * ### Text Encoding * * The Tag Processor assumes that the input HTML document is encoded with a * text encoding compatible with 7-bit ASCII's '<', '>', '&', ';', '/', '=', * "'", '"', 'a' - 'z', 'A' - 'Z', and the whitespace characters ' ', tab, * carriage-return, newline, and form-feed. * * In practice, this includes almost every single-byte encoding as well as * UTF-8. Notably, however, it does not include UTF-16. If providing input * that's incompatible, then convert the encoding beforehand. * * @since 6.2.0 * @since 6.2.1 Fix: Support for various invalid comments; attribute updates are case-insensitive. * @since 6.3.2 Fix: Skip HTML-like content inside rawtext elements such as STYLE. * @since 6.5.0 Pauses processor when input ends in an incomplete syntax token. * Introduces "special" elements which act like void elements, e.g. TITLE, STYLE. * Allows scanning through all tokens and processing modifiable text, where applicable. */ class WP_HTML_Tag_Processor { /** * The maximum number of bookmarks allowed to exist at * any given time. * * @since 6.2.0 * @var int * * @see WP_HTML_Tag_Processor::set_bookmark() */ const MAX_BOOKMARKS = 10; /** * Maximum number of times seek() can be called. * Prevents accidental infinite loops. * * @since 6.2.0 * @var int * * @see WP_HTML_Tag_Processor::seek() */ const MAX_SEEK_OPS = 1000; /** * The HTML document to parse. * * @since 6.2.0 * @var string */ protected $html; /** * The last query passed to next_tag(). * * @since 6.2.0 * @var array|null */ private $last_query; /** * The tag name this processor currently scans for. * * @since 6.2.0 * @var string|null */ private $sought_tag_name; /** * The CSS class name this processor currently scans for. * * @since 6.2.0 * @var string|null */ private $sought_class_name; /** * The match offset this processor currently scans for. * * @since 6.2.0 * @var int|null */ private $sought_match_offset; /** * Whether to visit tag closers, e.g. </div>, when walking an input document. * * @since 6.2.0 * @var bool */ private $stop_on_tag_closers; /** * Specifies mode of operation of the parser at any given time. * * | State | Meaning | * | ----------------|----------------------------------------------------------------------| * | *Ready* | The parser is ready to run. | * | *Complete* | There is nothing left to parse. | * | *Incomplete* | The HTML ended in the middle of a token; nothing more can be parsed. | * | *Matched tag* | Found an HTML tag; it's possible to modify its attributes. | * | *Text node* | Found a #text node; this is plaintext and modifiable. | * | *CDATA node* | Found a CDATA section; this is modifiable. | * | *Comment* | Found a comment or bogus comment; this is modifiable. | * | *Presumptuous* | Found an empty tag closer: `</>`. | * | *Funky comment* | Found a tag closer with an invalid tag name; this is modifiable. | * * @since 6.5.0 * * @see WP_HTML_Tag_Processor::STATE_READY * @see WP_HTML_Tag_Processor::STATE_COMPLETE * @see WP_HTML_Tag_Processor::STATE_INCOMPLETE_INPUT * @see WP_HTML_Tag_Processor::STATE_MATCHED_TAG * @see WP_HTML_Tag_Processor::STATE_TEXT_NODE * @see WP_HTML_Tag_Processor::STATE_CDATA_NODE * @see WP_HTML_Tag_Processor::STATE_COMMENT * @see WP_HTML_Tag_Processor::STATE_DOCTYPE * @see WP_HTML_Tag_Processor::STATE_PRESUMPTUOUS_TAG * @see WP_HTML_Tag_Processor::STATE_FUNKY_COMMENT * * @var string */ protected $parser_state = self::STATE_READY; /** * Indicates if the document is in quirks mode or no-quirks mode. * * Impact on HTML parsing: * * - In `NO_QUIRKS_MODE` (also known as "standard mode"): * - CSS class and ID selectors match byte-for-byte (case-sensitively). * - A TABLE start tag `<table>` implicitly closes any open `P` element. * * - In `QUIRKS_MODE`: * - CSS class and ID selectors match match in an ASCII case-insensitive manner. * - A TABLE start tag `<table>` opens a `TABLE` element as a child of a `P` * element if one is open. * * Quirks and no-quirks mode are thus mostly about styling, but have an impact when * tables are found inside paragraph elements. * * @see self::QUIRKS_MODE * @see self::NO_QUIRKS_MODE * * @since 6.7.0 * * @var string */ protected $compat_mode = self::NO_QUIRKS_MODE; /** * Indicates whether the parser is inside foreign content, * e.g. inside an SVG or MathML element. * * One of 'html', 'svg', or 'math'. * * Several parsing rules change based on whether the parser * is inside foreign content, including whether CDATA sections * are allowed and whether a self-closing flag indicates that * an element has no content. * * @since 6.7.0 * * @var string */ private $parsing_namespace = 'html'; /** * What kind of syntax token became an HTML comment. * * Since there are many ways in which HTML syntax can create an HTML comment, * this indicates which of those caused it. This allows the Tag Processor to * represent more from the original input document than would appear in the DOM. * * @since 6.5.0 * * @var string|null */ protected $comment_type = null; /** * What kind of text the matched text node represents, if it was subdivided. * * @see self::TEXT_IS_NULL_SEQUENCE * @see self::TEXT_IS_WHITESPACE * @see self::TEXT_IS_GENERIC * @see self::subdivide_text_appropriately * * @since 6.7.0 * * @var string */ protected $text_node_classification = self::TEXT_IS_GENERIC; /** * How many bytes from the original HTML document have been read and parsed. * * This value points to the latest byte offset in the input document which * has been already parsed. It is the internal cursor for the Tag Processor * and updates while scanning through the HTML tokens. * * @since 6.2.0 * @var int */ private $bytes_already_parsed = 0; /** * Byte offset in input document where current token starts. * * Example: * * <div id="test">... * 01234 * - token starts at 0 * * @since 6.5.0 * * @var int|null */ private $token_starts_at; /** * Byte length of current token. * * Example: * * <div id="test">... * 012345678901234 * - token length is 14 - 0 = 14 * * a <!-- comment --> is a token. * 0123456789 123456789 123456789 * - token length is 17 - 2 = 15 * * @since 6.5.0 * * @var int|null */ private $token_length; /** * Byte offset in input document where current tag name starts. * * Example: * * <div id="test">... * 01234 * - tag name starts at 1 * * @since 6.2.0 * * @var int|null */ private $tag_name_starts_at; /** * Byte length of current tag name. * * Example: * * <div id="test">... * 01234 * --- tag name length is 3 * * @since 6.2.0 * * @var int|null */ private $tag_name_length; /** * Byte offset into input document where current modifiable text starts. * * @since 6.5.0 * * @var int */ private $text_starts_at; /** * Byte length of modifiable text. * * @since 6.5.0 * * @var int */ private $text_length; /** * Whether the current tag is an opening tag, e.g. <div>, or a closing tag, e.g. </div>. * * @var bool */ private $is_closing_tag; /** * Lazily-built index of attributes found within an HTML tag, keyed by the attribute name. * * Example: * * // Supposing the parser is working through this content * // and stops after recognizing the `id` attribute. * // <div id="test-4" class=outline title="data:text/plain;base64=asdk3nk1j3fo8"> * // ^ parsing will continue from this point. * $this->attributes = array( * 'id' => new WP_HTML_Attribute_Token( 'id', 9, 6, 5, 11, false ) * ); * * // When picking up parsing again, or when asking to find the * // `class` attribute we will continue and add to this array. * $this->attributes = array( * 'id' => new WP_HTML_Attribute_Token( 'id', 9, 6, 5, 11, false ), * 'class' => new WP_HTML_Attribute_Token( 'class', 23, 7, 17, 13, false ) * ); * * // Note that only the `class` attribute value is stored in the index. * // That's because it is the only value used by this class at the moment. * * @since 6.2.0 * @var WP_HTML_Attribute_Token[] */ private $attributes = array(); /** * Tracks spans of duplicate attributes on a given tag, used for removing * all copies of an attribute when calling `remove_attribute()`. * * @since 6.3.2 * * @var (WP_HTML_Span[])[]|null */ private $duplicate_attributes = null; /** * Which class names to add or remove from a tag. * * These are tracked separately from attribute updates because they are * semantically distinct, whereas this interface exists for the common * case of adding and removing class names while other attributes are * generally modified as with DOM `setAttribute` calls. * * When modifying an HTML document these will eventually be collapsed * into a single `set_attribute( 'class', $changes )` call. * * Example: * * // Add the `wp-block-group` class, remove the `wp-group` class. * $classname_updates = array( * // Indexed by a comparable class name. * 'wp-block-group' => WP_HTML_Tag_Processor::ADD_CLASS, * 'wp-group' => WP_HTML_Tag_Processor::REMOVE_CLASS * ); * * @since 6.2.0 * @var bool[] */ private $classname_updates = array(); /** * Tracks a semantic location in the original HTML which * shifts with updates as they are applied to the document. * * @since 6.2.0 * @var WP_HTML_Span[] */ protected $bookmarks = array(); const ADD_CLASS = true; const REMOVE_CLASS = false; const SKIP_CLASS = null; /** * Lexical replacements to apply to input HTML document. * * "Lexical" in this class refers to the part of this class which * operates on pure text _as text_ and not as HTML. There's a line * between the public interface, with HTML-semantic methods like * `set_attribute` and `add_class`, and an internal state that tracks * text offsets in the input document. * * When higher-level HTML methods are called, those have to transform their * operations (such as setting an attribute's value) into text diffing * operations (such as replacing the sub-string from indices A to B with * some given new string). These text-diffing operations are the lexical * updates. * * As new higher-level methods are added they need to collapse their * operations into these lower-level lexical updates since that's the * Tag Processor's internal language of change. Any code which creates * these lexical updates must ensure that they do not cross HTML syntax * boundaries, however, so these should never be exposed outside of this * class or any classes which intentionally expand its functionality. * * These are enqueued while editing the document instead of being immediately * applied to avoid processing overhead, string allocations, and string * copies when applying many updates to a single document. * * Example: * * // Replace an attribute stored with a new value, indices * // sourced from the lazily-parsed HTML recognizer. * $start = $attributes['src']->start; * $length = $attributes['src']->length; * $modifications[] = new WP_HTML_Text_Replacement( $start, $length, $new_value ); * * // Correspondingly, something like this will appear in this array. * $lexical_updates = array( * WP_HTML_Text_Replacement( 14, 28, 'https://my-site.my-domain/wp-content/uploads/2014/08/kittens.jpg' ) * ); * * @since 6.2.0 * @var WP_HTML_Text_Replacement[] */ protected $lexical_updates = array(); /** * Tracks and limits `seek()` calls to prevent accidental infinite loops. * * @since 6.2.0 * @var int * * @see WP_HTML_Tag_Processor::seek() */ protected $seek_count = 0; /** * Whether the parser should skip over an immediately-following linefeed * character, as is the case with LISTING, PRE, and TEXTAREA. * * > If the next token is a U+000A LINE FEED (LF) character token, then * > ignore that token and move on to the next one. (Newlines at the start * > of [these] elements are ignored as an authoring convenience.) * * @since 6.7.0 * * @var int|null */ private $skip_newline_at = null; /** * Constructor. * * @since 6.2.0 * * @param string $html HTML to process. */ public function __construct( $html ) { $this->html = $html; } /** * Switches parsing mode into a new namespace, such as when * encountering an SVG tag and entering foreign content. * * @since 6.7.0 * * @param string $new_namespace One of 'html', 'svg', or 'math' indicating into what * namespace the next tokens will be processed. * @return bool Whether the namespace was valid and changed. */ public function change_parsing_namespace( string $new_namespace ): bool { if ( ! in_array( $new_namespace, array( 'html', 'math', 'svg' ), true ) ) { return false; } $this->parsing_namespace = $new_namespace; return true; } /** * Finds the next tag matching the $query. * * @since 6.2.0 * @since 6.5.0 No longer processes incomplete tokens at end of document; pauses the processor at start of token. * * @param array|string|null $query { * Optional. Which tag name to find, having which class, etc. Default is to find any tag. * * @type string|null $tag_name Which tag to find, or `null` for "any tag." * @type int|null $match_offset Find the Nth tag matching all search criteria. * 1 for "first" tag, 3 for "third," etc. * Defaults to first tag. * @type string|null $class_name Tag must contain this whole class name to match. * @type string|null $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. </div>. * } * @return bool Whether a tag was matched. */ public function next_tag( $query = null ): bool { $this->parse_query( $query ); $already_found = 0; do { if ( false === $this->next_token() ) { return false; } if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { continue; } if ( $this->matches() ) { ++$already_found; } } while ( $already_found < $this->sought_match_offset ); return true; } /** * Finds the next token in the HTML document. * * An HTML document can be viewed as a stream of tokens, * where tokens are things like HTML tags, HTML comments, * text nodes, etc. This method finds the next token in * the HTML document and returns whether it found one. * * If it starts parsing a token and reaches the end of the * document then it will seek to the start of the last * token and pause, returning `false` to indicate that it * failed to find a complete token. * * Possible token types, based on the HTML specification: * * - an HTML tag, whether opening, closing, or void. * - a text node - the plaintext inside tags. * - an HTML comment. * - a DOCTYPE declaration. * - a processing instruction, e.g. `<?xml version="1.0" ?>`. * * The Tag Processor currently only supports the tag token. * * @since 6.5.0 * @since 6.7.0 Recognizes CDATA sections within foreign content. * * @return bool Whether a token was parsed. */ public function next_token(): bool { return $this->base_class_next_token(); } /** * Internal method which finds the next token in the HTML document. * * This method is a protected internal function which implements the logic for * finding the next token in a document. It exists so that the parser can update * its state without affecting the location of the cursor in the document and * without triggering subclass methods for things like `next_token()`, e.g. when * applying patches before searching for the next token. * * @since 6.5.0 * * @access private * * @return bool Whether a token was parsed. */ private function base_class_next_token(): bool { $was_at = $this->bytes_already_parsed; $this->after_tag(); // Don't proceed if there's nothing more to scan. if ( self::STATE_COMPLETE === $this->parser_state || self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { return false; } /* * The next step in the parsing loop determines the parsing state; * clear it so that state doesn't linger from the previous step. */ $this->parser_state = self::STATE_READY; if ( $this->bytes_already_parsed >= strlen( $this->html ) ) { $this->parser_state = self::STATE_COMPLETE; return false; } // Find the next tag if it exists. if ( false === $this->parse_next_tag() ) { if ( self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { $this->bytes_already_parsed = $was_at; } return false; } /* * For legacy reasons the rest of this function handles tags and their * attributes. If the processor has reached the end of the document * or if it matched any other token then it should return here to avoid * attempting to process tag-specific syntax. */ if ( self::STATE_INCOMPLETE_INPUT !== $this->parser_state && self::STATE_COMPLETE !== $this->parser_state && self::STATE_MATCHED_TAG !== $this->parser_state ) { return true; } // Parse all of its attributes. while ( $this->parse_next_attribute() ) { continue; } // Ensure that the tag closes before the end of the document. if ( self::STATE_INCOMPLETE_INPUT === $this->parser_state || $this->bytes_already_parsed >= strlen( $this->html ) ) { // Does this appropriately clear state (parsed attributes)? $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } $tag_ends_at = strpos( $this->html, '>', $this->bytes_already_parsed ); if ( false === $tag_ends_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } $this->parser_state = self::STATE_MATCHED_TAG; $this->bytes_already_parsed = $tag_ends_at + 1; $this->token_length = $this->bytes_already_parsed - $this->token_starts_at; /* * Certain tags require additional processing. The first-letter pre-check * avoids unnecessary string allocation when comparing the tag names. * * - IFRAME * - LISTING (deprecated) * - NOEMBED (deprecated) * - NOFRAMES (deprecated) * - PRE * - SCRIPT * - STYLE * - TEXTAREA * - TITLE * - XMP (deprecated) */ if ( $this->is_closing_tag || 'html' !== $this->parsing_namespace || 1 !== strspn( $this->html, 'iIlLnNpPsStTxX', $this->tag_name_starts_at, 1 ) ) { return true; } $tag_name = $this->get_tag(); /* * For LISTING, PRE, and TEXTAREA, the first linefeed of an immediately-following * text node is ignored as an authoring convenience. * * @see static::skip_newline_at */ if ( 'LISTING' === $tag_name || 'PRE' === $tag_name ) { $this->skip_newline_at = $this->bytes_already_parsed; return true; } /* * There are certain elements whose children are not DATA but are instead * RCDATA or RAWTEXT. These cannot contain other elements, and the contents * are parsed as plaintext, with character references decoded in RCDATA but * not in RAWTEXT. * * These elements are described here as "self-contained" or special atomic * elements whose end tag is consumed with the opening tag, and they will * contain modifiable text inside of them. * * Preserve the opening tag pointers, as these will be overwritten * when finding the closing tag. They will be reset after finding * the closing to tag to point to the opening of the special atomic * tag sequence. */ $tag_name_starts_at = $this->tag_name_starts_at; $tag_name_length = $this->tag_name_length; $tag_ends_at = $this->token_starts_at + $this->token_length; $attributes = $this->attributes; $duplicate_attributes = $this->duplicate_attributes; // Find the closing tag if necessary. switch ( $tag_name ) { case 'SCRIPT': $found_closer = $this->skip_script_data(); break; case 'TEXTAREA': case 'TITLE': $found_closer = $this->skip_rcdata( $tag_name ); break; /* * In the browser this list would include the NOSCRIPT element, * but the Tag Processor is an environment with the scripting * flag disabled, meaning that it needs to descend into the * NOSCRIPT element to be able to properly process what will be * sent to a browser. * * Note that this rule makes HTML5 syntax incompatible with XML, * because the parsing of this token depends on client application. * The NOSCRIPT element cannot be represented in the XHTML syntax. */ case 'IFRAME': case 'NOEMBED': case 'NOFRAMES': case 'STYLE': case 'XMP': $found_closer = $this->skip_rawtext( $tag_name ); break; // No other tags should be treated in their entirety here. default: return true; } if ( ! $found_closer ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; $this->bytes_already_parsed = $was_at; return false; } /* * The values here look like they reference the opening tag but they reference * the closing tag instead. This is why the opening tag values were stored * above in a variable. It reads confusingly here, but that's because the * functions that skip the contents have moved all the internal cursors past * the inner content of the tag. */ $this->token_starts_at = $was_at; $this->token_length = $this->bytes_already_parsed - $this->token_starts_at; $this->text_starts_at = $tag_ends_at; $this->text_length = $this->tag_name_starts_at - $this->text_starts_at; $this->tag_name_starts_at = $tag_name_starts_at; $this->tag_name_length = $tag_name_length; $this->attributes = $attributes; $this->duplicate_attributes = $duplicate_attributes; return true; } /** * Whether the processor paused because the input HTML document ended * in the middle of a syntax element, such as in the middle of a tag. * * Example: * * $processor = new WP_HTML_Tag_Processor( '<input type="text" value="Th' ); * false === $processor->get_next_tag(); * true === $processor->paused_at_incomplete_token(); * * @since 6.5.0 * * @return bool Whether the parse paused at the start of an incomplete token. */ public function paused_at_incomplete_token(): bool { return self::STATE_INCOMPLETE_INPUT === $this->parser_state; } /** * Generator for a foreach loop to step through each class name for the matched tag. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $p = new WP_HTML_Tag_Processor( "<div class='free <egg<\tlang-en'>" ); * $p->next_tag(); * foreach ( $p->class_list() as $class_name ) { * echo "{$class_name} "; * } * // Outputs: "free <egg> lang-en " * * @since 6.4.0 */ public function class_list() { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return; } /** @var string $class contains the string value of the class attribute, with character references decoded. */ $class = $this->get_attribute( 'class' ); if ( ! is_string( $class ) ) { return; } $seen = array(); $is_quirks = self::QUIRKS_MODE === $this->compat_mode; $at = 0; while ( $at < strlen( $class ) ) { // Skip past any initial boundary characters. $at += strspn( $class, " \t\f\r\n", $at ); if ( $at >= strlen( $class ) ) { return; } // Find the byte length until the next boundary. $length = strcspn( $class, " \t\f\r\n", $at ); if ( 0 === $length ) { return; } $name = str_replace( "\x00", "\u{FFFD}", substr( $class, $at, $length ) ); if ( $is_quirks ) { $name = strtolower( $name ); } $at += $length; /* * It's expected that the number of class names for a given tag is relatively small. * Given this, it is probably faster overall to scan an array for a value rather * than to use the class name as a key and check if it's a key of $seen. */ if ( in_array( $name, $seen, true ) ) { continue; } $seen[] = $name; yield $name; } } /** * Returns if a matched tag contains the given ASCII case-insensitive class name. * * @since 6.4.0 * * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive. * @return bool|null Whether the matched tag contains the given class name, or null if not matched. */ public function has_class( $wanted_class ): ?bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $case_insensitive = self::QUIRKS_MODE === $this->compat_mode; $wanted_length = strlen( $wanted_class ); foreach ( $this->class_list() as $class_name ) { if ( strlen( $class_name ) === $wanted_length && 0 === substr_compare( $class_name, $wanted_class, 0, strlen( $wanted_class ), $case_insensitive ) ) { return true; } } return false; } /** * Sets a bookmark in the HTML document. * * Bookmarks represent specific places or tokens in the HTML * document, such as a tag opener or closer. When applying * edits to a document, such as setting an attribute, the * text offsets of that token may shift; the bookmark is * kept updated with those shifts and remains stable unless * the entire span of text in which the token sits is removed. * * Release bookmarks when they are no longer needed. * * Example: * * <main><h2>Surprising fact you may not know!</h2></main> * ^ ^ * \-|-- this `H2` opener bookmark tracks the token * * <main class="clickbait"><h2>Surprising fact you may no… * ^ ^ * \-|-- it shifts with edits * * Bookmarks provide the ability to seek to a previously-scanned * place in the HTML document. This avoids the need to re-scan * the entire document. * * Example: * * <ul><li>One</li><li>Two</li><li>Three</li></ul> * ^^^^ * want to note this last item * * $p = new WP_HTML_Tag_Processor( $html ); * $in_list = false; * while ( $p->next_tag( array( 'tag_closers' => $in_list ? 'visit' : 'skip' ) ) ) { * if ( 'UL' === $p->get_tag() ) { * if ( $p->is_tag_closer() ) { * $in_list = false; * $p->set_bookmark( 'resume' ); * if ( $p->seek( 'last-li' ) ) { * $p->add_class( 'last-li' ); * } * $p->seek( 'resume' ); * $p->release_bookmark( 'last-li' ); * $p->release_bookmark( 'resume' ); * } else { * $in_list = true; * } * } * * if ( 'LI' === $p->get_tag() ) { * $p->set_bookmark( 'last-li' ); * } * } * * Bookmarks intentionally hide the internal string offsets * to which they refer. They are maintained internally as * updates are applied to the HTML document and therefore * retain their "position" - the location to which they * originally pointed. The inability to use bookmarks with * functions like `substr` is therefore intentional to guard * against accidentally breaking the HTML. * * Because bookmarks allocate memory and require processing * for every applied update, they are limited and require * a name. They should not be created with programmatically-made * names, such as "li_{$index}" with some loop. As a general * rule they should only be created with string-literal names * like "start-of-section" or "last-paragraph". * * Bookmarks are a powerful tool to enable complicated behavior. * Consider double-checking that you need this tool if you are * reaching for it, as inappropriate use could lead to broken * HTML structure or unwanted processing overhead. * * @since 6.2.0 * * @param string $name Identifies this particular bookmark. * @return bool Whether the bookmark was successfully created. */ public function set_bookmark( $name ): bool { // It only makes sense to set a bookmark if the parser has paused on a concrete token. if ( self::STATE_COMPLETE === $this->parser_state || self::STATE_INCOMPLETE_INPUT === $this->parser_state ) { return false; } if ( ! array_key_exists( $name, $this->bookmarks ) && count( $this->bookmarks ) >= static::MAX_BOOKMARKS ) { _doing_it_wrong( __METHOD__, __( 'Too many bookmarks: cannot create any more.' ), '6.2.0' ); return false; } $this->bookmarks[ $name ] = new WP_HTML_Span( $this->token_starts_at, $this->token_length ); return true; } /** * Removes a bookmark that is no longer needed. * * Releasing a bookmark frees up the small * performance overhead it requires. * * @param string $name Name of the bookmark to remove. * @return bool Whether the bookmark already existed before removal. */ public function release_bookmark( $name ): bool { if ( ! array_key_exists( $name, $this->bookmarks ) ) { return false; } unset( $this->bookmarks[ $name ] ); return true; } /** * Skips contents of generic rawtext elements. * * @since 6.3.2 * * @see https://html.spec.whatwg.org/#generic-raw-text-element-parsing-algorithm * * @param string $tag_name The uppercase tag name which will close the RAWTEXT region. * @return bool Whether an end to the RAWTEXT region was found before the end of the document. */ private function skip_rawtext( string $tag_name ): bool { /* * These two functions distinguish themselves on whether character references are * decoded, and since functionality to read the inner markup isn't supported, it's * not necessary to implement these two functions separately. */ return $this->skip_rcdata( $tag_name ); } /** * Skips contents of RCDATA elements, namely title and textarea tags. * * @since 6.2.0 * * @see https://html.spec.whatwg.org/multipage/parsing.html#rcdata-state * * @param string $tag_name The uppercase tag name which will close the RCDATA region. * @return bool Whether an end to the RCDATA region was found before the end of the document. */ private function skip_rcdata( string $tag_name ): bool { $html = $this->html; $doc_length = strlen( $html ); $tag_length = strlen( $tag_name ); $at = $this->bytes_already_parsed; while ( false !== $at && $at < $doc_length ) { $at = strpos( $this->html, '</', $at ); $this->tag_name_starts_at = $at; // Fail if there is no possible tag closer. if ( false === $at || ( $at + $tag_length ) >= $doc_length ) { return false; } $at += 2; /* * Find a case-insensitive match to the tag name. * * Because tag names are limited to US-ASCII there is no * need to perform any kind of Unicode normalization when * comparing; any character which could be impacted by such * normalization could not be part of a tag name. */ for ( $i = 0; $i < $tag_length; $i++ ) { $tag_char = $tag_name[ $i ]; $html_char = $html[ $at + $i ]; if ( $html_char !== $tag_char && strtoupper( $html_char ) !== $tag_char ) { $at += $i; continue 2; } } $at += $tag_length; $this->bytes_already_parsed = $at; if ( $at >= strlen( $html ) ) { return false; } /* * Ensure that the tag name terminates to avoid matching on * substrings of a longer tag name. For example, the sequence * "</textarearug" should not match for "</textarea" even * though "textarea" is found within the text. */ $c = $html[ $at ]; if ( ' ' !== $c && "\t" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) { continue; } while ( $this->parse_next_attribute() ) { continue; } $at = $this->bytes_already_parsed; if ( $at >= strlen( $this->html ) ) { return false; } if ( '>' === $html[ $at ] ) { $this->bytes_already_parsed = $at + 1; return true; } if ( $at + 1 >= strlen( $this->html ) ) { return false; } if ( '/' === $html[ $at ] && '>' === $html[ $at + 1 ] ) { $this->bytes_already_parsed = $at + 2; return true; } } return false; } /** * Skips contents of script tags. * * @since 6.2.0 * * @return bool Whether the script tag was closed before the end of the document. */ private function skip_script_data(): bool { $state = 'unescaped'; $html = $this->html; $doc_length = strlen( $html ); $at = $this->bytes_already_parsed; while ( false !== $at && $at < $doc_length ) { $at += strcspn( $html, '-<', $at ); /* * For all script states a "-->" transitions * back into the normal unescaped script mode, * even if that's the current state. */ if ( $at + 2 < $doc_length && '-' === $html[ $at ] && '-' === $html[ $at + 1 ] && '>' === $html[ $at + 2 ] ) { $at += 3; $state = 'unescaped'; continue; } if ( $at + 1 >= $doc_length ) { return false; } /* * Everything of interest past here starts with "<". * Check this character and advance position regardless. */ if ( '<' !== $html[ $at++ ] ) { continue; } /* * Unlike with "-->", the "<!--" only transitions * into the escaped mode if not already there. * * Inside the escaped modes it will be ignored; and * should never break out of the double-escaped * mode and back into the escaped mode. * * While this requires a mode change, it does not * impact the parsing otherwise, so continue * parsing after updating the state. */ if ( $at + 2 < $doc_length && '!' === $html[ $at ] && '-' === $html[ $at + 1 ] && '-' === $html[ $at + 2 ] ) { $at += 3; $state = 'unescaped' === $state ? 'escaped' : $state; continue; } if ( '/' === $html[ $at ] ) { $closer_potentially_starts_at = $at - 1; $is_closing = true; ++$at; } else { $is_closing = false; } /* * At this point the only remaining state-changes occur with the * <script> and </script> tags; unless one of these appears next, * proceed scanning to the next potential token in the text. */ if ( ! ( $at + 6 < $doc_length && ( 's' === $html[ $at ] || 'S' === $html[ $at ] ) && ( 'c' === $html[ $at + 1 ] || 'C' === $html[ $at + 1 ] ) && ( 'r' === $html[ $at + 2 ] || 'R' === $html[ $at + 2 ] ) && ( 'i' === $html[ $at + 3 ] || 'I' === $html[ $at + 3 ] ) && ( 'p' === $html[ $at + 4 ] || 'P' === $html[ $at + 4 ] ) && ( 't' === $html[ $at + 5 ] || 'T' === $html[ $at + 5 ] ) ) ) { ++$at; continue; } /* * Ensure that the script tag terminates to avoid matching on * substrings of a non-match. For example, the sequence * "<script123" should not end a script region even though * "<script" is found within the text. */ if ( $at + 6 >= $doc_length ) { continue; } $at += 6; $c = $html[ $at ]; if ( ' ' !== $c && "\t" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) { ++$at; continue; } if ( 'escaped' === $state && ! $is_closing ) { $state = 'double-escaped'; continue; } if ( 'double-escaped' === $state && $is_closing ) { $state = 'escaped'; continue; } if ( $is_closing ) { $this->bytes_already_parsed = $closer_potentially_starts_at; $this->tag_name_starts_at = $closer_potentially_starts_at; if ( $this->bytes_already_parsed >= $doc_length ) { return false; } while ( $this->parse_next_attribute() ) { continue; } if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( '>' === $html[ $this->bytes_already_parsed ] ) { ++$this->bytes_already_parsed; return true; } } ++$at; } return false; } /** * Parses the next tag. * * This will find and start parsing the next tag, including * the opening `<`, the potential closer `/`, and the tag * name. It does not parse the attributes or scan to the * closing `>`; these are left for other methods. * * @since 6.2.0 * @since 6.2.1 Support abruptly-closed comments, invalid-tag-closer-comments, and empty elements. * * @return bool Whether a tag was found before the end of the document. */ private function parse_next_tag(): bool { $this->after_tag(); $html = $this->html; $doc_length = strlen( $html ); $was_at = $this->bytes_already_parsed; $at = $was_at; while ( $at < $doc_length ) { $at = strpos( $html, '<', $at ); if ( false === $at ) { break; } if ( $at > $was_at ) { /* * A "<" normally starts a new HTML tag or syntax token, but in cases where the * following character can't produce a valid token, the "<" is instead treated * as plaintext and the parser should skip over it. This avoids a problem when * following earlier practices of typing emoji with text, e.g. "<3". This * should be a heart, not a tag. It's supposed to be rendered, not hidden. * * At this point the parser checks if this is one of those cases and if it is * will continue searching for the next "<" in search of a token boundary. * * @see https://html.spec.whatwg.org/#tag-open-state */ if ( 1 !== strspn( $html, '!/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1, 1 ) ) { ++$at; continue; } $this->parser_state = self::STATE_TEXT_NODE; $this->token_starts_at = $was_at; $this->token_length = $at - $was_at; $this->text_starts_at = $was_at; $this->text_length = $this->token_length; $this->bytes_already_parsed = $at; return true; } $this->token_starts_at = $at; if ( $at + 1 < $doc_length && '/' === $this->html[ $at + 1 ] ) { $this->is_closing_tag = true; ++$at; } else { $this->is_closing_tag = false; } /* * HTML tag names must start with [a-zA-Z] otherwise they are not tags. * For example, "<3" is rendered as text, not a tag opener. If at least * one letter follows the "<" then _it is_ a tag, but if the following * character is anything else it _is not a tag_. * * It's not uncommon to find non-tags starting with `<` in an HTML * document, so it's good for performance to make this pre-check before * continuing to attempt to parse a tag name. * * Reference: * * https://html.spec.whatwg.org/multipage/parsing.html#data-state * * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state */ $tag_name_prefix_length = strspn( $html, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1 ); if ( $tag_name_prefix_length > 0 ) { ++$at; $this->parser_state = self::STATE_MATCHED_TAG; $this->tag_name_starts_at = $at; $this->tag_name_length = $tag_name_prefix_length + strcspn( $html, " \t\f\r\n/>", $at + $tag_name_prefix_length ); $this->bytes_already_parsed = $at + $this->tag_name_length; return true; } /* * Abort if no tag is found before the end of * the document. There is nothing left to parse. */ if ( $at + 1 >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } /* * `<!` transitions to markup declaration open state * https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state */ if ( ! $this->is_closing_tag && '!' === $html[ $at + 1 ] ) { /* * `<!--` transitions to a comment state – apply further comment rules. * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state */ if ( 0 === substr_compare( $html, '--', $at + 2, 2 ) ) { $closer_at = $at + 4; // If it's not possible to close the comment then there is nothing more to scan. if ( $doc_length <= $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } // Abruptly-closed empty comments are a sequence of dashes followed by `>`. $span_of_dashes = strspn( $html, '-', $closer_at ); if ( '>' === $html[ $closer_at + $span_of_dashes ] ) { /* * @todo When implementing `set_modifiable_text()` ensure that updates to this token * don't break the syntax for short comments, e.g. `<!--->`. Unlike other comment * and bogus comment syntax, these leave no clear insertion point for text and * they need to be modified specially in order to contain text. E.g. to store * `?` as the modifiable text, the `<!--->` needs to become `<!--?-->`, which * involves inserting an additional `-` into the token after the modifiable text. */ $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT; $this->token_length = $closer_at + $span_of_dashes + 1 - $this->token_starts_at; // Only provide modifiable text if the token is long enough to contain it. if ( $span_of_dashes >= 2 ) { $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $span_of_dashes - 2; } $this->bytes_already_parsed = $closer_at + $span_of_dashes + 1; return true; } /* * Comments may be closed by either a --> or an invalid --!>. * The first occurrence closes the comment. * * See https://html.spec.whatwg.org/#parse-error-incorrectly-closed-comment */ --$closer_at; // Pre-increment inside condition below reduces risk of accidental infinite looping. while ( ++$closer_at < $doc_length ) { $closer_at = strpos( $html, '--', $closer_at ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( $closer_at + 2 < $doc_length && '>' === $html[ $closer_at + 2 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->token_length = $closer_at + 3 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 3; return true; } if ( $closer_at + 3 < $doc_length && '!' === $html[ $closer_at + 2 ] && '>' === $html[ $closer_at + 3 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_HTML_COMMENT; $this->token_length = $closer_at + 4 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 4; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 4; return true; } } } /* * `<!DOCTYPE` transitions to DOCTYPE state – skip to the nearest > * These are ASCII-case-insensitive. * https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state */ if ( $doc_length > $at + 8 && ( 'D' === $html[ $at + 2 ] || 'd' === $html[ $at + 2 ] ) && ( 'O' === $html[ $at + 3 ] || 'o' === $html[ $at + 3 ] ) && ( 'C' === $html[ $at + 4 ] || 'c' === $html[ $at + 4 ] ) && ( 'T' === $html[ $at + 5 ] || 't' === $html[ $at + 5 ] ) && ( 'Y' === $html[ $at + 6 ] || 'y' === $html[ $at + 6 ] ) && ( 'P' === $html[ $at + 7 ] || 'p' === $html[ $at + 7 ] ) && ( 'E' === $html[ $at + 8 ] || 'e' === $html[ $at + 8 ] ) ) { $closer_at = strpos( $html, '>', $at + 9 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_DOCTYPE; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 9; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; return true; } if ( 'html' !== $this->parsing_namespace && strlen( $html ) > $at + 8 && '[' === $html[ $at + 2 ] && 'C' === $html[ $at + 3 ] && 'D' === $html[ $at + 4 ] && 'A' === $html[ $at + 5 ] && 'T' === $html[ $at + 6 ] && 'A' === $html[ $at + 7 ] && '[' === $html[ $at + 8 ] ) { $closer_at = strpos( $html, ']]>', $at + 9 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_CDATA_NODE; $this->text_starts_at = $at + 9; $this->text_length = $closer_at - $this->text_starts_at; $this->token_length = $closer_at + 3 - $this->token_starts_at; $this->bytes_already_parsed = $closer_at + 3; return true; } /* * Anything else here is an incorrectly-opened comment and transitions * to the bogus comment state - skip to the nearest >. If no closer is * found then the HTML was truncated inside the markup declaration. */ $closer_at = strpos( $html, '>', $at + 1 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_INVALID_HTML; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; /* * Identify nodes that would be CDATA if HTML had CDATA sections. * * This section must occur after identifying the bogus comment end * because in an HTML parser it will span to the nearest `>`, even * if there's no `]]>` as would be required in an XML document. It * is therefore not possible to parse a CDATA section containing * a `>` in the HTML syntax. * * Inside foreign elements there is a discrepancy between browsers * and the specification on this. * * @todo Track whether the Tag Processor is inside a foreign element * and require the proper closing `]]>` in those cases. */ if ( $this->token_length >= 10 && '[' === $html[ $this->token_starts_at + 2 ] && 'C' === $html[ $this->token_starts_at + 3 ] && 'D' === $html[ $this->token_starts_at + 4 ] && 'A' === $html[ $this->token_starts_at + 5 ] && 'T' === $html[ $this->token_starts_at + 6 ] && 'A' === $html[ $this->token_starts_at + 7 ] && '[' === $html[ $this->token_starts_at + 8 ] && ']' === $html[ $closer_at - 1 ] && ']' === $html[ $closer_at - 2 ] ) { $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_CDATA_LOOKALIKE; $this->text_starts_at += 7; $this->text_length -= 9; } return true; } /* * </> is a missing end tag name, which is ignored. * * This was also known as the "presumptuous empty tag" * in early discussions as it was proposed to close * the nearest previous opening tag. * * See https://html.spec.whatwg.org/#parse-error-missing-end-tag-name */ if ( '>' === $html[ $at + 1 ] ) { // `<>` is interpreted as plaintext. if ( ! $this->is_closing_tag ) { ++$at; continue; } $this->parser_state = self::STATE_PRESUMPTUOUS_TAG; $this->token_length = $at + 2 - $this->token_starts_at; $this->bytes_already_parsed = $at + 2; return true; } /* * `<?` transitions to a bogus comment state – skip to the nearest > * See https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state */ if ( ! $this->is_closing_tag && '?' === $html[ $at + 1 ] ) { $closer_at = strpos( $html, '>', $at + 2 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_COMMENT; $this->comment_type = self::COMMENT_AS_INVALID_HTML; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; /* * Identify a Processing Instruction node were HTML to have them. * * This section must occur after identifying the bogus comment end * because in an HTML parser it will span to the nearest `>`, even * if there's no `?>` as would be required in an XML document. It * is therefore not possible to parse a Processing Instruction node * containing a `>` in the HTML syntax. * * XML allows for more target names, but this code only identifies * those with ASCII-representable target names. This means that it * may identify some Processing Instruction nodes as bogus comments, * but it will not misinterpret the HTML structure. By limiting the * identification to these target names the Tag Processor can avoid * the need to start parsing UTF-8 sequences. * * > NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | * [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | * [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | * [#x10000-#xEFFFF] * > NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] * * @todo Processing instruction nodes in SGML may contain any kind of markup. XML defines a * special case with `<?xml ... ?>` syntax, but the `?` is part of the bogus comment. * * @see https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-PITarget */ if ( $this->token_length >= 5 && '?' === $html[ $closer_at - 1 ] ) { $comment_text = substr( $html, $this->token_starts_at + 2, $this->token_length - 4 ); $pi_target_length = strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_' ); if ( 0 < $pi_target_length ) { $pi_target_length += strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:_-.', $pi_target_length ); $this->comment_type = self::COMMENT_AS_PI_NODE_LOOKALIKE; $this->tag_name_starts_at = $this->token_starts_at + 2; $this->tag_name_length = $pi_target_length; $this->text_starts_at += $pi_target_length; $this->text_length -= $pi_target_length + 1; } } return true; } /* * If a non-alpha starts the tag name in a tag closer it's a comment. * Find the first `>`, which closes the comment. * * This parser classifies these particular comments as special "funky comments" * which are made available for further processing. * * See https://html.spec.whatwg.org/#parse-error-invalid-first-character-of-tag-name */ if ( $this->is_closing_tag ) { // No chance of finding a closer. if ( $at + 3 > $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $closer_at = strpos( $html, '>', $at + 2 ); if ( false === $closer_at ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->parser_state = self::STATE_FUNKY_COMMENT; $this->token_length = $closer_at + 1 - $this->token_starts_at; $this->text_starts_at = $this->token_starts_at + 2; $this->text_length = $closer_at - $this->text_starts_at; $this->bytes_already_parsed = $closer_at + 1; return true; } ++$at; } /* * This does not imply an incomplete parse; it indicates that there * can be nothing left in the document other than a #text node. */ $this->parser_state = self::STATE_TEXT_NODE; $this->token_starts_at = $was_at; $this->token_length = $doc_length - $was_at; $this->text_starts_at = $was_at; $this->text_length = $this->token_length; $this->bytes_already_parsed = $doc_length; return true; } /** * Parses the next attribute. * * @since 6.2.0 * * @return bool Whether an attribute was found before the end of the document. */ private function parse_next_attribute(): bool { $doc_length = strlen( $this->html ); // Skip whitespace and slashes. $this->bytes_already_parsed += strspn( $this->html, " \t\f\r\n/", $this->bytes_already_parsed ); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } /* * Treat the equal sign as a part of the attribute * name if it is the first encountered byte. * * @see https://html.spec.whatwg.org/multipage/parsing.html#before-attribute-name-state */ $name_length = '=' === $this->html[ $this->bytes_already_parsed ] ? 1 + strcspn( $this->html, "=/> \t\f\r\n", $this->bytes_already_parsed + 1 ) : strcspn( $this->html, "=/> \t\f\r\n", $this->bytes_already_parsed ); // No attribute, just tag closer. if ( 0 === $name_length || $this->bytes_already_parsed + $name_length >= $doc_length ) { return false; } $attribute_start = $this->bytes_already_parsed; $attribute_name = substr( $this->html, $attribute_start, $name_length ); $this->bytes_already_parsed += $name_length; if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $this->skip_whitespace(); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } $has_value = '=' === $this->html[ $this->bytes_already_parsed ]; if ( $has_value ) { ++$this->bytes_already_parsed; $this->skip_whitespace(); if ( $this->bytes_already_parsed >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } switch ( $this->html[ $this->bytes_already_parsed ] ) { case "'": case '"': $quote = $this->html[ $this->bytes_already_parsed ]; $value_start = $this->bytes_already_parsed + 1; $end_quote_at = strpos( $this->html, $quote, $value_start ); $end_quote_at = false === $end_quote_at ? $doc_length : $end_quote_at; $value_length = $end_quote_at - $value_start; $attribute_end = $end_quote_at + 1; $this->bytes_already_parsed = $attribute_end; break; default: $value_start = $this->bytes_already_parsed; $value_length = strcspn( $this->html, "> \t\f\r\n", $value_start ); $attribute_end = $value_start + $value_length; $this->bytes_already_parsed = $attribute_end; } } else { $value_start = $this->bytes_already_parsed; $value_length = 0; $attribute_end = $attribute_start + $name_length; } if ( $attribute_end >= $doc_length ) { $this->parser_state = self::STATE_INCOMPLETE_INPUT; return false; } if ( $this->is_closing_tag ) { return true; } /* * > There must never be two or more attributes on * > the same start tag whose names are an ASCII * > case-insensitive match for each other. * - HTML 5 spec * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive */ $comparable_name = strtolower( $attribute_name ); // If an attribute is listed many times, only use the first declaration and ignore the rest. if ( ! isset( $this->attributes[ $comparable_name ] ) ) { $this->attributes[ $comparable_name ] = new WP_HTML_Attribute_Token( $attribute_name, $value_start, $value_length, $attribute_start, $attribute_end - $attribute_start, ! $has_value ); return true; } /* * Track the duplicate attributes so if we remove it, all disappear together. * * While `$this->duplicated_attributes` could always be stored as an `array()`, * which would simplify the logic here, storing a `null` and only allocating * an array when encountering duplicates avoids needless allocations in the * normative case of parsing tags with no duplicate attributes. */ $duplicate_span = new WP_HTML_Span( $attribute_start, $attribute_end - $attribute_start ); if ( null === $this->duplicate_attributes ) { $this->duplicate_attributes = array( $comparable_name => array( $duplicate_span ) ); } elseif ( ! isset( $this->duplicate_attributes[ $comparable_name ] ) ) { $this->duplicate_attributes[ $comparable_name ] = array( $duplicate_span ); } else { $this->duplicate_attributes[ $comparable_name ][] = $duplicate_span; } return true; } /** * Move the internal cursor past any immediate successive whitespace. * * @since 6.2.0 */ private function skip_whitespace(): void { $this->bytes_already_parsed += strspn( $this->html, " \t\f\r\n", $this->bytes_already_parsed ); } /** * Applies attribute updates and cleans up once a tag is fully parsed. * * @since 6.2.0 */ private function after_tag(): void { /* * There could be lexical updates enqueued for an attribute that * also exists on the next tag. In order to avoid conflating the * attributes across the two tags, lexical updates with names * need to be flushed to raw lexical updates. */ $this->class_name_updates_to_attributes_updates(); /* * Purge updates if there are too many. The actual count isn't * scientific, but a few values from 100 to a few thousand were * tests to find a practically-useful limit. * * If the update queue grows too big, then the Tag Processor * will spend more time iterating through them and lose the * efficiency gains of deferring applying them. */ if ( 1000 < count( $this->lexical_updates ) ) { $this->get_updated_html(); } foreach ( $this->lexical_updates as $name => $update ) { /* * Any updates appearing after the cursor should be applied * before proceeding, otherwise they may be overlooked. */ if ( $update->start >= $this->bytes_already_parsed ) { $this->get_updated_html(); break; } if ( is_int( $name ) ) { continue; } $this->lexical_updates[] = $update; unset( $this->lexical_updates[ $name ] ); } $this->token_starts_at = null; $this->token_length = null; $this->tag_name_starts_at = null; $this->tag_name_length = null; $this->text_starts_at = 0; $this->text_length = 0; $this->is_closing_tag = null; $this->attributes = array(); $this->comment_type = null; $this->text_node_classification = self::TEXT_IS_GENERIC; $this->duplicate_attributes = null; } /** * Converts class name updates into tag attributes updates * (they are accumulated in different data formats for performance). * * @since 6.2.0 * * @see WP_HTML_Tag_Processor::$lexical_updates * @see WP_HTML_Tag_Processor::$classname_updates */ private function class_name_updates_to_attributes_updates(): void { if ( count( $this->classname_updates ) === 0 ) { return; } $existing_class = $this->get_enqueued_attribute_value( 'class' ); if ( null === $existing_class || true === $existing_class ) { $existing_class = ''; } if ( false === $existing_class && isset( $this->attributes['class'] ) ) { $existing_class = substr( $this->html, $this->attributes['class']->value_starts_at, $this->attributes['class']->value_length ); } if ( false === $existing_class ) { $existing_class = ''; } /** * Updated "class" attribute value. * * This is incrementally built while scanning through the existing class * attribute, skipping removed classes on the way, and then appending * added classes at the end. Only when finished processing will the * value contain the final new value. * @var string $class */ $class = ''; /** * Tracks the cursor position in the existing * class attribute value while parsing. * * @var int $at */ $at = 0; /** * Indicates if there's any need to modify the existing class attribute. * * If a call to `add_class()` and `remove_class()` wouldn't impact * the `class` attribute value then there's no need to rebuild it. * For example, when adding a class that's already present or * removing one that isn't. * * This flag enables a performance optimization when none of the enqueued * class updates would impact the `class` attribute; namely, that the * processor can continue without modifying the input document, as if * none of the `add_class()` or `remove_class()` calls had been made. * * This flag is set upon the first change that requires a string update. * * @var bool $modified */ $modified = false; $seen = array(); $to_remove = array(); $is_quirks = self::QUIRKS_MODE === $this->compat_mode; if ( $is_quirks ) { foreach ( $this->classname_updates as $updated_name => $action ) { if ( self::REMOVE_CLASS === $action ) { $to_remove[] = strtolower( $updated_name ); } } } else { foreach ( $this->classname_updates as $updated_name => $action ) { if ( self::REMOVE_CLASS === $action ) { $to_remove[] = $updated_name; } } } // Remove unwanted classes by only copying the new ones. $existing_class_length = strlen( $existing_class ); while ( $at < $existing_class_length ) { // Skip to the first non-whitespace character. $ws_at = $at; $ws_length = strspn( $existing_class, " \t\f\r\n", $ws_at ); $at += $ws_length; // Capture the class name – it's everything until the next whitespace. $name_length = strcspn( $existing_class, " \t\f\r\n", $at ); if ( 0 === $name_length ) { // If no more class names are found then that's the end. break; } $name = substr( $existing_class, $at, $name_length ); $comparable_class_name = $is_quirks ? strtolower( $name ) : $name; $at += $name_length; // If this class is marked for removal, remove it and move on to the next one. if ( in_array( $comparable_class_name, $to_remove, true ) ) { $modified = true; continue; } // If a class has already been seen then skip it; it should not be added twice. if ( in_array( $comparable_class_name, $seen, true ) ) { continue; } $seen[] = $comparable_class_name; /* * Otherwise, append it to the new "class" attribute value. * * There are options for handling whitespace between tags. * Preserving the existing whitespace produces fewer changes * to the HTML content and should clarify the before/after * content when debugging the modified output. * * This approach contrasts normalizing the inter-class * whitespace to a single space, which might appear cleaner * in the output HTML but produce a noisier change. */ if ( '' !== $class ) { $class .= substr( $existing_class, $ws_at, $ws_length ); } $class .= $name; } // Add new classes by appending those which haven't already been seen. foreach ( $this->classname_updates as $name => $operation ) { $comparable_name = $is_quirks ? strtolower( $name ) : $name; if ( self::ADD_CLASS === $operation && ! in_array( $comparable_name, $seen, true ) ) { $modified = true; $class .= strlen( $class ) > 0 ? ' ' : ''; $class .= $name; } } $this->classname_updates = array(); if ( ! $modified ) { return; } if ( strlen( $class ) > 0 ) { $this->set_attribute( 'class', $class ); } else { $this->remove_attribute( 'class' ); } } /** * Applies attribute updates to HTML document. * * @since 6.2.0 * @since 6.2.1 Accumulates shift for internal cursor and passed pointer. * @since 6.3.0 Invalidate any bookmarks whose targets are overwritten. * * @param int $shift_this_point Accumulate and return shift for this position. * @return int How many bytes the given pointer moved in response to the updates. */ private function apply_attributes_updates( int $shift_this_point ): int { if ( ! count( $this->lexical_updates ) ) { return 0; } $accumulated_shift_for_given_point = 0; /* * Attribute updates can be enqueued in any order but updates * to the document must occur in lexical order; that is, each * replacement must be made before all others which follow it * at later string indices in the input document. * * Sorting avoid making out-of-order replacements which * can lead to mangled output, partially-duplicated * attributes, and overwritten attributes. */ usort( $this->lexical_updates, array( self::class, 'sort_start_ascending' ) ); $bytes_already_copied = 0; $output_buffer = ''; foreach ( $this->lexical_updates as $diff ) { $shift = strlen( $diff->text ) - $diff->length; // Adjust the cursor position by however much an update affects it. if ( $diff->start < $this->bytes_already_parsed ) { $this->bytes_already_parsed += $shift; } // Accumulate shift of the given pointer within this function call. if ( $diff->start < $shift_this_point ) { $accumulated_shift_for_given_point += $shift; } $output_buffer .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied ); $output_buffer .= $diff->text; $bytes_already_copied = $diff->start + $diff->length; } $this->html = $output_buffer . substr( $this->html, $bytes_already_copied ); /* * Adjust bookmark locations to account for how the text * replacements adjust offsets in the input document. */ foreach ( $this->bookmarks as $bookmark_name => $bookmark ) { $bookmark_end = $bookmark->start + $bookmark->length; /* * Each lexical update which appears before the bookmark's endpoints * might shift the offsets for those endpoints. Loop through each change * and accumulate the total shift for each bookmark, then apply that * shift after tallying the full delta. */ $head_delta = 0; $tail_delta = 0; foreach ( $this->lexical_updates as $diff ) { $diff_end = $diff->start + $diff->length; if ( $bookmark->start < $diff->start && $bookmark_end < $diff->start ) { break; } if ( $bookmark->start >= $diff->start && $bookmark_end < $diff_end ) { $this->release_bookmark( $bookmark_name ); continue 2; } $delta = strlen( $diff->text ) - $diff->length; if ( $bookmark->start >= $diff->start ) { $head_delta += $delta; } if ( $bookmark_end >= $diff_end ) { $tail_delta += $delta; } } $bookmark->start += $head_delta; $bookmark->length += $tail_delta - $head_delta; } $this->lexical_updates = array(); return $accumulated_shift_for_given_point; } /** * Checks whether a bookmark with the given name exists. * * @since 6.3.0 * * @param string $bookmark_name Name to identify a bookmark that potentially exists. * @return bool Whether that bookmark exists. */ public function has_bookmark( $bookmark_name ): bool { return array_key_exists( $bookmark_name, $this->bookmarks ); } /** * Move the internal cursor in the Tag Processor to a given bookmark's location. * * In order to prevent accidental infinite loops, there's a * maximum limit on the number of times seek() can be called. * * @since 6.2.0 * * @param string $bookmark_name Jump to the place in the document identified by this bookmark name. * @return bool Whether the internal cursor was successfully moved to the bookmark's location. */ public function seek( $bookmark_name ): bool { if ( ! array_key_exists( $bookmark_name, $this->bookmarks ) ) { _doing_it_wrong( __METHOD__, __( 'Unknown bookmark name.' ), '6.2.0' ); return false; } $existing_bookmark = $this->bookmarks[ $bookmark_name ]; if ( $this->token_starts_at === $existing_bookmark->start && $this->token_length === $existing_bookmark->length ) { return true; } if ( ++$this->seek_count > static::MAX_SEEK_OPS ) { _doing_it_wrong( __METHOD__, __( 'Too many calls to seek() - this can lead to performance issues.' ), '6.2.0' ); return false; } // Flush out any pending updates to the document. $this->get_updated_html(); // Point this tag processor before the sought tag opener and consume it. $this->bytes_already_parsed = $this->bookmarks[ $bookmark_name ]->start; $this->parser_state = self::STATE_READY; return $this->next_token(); } /** * Compare two WP_HTML_Text_Replacement objects. * * @since 6.2.0 * * @param WP_HTML_Text_Replacement $a First attribute update. * @param WP_HTML_Text_Replacement $b Second attribute update. * @return int Comparison value for string order. */ private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HTML_Text_Replacement $b ): int { $by_start = $a->start - $b->start; if ( 0 !== $by_start ) { return $by_start; } $by_text = isset( $a->text, $b->text ) ? strcmp( $a->text, $b->text ) : 0; if ( 0 !== $by_text ) { return $by_text; } /* * This code should be unreachable, because it implies the two replacements * start at the same location and contain the same text. */ return $a->length - $b->length; } /** * Return the enqueued value for a given attribute, if one exists. * * Enqueued updates can take different data types: * - If an update is enqueued and is boolean, the return will be `true` * - If an update is otherwise enqueued, the return will be the string value of that update. * - If an attribute is enqueued to be removed, the return will be `null` to indicate that. * - If no updates are enqueued, the return will be `false` to differentiate from "removed." * * @since 6.2.0 * * @param string $comparable_name The attribute name in its comparable form. * @return string|boolean|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 ) { return false; } if ( ! isset( $this->lexical_updates[ $comparable_name ] ) ) { return false; } $enqueued_text = $this->lexical_updates[ $comparable_name ]->text; // Removed attributes erase the entire span. if ( '' === $enqueued_text ) { return null; } /* * Boolean attribute updates are just the attribute name without a corresponding value. * * This value might differ from the given comparable name in that there could be leading * or trailing whitespace, and that the casing follows the name given in `set_attribute`. * * Example: * * $p->set_attribute( 'data-TEST-id', 'update' ); * 'update' === $p->get_enqueued_attribute_value( 'data-test-id' ); * * Detect this difference based on the absence of the `=`, which _must_ exist in any * attribute containing a value, e.g. `<input type="text" enabled />`. * ¹ ² * 1. Attribute with a string value. * 2. Boolean attribute whose value is `true`. */ $equals_at = strpos( $enqueued_text, '=' ); if ( false === $equals_at ) { return true; } /* * Finally, a normal update's value will appear after the `=` and * be double-quoted, as performed incidentally by `set_attribute`. * * e.g. `type="text"` * ¹² ³ * 1. Equals is here. * 2. Double-quoting starts one after the equals sign. * 3. Double-quoting ends at the last character in the update. */ $enqueued_value = substr( $enqueued_text, $equals_at + 2, -1 ); return WP_HTML_Decoder::decode_attribute( $enqueued_value ); } /** * Returns the value of a requested attribute from a matched tag opener if that attribute exists. * * Example: * * $p = new WP_HTML_Tag_Processor( '<div enabled class="test" data-test-id="14">Test</div>' ); * $p->next_tag( array( 'class_name' => 'test' ) ) === true; * $p->get_attribute( 'data-test-id' ) === '14'; * $p->get_attribute( 'enabled' ) === true; * $p->get_attribute( 'aria-label' ) === null; * * $p->next_tag() === false; * $p->get_attribute( 'class' ) === null; * * @since 6.2.0 * * @param string $name Name of attribute whose value is requested. * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`. */ public function get_attribute( $name ) { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $comparable = strtolower( $name ); /* * For every attribute other than `class` it's possible to perform a quick check if * there's an enqueued lexical update whose value takes priority over what's found in * the input document. * * The `class` attribute is special though because of the exposed helpers `add_class` * and `remove_class`. These form a builder for the `class` attribute, so an additional * check for enqueued class changes is required in addition to the check for any enqueued * attribute values. If any exist, those enqueued class changes must first be flushed out * into an attribute value update. */ if ( 'class' === $name ) { $this->class_name_updates_to_attributes_updates(); } // Return any enqueued attribute value updates if they exist. $enqueued_value = $this->get_enqueued_attribute_value( $comparable ); if ( false !== $enqueued_value ) { return $enqueued_value; } if ( ! isset( $this->attributes[ $comparable ] ) ) { return null; } $attribute = $this->attributes[ $comparable ]; /* * This flag distinguishes an attribute with no value * from an attribute with an empty string value. For * unquoted attributes this could look very similar. * It refers to whether an `=` follows the name. * * e.g. <div boolean-attribute empty-attribute=></div> * ¹ ² * 1. Attribute `boolean-attribute` is `true`. * 2. Attribute `empty-attribute` is `""`. */ if ( true === $attribute->is_true ) { return true; } $raw_value = substr( $this->html, $attribute->value_starts_at, $attribute->value_length ); return WP_HTML_Decoder::decode_attribute( $raw_value ); } /** * Gets lowercase names of all attributes matching a given prefix in the current tag. * * Note that matching is case-insensitive. This is in accordance with the spec: * * > There must never be two or more attributes on * > the same start tag whose names are an ASCII * > case-insensitive match for each other. * - HTML 5 spec * * Example: * * $p = new WP_HTML_Tag_Processor( '<div data-ENABLED class="test" DATA-test-id="14">Test</div>' ); * $p->next_tag( array( 'class_name' => 'test' ) ) === true; * $p->get_attribute_names_with_prefix( 'data-' ) === array( 'data-enabled', 'data-test-id' ); * * $p->next_tag() === false; * $p->get_attribute_names_with_prefix( 'data-' ) === null; * * @since 6.2.0 * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive * * @param string $prefix Prefix of requested attribute names. * @return array|null List of attribute names, or `null` when no tag opener is matched. */ public function get_attribute_names_with_prefix( $prefix ): ?array { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return null; } $comparable = strtolower( $prefix ); $matches = array(); foreach ( array_keys( $this->attributes ) as $attr_name ) { if ( str_starts_with( $attr_name, $comparable ) ) { $matches[] = $attr_name; } } return $matches; } /** * Returns the namespace of the matched token. * * @since 6.7.0 * * @return string One of 'html', 'math', or 'svg'. */ public function get_namespace(): string { return $this->parsing_namespace; } /** * Returns the uppercase name of the matched tag. * * Example: * * $p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' ); * $p->next_tag() === true; * $p->get_tag() === 'DIV'; * * $p->next_tag() === false; * $p->get_tag() === null; * * @since 6.2.0 * * @return string|null Name of currently matched tag in input HTML, or `null` if none found. */ public function get_tag(): ?string { if ( null === $this->tag_name_starts_at ) { return null; } $tag_name = substr( $this->html, $this->tag_name_starts_at, $this->tag_name_length ); if ( self::STATE_MATCHED_TAG === $this->parser_state ) { return strtoupper( $tag_name ); } if ( self::STATE_COMMENT === $this->parser_state && self::COMMENT_AS_PI_NODE_LOOKALIKE === $this->get_comment_type() ) { return $tag_name; } return null; } /** * Returns the adjusted tag name for a given token, taking into * account the current parsing context, whether HTML, SVG, or MathML. * * @since 6.7.0 * * @return string|null Name of current tag name. */ public function get_qualified_tag_name(): ?string { $tag_name = $this->get_tag(); if ( null === $tag_name ) { return null; } if ( 'html' === $this->get_namespace() ) { return $tag_name; } $lower_tag_name = strtolower( $tag_name ); if ( 'math' === $this->get_namespace() ) { return $lower_tag_name; } if ( 'svg' === $this->get_namespace() ) { switch ( $lower_tag_name ) { case 'altglyph': return 'altGlyph'; case 'altglyphdef': return 'altGlyphDef'; case 'altglyphitem': return 'altGlyphItem'; case 'animatecolor': return 'animateColor'; case 'animatemotion': return 'animateMotion'; case 'animatetransform': return 'animateTransform'; case 'clippath': return 'clipPath'; case 'feblend': return 'feBlend'; case 'fecolormatrix': return 'feColorMatrix'; case 'fecomponenttransfer': return 'feComponentTransfer'; case 'fecomposite': return 'feComposite'; case 'feconvolvematrix': return 'feConvolveMatrix'; case 'fediffuselighting': return 'feDiffuseLighting'; case 'fedisplacementmap': return 'feDisplacementMap'; case 'fedistantlight': return 'feDistantLight'; case 'fedropshadow': return 'feDropShadow'; case 'feflood': return 'feFlood'; case 'fefunca': return 'feFuncA'; case 'fefuncb': return 'feFuncB'; case 'fefuncg': return 'feFuncG'; case 'fefuncr': return 'feFuncR'; case 'fegaussianblur': return 'feGaussianBlur'; case 'feimage': return 'feImage'; case 'femerge': return 'feMerge'; case 'femergenode': return 'feMergeNode'; case 'femorphology': return 'feMorphology'; case 'feoffset': return 'feOffset'; case 'fepointlight': return 'fePointLight'; case 'fespecularlighting': return 'feSpecularLighting'; case 'fespotlight': return 'feSpotLight'; case 'fetile': return 'feTile'; case 'feturbulence': return 'feTurbulence'; case 'foreignobject': return 'foreignObject'; case 'glyphref': return 'glyphRef'; case 'lineargradient': return 'linearGradient'; case 'radialgradient': return 'radialGradient'; case 'textpath': return 'textPath'; default: return $lower_tag_name; } } // This unnecessary return prevents tools from inaccurately reporting type errors. return $tag_name; } /** * Returns the adjusted attribute name for a given attribute, taking into * account the current parsing context, whether HTML, SVG, or MathML. * * @since 6.7.0 * * @param string $attribute_name Which attribute to adjust. * * @return string|null */ public function get_qualified_attribute_name( $attribute_name ): ?string { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return null; } $namespace = $this->get_namespace(); $lower_name = strtolower( $attribute_name ); if ( 'math' === $namespace && 'definitionurl' === $lower_name ) { return 'definitionURL'; } if ( 'svg' === $this->get_namespace() ) { switch ( $lower_name ) { case 'attributename': return 'attributeName'; case 'attributetype': return 'attributeType'; case 'basefrequency': return 'baseFrequency'; case 'baseprofile': return 'baseProfile'; case 'calcmode': return 'calcMode'; case 'clippathunits': return 'clipPathUnits'; case 'diffuseconstant': return 'diffuseConstant'; case 'edgemode': return 'edgeMode'; case 'filterunits': return 'filterUnits'; case 'glyphref': return 'glyphRef'; case 'gradienttransform': return 'gradientTransform'; case 'gradientunits': return 'gradientUnits'; case 'kernelmatrix': return 'kernelMatrix'; case 'kernelunitlength': return 'kernelUnitLength'; case 'keypoints': return 'keyPoints'; case 'keysplines': return 'keySplines'; case 'keytimes': return 'keyTimes'; case 'lengthadjust': return 'lengthAdjust'; case 'limitingconeangle': return 'limitingConeAngle'; case 'markerheight': return 'markerHeight'; case 'markerunits': return 'markerUnits'; case 'markerwidth': return 'markerWidth'; case 'maskcontentunits': return 'maskContentUnits'; case 'maskunits': return 'maskUnits'; case 'numoctaves': return 'numOctaves'; case 'pathlength': return 'pathLength'; case 'patterncontentunits': return 'patternContentUnits'; case 'patterntransform': return 'patternTransform'; case 'patternunits': return 'patternUnits'; case 'pointsatx': return 'pointsAtX'; case 'pointsaty': return 'pointsAtY'; case 'pointsatz': return 'pointsAtZ'; case 'preservealpha': return 'preserveAlpha'; case 'preserveaspectratio': return 'preserveAspectRatio'; case 'primitiveunits': return 'primitiveUnits'; case 'refx': return 'refX'; case 'refy': return 'refY'; case 'repeatcount': return 'repeatCount'; case 'repeatdur': return 'repeatDur'; case 'requiredextensions': return 'requiredExtensions'; case 'requiredfeatures': return 'requiredFeatures'; case 'specularconstant': return 'specularConstant'; case 'specularexponent': return 'specularExponent'; case 'spreadmethod': return 'spreadMethod'; case 'startoffset': return 'startOffset'; case 'stddeviation': return 'stdDeviation'; case 'stitchtiles': return 'stitchTiles'; case 'surfacescale': return 'surfaceScale'; case 'systemlanguage': return 'systemLanguage'; case 'tablevalues': return 'tableValues'; case 'targetx': return 'targetX'; case 'targety': return 'targetY'; case 'textlength': return 'textLength'; case 'viewbox': return 'viewBox'; case 'viewtarget': return 'viewTarget'; case 'xchannelselector': return 'xChannelSelector'; case 'ychannelselector': return 'yChannelSelector'; case 'zoomandpan': return 'zoomAndPan'; } } if ( 'html' !== $namespace ) { switch ( $lower_name ) { case 'xlink:actuate': return 'xlink actuate'; case 'xlink:arcrole': return 'xlink arcrole'; case 'xlink:href': return 'xlink href'; case 'xlink:role': return 'xlink role'; case 'xlink:show': return 'xlink show'; case 'xlink:title': return 'xlink title'; case 'xlink:type': return 'xlink type'; case 'xml:lang': return 'xml lang'; case 'xml:space': return 'xml space'; case 'xmlns': return 'xmlns'; case 'xmlns:xlink': return 'xmlns xlink'; } } return $attribute_name; } /** * Indicates if the currently matched tag contains the self-closing flag. * * No HTML elements ought to have the self-closing flag and for those, the self-closing * flag will be ignored. For void elements this is benign because they "self close" * automatically. For non-void HTML elements though problems will appear if someone * intends to use a self-closing element in place of that element with an empty body. * For HTML foreign elements and custom elements the self-closing flag determines if * they self-close or not. * * This function does not determine if a tag is self-closing, * but only if the self-closing flag is present in the syntax. * * @since 6.3.0 * * @return bool Whether the currently matched tag contains the self-closing flag. */ public function has_self_closing_flag(): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return false; } /* * The self-closing flag is the solidus at the _end_ of the tag, not the beginning. * * Example: * * <figure /> * ^ this appears one character before the end of the closing ">". */ return '/' === $this->html[ $this->token_starts_at + $this->token_length - 2 ]; } /** * Indicates if the current tag token is a tag closer. * * Example: * * $p = new WP_HTML_Tag_Processor( '<div></div>' ); * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); * $p->is_tag_closer() === false; * * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); * $p->is_tag_closer() === true; * * @since 6.2.0 * @since 6.7.0 Reports all BR tags as opening tags. * * @return bool Whether the current tag is a tag closer. */ public function is_tag_closer(): bool { return ( self::STATE_MATCHED_TAG === $this->parser_state && $this->is_closing_tag && /* * The BR tag can only exist as an opening tag. If something like `</br>` * appears then the HTML parser will treat it as an opening tag with no * attributes. The BR tag is unique in this way. * * @see https://html.spec.whatwg.org/#parsing-main-inbody */ 'BR' !== $this->get_tag() ); } /** * Indicates the kind of matched token, if any. * * This differs from `get_token_name()` in that it always * returns a static string indicating the type, whereas * `get_token_name()` may return values derived from the * token itself, such as a tag name or processing * instruction tag. * * Possible values: * - `#tag` when matched on a tag. * - `#text` when matched on a text node. * - `#cdata-section` when matched on a CDATA node. * - `#comment` when matched on a comment. * - `#doctype` when matched on a DOCTYPE declaration. * - `#presumptuous-tag` when matched on an empty tag closer. * - `#funky-comment` when matched on a funky comment. * * @since 6.5.0 * * @return string|null What kind of token is matched, or null. */ public function get_token_type(): ?string { switch ( $this->parser_state ) { case self::STATE_MATCHED_TAG: return '#tag'; case self::STATE_DOCTYPE: return '#doctype'; default: return $this->get_token_name(); } } /** * Returns the node name represented by the token. * * This matches the DOM API value `nodeName`. Some values * are static, such as `#text` for a text node, while others * are dynamically generated from the token itself. * * Dynamic names: * - Uppercase tag name for tag matches. * - `html` for DOCTYPE declarations. * * Note that if the Tag Processor is not matched on a token * then this function will return `null`, either because it * hasn't yet found a token or because it reached the end * of the document without matching a token. * * @since 6.5.0 * * @return string|null Name of the matched token. */ public function get_token_name(): ?string { switch ( $this->parser_state ) { case self::STATE_MATCHED_TAG: return $this->get_tag(); case self::STATE_TEXT_NODE: return '#text'; case self::STATE_CDATA_NODE: return '#cdata-section'; case self::STATE_COMMENT: return '#comment'; case self::STATE_DOCTYPE: return 'html'; case self::STATE_PRESUMPTUOUS_TAG: return '#presumptuous-tag'; case self::STATE_FUNKY_COMMENT: return '#funky-comment'; } return null; } /** * Indicates what kind of comment produced the comment node. * * Because there are different kinds of HTML syntax which produce * comments, the Tag Processor tracks and exposes this as a type * for the comment. Nominally only regular HTML comments exist as * they are commonly known, but a number of unrelated syntax errors * also produce comments. * * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT * @see self::COMMENT_AS_CDATA_LOOKALIKE * @see self::COMMENT_AS_INVALID_HTML * @see self::COMMENT_AS_HTML_COMMENT * @see self::COMMENT_AS_PI_NODE_LOOKALIKE * * @since 6.5.0 * * @return string|null */ public function get_comment_type(): ?string { if ( self::STATE_COMMENT !== $this->parser_state ) { return null; } return $this->comment_type; } /** * Returns the text of a matched comment or null if not on a comment type node. * * This method returns the entire text content of a comment node as it * would appear in the browser. * * This differs from {@see ::get_modifiable_text()} in that certain comment * types in the HTML API cannot allow their entire comment text content to * be modified. Namely, "bogus comments" of the form `<?not allowed in html>` * will create a comment whose text content starts with `?`. Note that if * that character were modified, it would be possible to change the node * type. * * @since 6.7.0 * * @return string|null The comment text as it would appear in the browser or null * if not on a comment type node. */ public function get_full_comment_text(): ?string { if ( self::STATE_FUNKY_COMMENT === $this->parser_state ) { return $this->get_modifiable_text(); } if ( self::STATE_COMMENT !== $this->parser_state ) { return null; } switch ( $this->get_comment_type() ) { case self::COMMENT_AS_HTML_COMMENT: case self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT: return $this->get_modifiable_text(); case self::COMMENT_AS_CDATA_LOOKALIKE: return "[CDATA[{$this->get_modifiable_text()}]]"; case self::COMMENT_AS_PI_NODE_LOOKALIKE: return "?{$this->get_tag()}{$this->get_modifiable_text()}?"; /* * This represents "bogus comments state" from HTML tokenization. * This can be entered by `<?` or `<!`, where `?` is included in * the comment text but `!` is not. */ case self::COMMENT_AS_INVALID_HTML: $preceding_character = $this->html[ $this->text_starts_at - 1 ]; $comment_start = '?' === $preceding_character ? '?' : ''; return "{$comment_start}{$this->get_modifiable_text()}"; } return null; } /** * Subdivides a matched text node, splitting NULL byte sequences and decoded whitespace as * distinct nodes prefixes. * * Note that once anything that's neither a NULL byte nor decoded whitespace is * encountered, then the remainder of the text node is left intact as generic text. * * - The HTML Processor uses this to apply distinct rules for different kinds of text. * - Inter-element whitespace can be detected and skipped with this method. * * Text nodes aren't eagerly subdivided because there's no need to split them unless * decisions are being made on NULL byte sequences or whitespace-only text. * * Example: * * $processor = new WP_HTML_Tag_Processor( "\x00Apples & Oranges" ); * true === $processor->next_token(); // Text is "Apples & Oranges". * true === $processor->subdivide_text_appropriately(); // Text is "". * true === $processor->next_token(); // Text is "Apples & Oranges". * false === $processor->subdivide_text_appropriately(); * * $processor = new WP_HTML_Tag_Processor( " \r\n\tMore" ); * true === $processor->next_token(); // Text is " ␉More". * true === $processor->subdivide_text_appropriately(); // Text is " ␉". * true === $processor->next_token(); // Text is "More". * false === $processor->subdivide_text_appropriately(); * * @since 6.7.0 * * @return bool Whether the text node was subdivided. */ public function subdivide_text_appropriately(): bool { if ( self::STATE_TEXT_NODE !== $this->parser_state ) { return false; } $this->text_node_classification = self::TEXT_IS_GENERIC; /* * NULL bytes are treated categorically different than numeric character * references whose number is zero. `�` is not the same as `"\x00"`. */ $leading_nulls = strspn( $this->html, "\x00", $this->text_starts_at, $this->text_length ); if ( $leading_nulls > 0 ) { $this->token_length = $leading_nulls; $this->text_length = $leading_nulls; $this->bytes_already_parsed = $this->token_starts_at + $leading_nulls; $this->text_node_classification = self::TEXT_IS_NULL_SEQUENCE; return true; } /* * Start a decoding loop to determine the point at which the * text subdivides. This entails raw whitespace bytes and any * character reference that decodes to the same. */ $at = $this->text_starts_at; $end = $this->text_starts_at + $this->text_length; while ( $at < $end ) { $skipped = strspn( $this->html, " \t\f\r\n", $at, $end - $at ); $at += $skipped; if ( $at < $end && '&' === $this->html[ $at ] ) { $matched_byte_length = null; $replacement = WP_HTML_Decoder::read_character_reference( 'data', $this->html, $at, $matched_byte_length ); if ( isset( $replacement ) && 1 === strspn( $replacement, " \t\f\r\n" ) ) { $at += $matched_byte_length; continue; } } break; } if ( $at > $this->text_starts_at ) { $new_length = $at - $this->text_starts_at; $this->text_length = $new_length; $this->token_length = $new_length; $this->bytes_already_parsed = $at; $this->text_node_classification = self::TEXT_IS_WHITESPACE; return true; } return false; } /** * Returns the modifiable text for a matched token, or an empty string. * * Modifiable text is text content that may be read and changed without * changing the HTML structure of the document around it. This includes * the contents of `#text` nodes in the HTML as well as the inner * contents of HTML comments, Processing Instructions, and others, even * though these nodes aren't part of a parsed DOM tree. They also contain * the contents of SCRIPT and STYLE tags, of TEXTAREA tags, and of any * other section in an HTML document which cannot contain HTML markup (DATA). * * If a token has no modifiable text then an empty string is returned to * avoid needless crashing or type errors. An empty string does not mean * that a token has modifiable text, and a token with modifiable text may * have an empty string (e.g. a comment with no contents). * * Limitations: * * - This function will not strip the leading newline appropriately * after seeking into a LISTING or PRE element. To ensure that the * newline is treated properly, seek to the LISTING or PRE opening * tag instead of to the first text node inside the element. * * @since 6.5.0 * @since 6.7.0 Replaces NULL bytes (U+0000) and newlines appropriately. * * @return string */ public function get_modifiable_text(): string { $has_enqueued_update = isset( $this->lexical_updates['modifiable text'] ); if ( ! $has_enqueued_update && ( null === $this->text_starts_at || 0 === $this->text_length ) ) { return ''; } $text = $has_enqueued_update ? $this->lexical_updates['modifiable text']->text : substr( $this->html, $this->text_starts_at, $this->text_length ); /* * Pre-processing the input stream would normally happen before * any parsing is done, but deferring it means it's possible to * skip in most cases. When getting the modifiable text, however * it's important to apply the pre-processing steps, which is * normalizing newlines. * * @see https://html.spec.whatwg.org/#preprocessing-the-input-stream * @see https://infra.spec.whatwg.org/#normalize-newlines */ $text = str_replace( "\r\n", "\n", $text ); $text = str_replace( "\r", "\n", $text ); // Comment data is not decoded. if ( self::STATE_CDATA_NODE === $this->parser_state || self::STATE_COMMENT === $this->parser_state || self::STATE_DOCTYPE === $this->parser_state || self::STATE_FUNKY_COMMENT === $this->parser_state ) { return str_replace( "\x00", "\u{FFFD}", $text ); } $tag_name = $this->get_token_name(); if ( // Script data is not decoded. 'SCRIPT' === $tag_name || // RAWTEXT data is not decoded. 'IFRAME' === $tag_name || 'NOEMBED' === $tag_name || 'NOFRAMES' === $tag_name || 'STYLE' === $tag_name || 'XMP' === $tag_name ) { return str_replace( "\x00", "\u{FFFD}", $text ); } $decoded = WP_HTML_Decoder::decode_text_node( $text ); /* * Skip the first line feed after LISTING, PRE, and TEXTAREA opening tags. * * Note that this first newline may come in the form of a character * reference, such as `
`, and so it's important to perform * this transformation only after decoding the raw text content. */ if ( ( "\n" === ( $decoded[0] ?? '' ) ) && ( ( $this->skip_newline_at === $this->token_starts_at && '#text' === $tag_name ) || 'TEXTAREA' === $tag_name ) ) { $decoded = substr( $decoded, 1 ); } /* * Only in normative text nodes does the NULL byte (U+0000) get removed. * In all other contexts it's replaced by the replacement character (U+FFFD) * for security reasons (to avoid joining together strings that were safe * when separated, but not when joined). * * @todo Inside HTML integration points and MathML integration points, the * text is processed according to the insertion mode, not according * to the foreign content rules. This should strip the NULL bytes. */ return ( '#text' === $tag_name && 'html' === $this->get_namespace() ) ? str_replace( "\x00", '', $decoded ) : str_replace( "\x00", "\u{FFFD}", $decoded ); } /** * Sets the modifiable text for the matched token, if matched. * * Modifiable text is text content that may be read and changed without * changing the HTML structure of the document around it. This includes * the contents of `#text` nodes in the HTML as well as the inner * contents of HTML comments, Processing Instructions, and others, even * though these nodes aren't part of a parsed DOM tree. They also contain * the contents of SCRIPT and STYLE tags, of TEXTAREA tags, and of any * other section in an HTML document which cannot contain HTML markup (DATA). * * Not all modifiable text may be set by this method, and not all content * may be set as modifiable text. In the case that this fails it will return * `false` indicating as much. For instance, it will not allow inserting the * string `</script` into a SCRIPT element, because the rules for escaping * that safely are complicated. Similarly, it will not allow setting content * into a comment which would prematurely terminate the comment. * * Example: * * // Add a preface to all STYLE contents. * while ( $processor->next_tag( 'STYLE' ) ) { * $style = $processor->get_modifiable_text(); * $processor->set_modifiable_text( "// Made with love on the World Wide Web\n{$style}" ); * } * * // Replace smiley text with Emoji smilies. * while ( $processor->next_token() ) { * if ( '#text' !== $processor->get_token_name() ) { * continue; * } * * $chunk = $processor->get_modifiable_text(); * if ( ! str_contains( $chunk, ':)' ) ) { * continue; * } * * $processor->set_modifiable_text( str_replace( ':)', '🙂', $chunk ) ); * } * * @since 6.7.0 * * @param string $plaintext_content New text content to represent in the matched token. * * @return bool Whether the text was able to update. */ public function set_modifiable_text( string $plaintext_content ): bool { if ( self::STATE_TEXT_NODE === $this->parser_state ) { $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, htmlspecialchars( $plaintext_content, ENT_QUOTES | ENT_HTML5 ) ); return true; } // Comment data is not encoded. if ( self::STATE_COMMENT === $this->parser_state && self::COMMENT_AS_HTML_COMMENT === $this->comment_type ) { // Check if the text could close the comment. if ( 1 === preg_match( '/--!?>/', $plaintext_content ) ) { return false; } $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; } if ( self::STATE_MATCHED_TAG !== $this->parser_state ) { return false; } switch ( $this->get_tag() ) { case 'SCRIPT': /* * This is over-protective, but ensures the update doesn't break * out of the SCRIPT element. A more thorough check would need to * ensure that the script closing tag doesn't exist, and isn't * also "hidden" inside the script double-escaped state. * * It may seem like replacing `</script` with `<\/script` would * properly escape these things, but this could mask regex patterns * that previously worked. Resolve this by not sending `</script` */ if ( false !== stripos( $plaintext_content, '</script' ) ) { return false; } $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; case 'STYLE': $plaintext_content = preg_replace_callback( '~</(?P<TAG_NAME>style)~i', static function ( $tag_match ) { return "\\3c\\2f{$tag_match['TAG_NAME']}"; }, $plaintext_content ); $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; case 'TEXTAREA': case 'TITLE': $plaintext_content = preg_replace_callback( "~</(?P<TAG_NAME>{$this->get_tag()})~i", static function ( $tag_match ) { return "</{$tag_match['TAG_NAME']}"; }, $plaintext_content ); /* * These don't _need_ to be escaped, but since they are decoded it's * safe to leave them escaped and this can prevent other code from * naively detecting tags within the contents. * * @todo It would be useful to prefix a multiline replacement text * with a newline, but not necessary. This is for aesthetics. */ $this->lexical_updates['modifiable text'] = new WP_HTML_Text_Replacement( $this->text_starts_at, $this->text_length, $plaintext_content ); return true; } return false; } /** * Updates or creates a new attribute on the currently matched tag with the passed value. * * For boolean attributes special handling is provided: * - When `true` is passed as the value, then only the attribute name is added to the tag. * - When `false` is passed, the attribute gets removed if it existed before. * * For string attributes, the value is escaped using the `esc_attr` function. * * @since 6.2.0 * @since 6.2.1 Fix: Only create a single update for multiple calls with case-variant attribute names. * * @param string $name The attribute name to target. * @param string|bool $value The new attribute value. * @return bool Whether an attribute value was set. */ public function set_attribute( $name, $value ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } /* * WordPress rejects more characters than are strictly forbidden * in HTML5. This is to prevent additional security risks deeper * in the WordPress and plugin stack. Specifically the * less-than (<) greater-than (>) and ampersand (&) aren't allowed. * * The use of a PCRE match enables looking for specific Unicode * code points without writing a UTF-8 decoder. Whereas scanning * for one-byte characters is trivial (with `strcspn`), scanning * for the longer byte sequences would be more complicated. Given * that this shouldn't be in the hot path for execution, it's a * reasonable compromise in efficiency without introducing a * noticeable impact on the overall system. * * @see https://html.spec.whatwg.org/#attributes-2 * * @todo As the only regex pattern maybe we should take it out? * Are Unicode patterns available broadly in Core? */ if ( preg_match( '~[' . // Syntax-like characters. '"\'>&</ =' . // Control characters. '\x{00}-\x{1F}' . // HTML noncharacters. '\x{FDD0}-\x{FDEF}' . '\x{FFFE}\x{FFFF}\x{1FFFE}\x{1FFFF}\x{2FFFE}\x{2FFFF}\x{3FFFE}\x{3FFFF}' . '\x{4FFFE}\x{4FFFF}\x{5FFFE}\x{5FFFF}\x{6FFFE}\x{6FFFF}\x{7FFFE}\x{7FFFF}' . '\x{8FFFE}\x{8FFFF}\x{9FFFE}\x{9FFFF}\x{AFFFE}\x{AFFFF}\x{BFFFE}\x{BFFFF}' . '\x{CFFFE}\x{CFFFF}\x{DFFFE}\x{DFFFF}\x{EFFFE}\x{EFFFF}\x{FFFFE}\x{FFFFF}' . '\x{10FFFE}\x{10FFFF}' . ']~Ssu', $name ) ) { _doing_it_wrong( __METHOD__, __( 'Invalid attribute name.' ), '6.2.0' ); return false; } /* * > The values "true" and "false" are not allowed on boolean attributes. * > To represent a false value, the attribute has to be omitted altogether. * - HTML5 spec, https://html.spec.whatwg.org/#boolean-attributes */ if ( false === $value ) { return $this->remove_attribute( $name ); } if ( true === $value ) { $updated_attribute = $name; } else { $comparable_name = strtolower( $name ); /* * Escape URL attributes. * * @see https://html.spec.whatwg.org/#attributes-3 */ $escaped_new_value = in_array( $comparable_name, wp_kses_uri_attributes(), true ) ? esc_url( $value ) : esc_attr( $value ); // If the escaping functions wiped out the update, reject it and indicate it was rejected. if ( '' === $escaped_new_value && '' !== $value ) { return false; } $updated_attribute = "{$name}=\"{$escaped_new_value}\""; } /* * > There must never be two or more attributes on * > the same start tag whose names are an ASCII * > case-insensitive match for each other. * - HTML 5 spec * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive */ $comparable_name = strtolower( $name ); if ( isset( $this->attributes[ $comparable_name ] ) ) { /* * Update an existing attribute. * * Example – set attribute id to "new" in <div id="initial_id" />: * * <div id="initial_id"/> * ^-------------^ * start end * replacement: `id="new"` * * Result: <div id="new"/> */ $existing_attribute = $this->attributes[ $comparable_name ]; $this->lexical_updates[ $comparable_name ] = new WP_HTML_Text_Replacement( $existing_attribute->start, $existing_attribute->length, $updated_attribute ); } else { /* * Create a new attribute at the tag's name end. * * Example – add attribute id="new" to <div />: * * <div/> * ^ * start and end * replacement: ` id="new"` * * Result: <div id="new"/> */ $this->lexical_updates[ $comparable_name ] = new WP_HTML_Text_Replacement( $this->tag_name_starts_at + $this->tag_name_length, 0, ' ' . $updated_attribute ); } /* * Any calls to update the `class` attribute directly should wipe out any * enqueued class changes from `add_class` and `remove_class`. */ if ( 'class' === $comparable_name && ! empty( $this->classname_updates ) ) { $this->classname_updates = array(); } return true; } /** * Remove an attribute from the currently-matched tag. * * @since 6.2.0 * * @param string $name The attribute name to remove. * @return bool Whether an attribute was removed. */ public function remove_attribute( $name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } /* * > There must never be two or more attributes on * > the same start tag whose names are an ASCII * > case-insensitive match for each other. * - HTML 5 spec * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive */ $name = strtolower( $name ); /* * Any calls to update the `class` attribute directly should wipe out any * enqueued class changes from `add_class` and `remove_class`. */ if ( 'class' === $name && count( $this->classname_updates ) !== 0 ) { $this->classname_updates = array(); } /* * If updating an attribute that didn't exist in the input * document, then remove the enqueued update and move on. * * For example, this might occur when calling `remove_attribute()` * after calling `set_attribute()` for the same attribute * and when that attribute wasn't originally present. */ if ( ! isset( $this->attributes[ $name ] ) ) { if ( isset( $this->lexical_updates[ $name ] ) ) { unset( $this->lexical_updates[ $name ] ); } return false; } /* * Removes an existing tag attribute. * * Example – remove the attribute id from <div id="main"/>: * <div id="initial_id"/> * ^-------------^ * start end * replacement: `` * * Result: <div /> */ $this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement( $this->attributes[ $name ]->start, $this->attributes[ $name ]->length, '' ); // Removes any duplicated attributes if they were also present. foreach ( $this->duplicate_attributes[ $name ] ?? array() as $attribute_token ) { $this->lexical_updates[] = new WP_HTML_Text_Replacement( $attribute_token->start, $attribute_token->length, '' ); } return true; } /** * Adds a new class name to the currently matched tag. * * @since 6.2.0 * * @param string $class_name The class name to add. * @return bool Whether the class was set to be added. */ public function add_class( $class_name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } if ( self::QUIRKS_MODE !== $this->compat_mode ) { $this->classname_updates[ $class_name ] = self::ADD_CLASS; return true; } /* * Because class names are matched ASCII-case-insensitively in quirks mode, * this needs to see if a case variant of the given class name is already * enqueued and update that existing entry, if so. This picks the casing of * the first-provided class name for all lexical variations. */ $class_name_length = strlen( $class_name ); foreach ( $this->classname_updates as $updated_name => $action ) { if ( strlen( $updated_name ) === $class_name_length && 0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true ) ) { $this->classname_updates[ $updated_name ] = self::ADD_CLASS; return true; } } $this->classname_updates[ $class_name ] = self::ADD_CLASS; return true; } /** * Removes a class name from the currently matched tag. * * @since 6.2.0 * * @param string $class_name The class name to remove. * @return bool Whether the class was set to be removed. */ public function remove_class( $class_name ): bool { if ( self::STATE_MATCHED_TAG !== $this->parser_state || $this->is_closing_tag ) { return false; } if ( self::QUIRKS_MODE !== $this->compat_mode ) { $this->classname_updates[ $class_name ] = self::REMOVE_CLASS; return true; } /* * Because class names are matched ASCII-case-insensitively in quirks mode, * this needs to see if a case variant of the given class name is already * enqueued and update that existing entry, if so. This picks the casing of * the first-provided class name for all lexical variations. */ $class_name_length = strlen( $class_name ); foreach ( $this->classname_updates as $updated_name => $action ) { if ( strlen( $updated_name ) === $class_name_length && 0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true ) ) { $this->classname_updates[ $updated_name ] = self::REMOVE_CLASS; return true; } } $this->classname_updates[ $class_name ] = self::REMOVE_CLASS; return true; } /** * Returns the string representation of the HTML Tag Processor. * * @since 6.2.0 * * @see WP_HTML_Tag_Processor::get_updated_html() * * @return string The processed HTML. */ public function __toString(): string { return $this->get_updated_html(); } /** * Returns the string representation of the HTML Tag Processor. * * @since 6.2.0 * @since 6.2.1 Shifts the internal cursor corresponding to the applied updates. * @since 6.4.0 No longer calls subclass method `next_tag()` after updating HTML. * * @return string The processed HTML. */ public function get_updated_html(): string { $requires_no_updating = 0 === count( $this->classname_updates ) && 0 === count( $this->lexical_updates ); /* * When there is nothing more to update and nothing has already been * updated, return the original document and avoid a string copy. */ if ( $requires_no_updating ) { return $this->html; } /* * Keep track of the position right before the current tag. This will * be necessary for reparsing the current tag after updating the HTML. */ $before_current_tag = $this->token_starts_at ?? 0; /* * 1. Apply the enqueued edits and update all the pointers to reflect those changes. */ $this->class_name_updates_to_attributes_updates(); $before_current_tag += $this->apply_attributes_updates( $before_current_tag ); /* * 2. Rewind to before the current tag and reparse to get updated attributes. * * At this point the internal cursor points to the end of the tag name. * Rewind before the tag name starts so that it's as if the cursor didn't * move; a call to `next_tag()` will reparse the recently-updated attributes * and additional calls to modify the attributes will apply at this same * location, but in order to avoid issues with subclasses that might add * behaviors to `next_tag()`, the internal methods should be called here * instead. * * It's important to note that in this specific place there will be no change * because the processor was already at a tag when this was called and it's * rewinding only to the beginning of this very tag before reprocessing it * and its attributes. * * <p>Previous HTML<em>More HTML</em></p> * ↑ │ back up by the length of the tag name plus the opening < * └←─┘ back up by strlen("em") + 1 ==> 3 */ $this->bytes_already_parsed = $before_current_tag; $this->base_class_next_token(); return $this->html; } /** * Parses tag query input into internal search criteria. * * @since 6.2.0 * * @param array|string|null $query { * Optional. Which tag name to find, having which class, etc. Default is to find any tag. * * @type string|null $tag_name Which tag to find, or `null` for "any tag." * @type int|null $match_offset Find the Nth tag matching all search criteria. * 1 for "first" tag, 3 for "third," etc. * Defaults to first tag. * @type string|null $class_name Tag must contain this class name to match. * @type string $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. </div>. * } */ private function parse_query( $query ) { if ( null !== $query && $query === $this->last_query ) { return; } $this->last_query = $query; $this->sought_tag_name = null; $this->sought_class_name = null; $this->sought_match_offset = 1; $this->stop_on_tag_closers = false; // A single string value means "find the tag of this name". if ( is_string( $query ) ) { $this->sought_tag_name = $query; return; } // An empty query parameter applies no restrictions on the search. if ( null === $query ) { return; } // If not using the string interface, an associative array is required. if ( ! is_array( $query ) ) { _doing_it_wrong( __METHOD__, __( 'The query argument must be an array or a tag name.' ), '6.2.0' ); return; } if ( isset( $query['tag_name'] ) && is_string( $query['tag_name'] ) ) { $this->sought_tag_name = $query['tag_name']; } if ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) ) { $this->sought_class_name = $query['class_name']; } if ( isset( $query['match_offset'] ) && is_int( $query['match_offset'] ) && 0 < $query['match_offset'] ) { $this->sought_match_offset = $query['match_offset']; } if ( isset( $query['tag_closers'] ) ) { $this->stop_on_tag_closers = 'visit' === $query['tag_closers']; } } /** * Checks whether a given tag and its attributes match the search criteria. * * @since 6.2.0 * * @return bool Whether the given tag and its attribute match the search criteria. */ private function matches(): bool { if ( $this->is_closing_tag && ! $this->stop_on_tag_closers ) { return false; } // Does the tag name match the requested tag name in a case-insensitive manner? if ( isset( $this->sought_tag_name ) && ( strlen( $this->sought_tag_name ) !== $this->tag_name_length || 0 !== substr_compare( $this->html, $this->sought_tag_name, $this->tag_name_starts_at, $this->tag_name_length, true ) ) ) { return false; } if ( null !== $this->sought_class_name && ! $this->has_class( $this->sought_class_name ) ) { return false; } return true; } /** * Gets DOCTYPE declaration info from a DOCTYPE token. * * DOCTYPE tokens may appear in many places in an HTML document. In most places, they are * simply ignored. The main parsing functions find the basic shape of DOCTYPE tokens but * do not perform detailed parsing. * * This method can be called to perform a full parse of the DOCTYPE token and retrieve * its information. * * @return WP_HTML_Doctype_Info|null The DOCTYPE declaration information or `null` if not * currently at a DOCTYPE node. */ public function get_doctype_info(): ?WP_HTML_Doctype_Info { if ( self::STATE_DOCTYPE !== $this->parser_state ) { return null; } return WP_HTML_Doctype_Info::from_doctype_token( substr( $this->html, $this->token_starts_at, $this->token_length ) ); } /** * Parser Ready State. * * Indicates that the parser is ready to run and waiting for a state transition. * It may not have started yet, or it may have just finished parsing a token and * is ready to find the next one. * * @since 6.5.0 * * @access private */ const STATE_READY = 'STATE_READY'; /** * Parser Complete State. * * Indicates that the parser has reached the end of the document and there is * nothing left to scan. It finished parsing the last token completely. * * @since 6.5.0 * * @access private */ const STATE_COMPLETE = 'STATE_COMPLETE'; /** * Parser Incomplete Input State. * * Indicates that the parser has reached the end of the document before finishing * a token. It started parsing a token but there is a possibility that the input * HTML document was truncated in the middle of a token. * * The parser is reset at the start of the incomplete token and has paused. There * is nothing more than can be scanned unless provided a more complete document. * * @since 6.5.0 * * @access private */ const STATE_INCOMPLETE_INPUT = 'STATE_INCOMPLETE_INPUT'; /** * Parser Matched Tag State. * * Indicates that the parser has found an HTML tag and it's possible to get * the tag name and read or modify its attributes (if it's not a closing tag). * * @since 6.5.0 * * @access private */ const STATE_MATCHED_TAG = 'STATE_MATCHED_TAG'; /** * Parser Text Node State. * * Indicates that the parser has found a text node and it's possible * to read and modify that text. * * @since 6.5.0 * * @access private */ const STATE_TEXT_NODE = 'STATE_TEXT_NODE'; /** * Parser CDATA Node State. * * Indicates that the parser has found a CDATA node and it's possible * to read and modify its modifiable text. Note that in HTML there are * no CDATA nodes outside of foreign content (SVG and MathML). Outside * of foreign content, they are treated as HTML comments. * * @since 6.5.0 * * @access private */ const STATE_CDATA_NODE = 'STATE_CDATA_NODE'; /** * Indicates that the parser has found an HTML comment and it's * possible to read and modify its modifiable text. * * @since 6.5.0 * * @access private */ const STATE_COMMENT = 'STATE_COMMENT'; /** * Indicates that the parser has found a DOCTYPE node and it's * possible to read its DOCTYPE information via `get_doctype_info()`. * * @since 6.5.0 * * @access private */ const STATE_DOCTYPE = 'STATE_DOCTYPE'; /** * Indicates that the parser has found an empty tag closer `</>`. * * Note that in HTML there are no empty tag closers, and they * are ignored. Nonetheless, the Tag Processor still * recognizes them as they appear in the HTML stream. * * These were historically discussed as a "presumptuous tag * closer," which would close the nearest open tag, but were * dismissed in favor of explicitly-closing tags. * * @since 6.5.0 * * @access private */ const STATE_PRESUMPTUOUS_TAG = 'STATE_PRESUMPTUOUS_TAG'; /** * Indicates that the parser has found a "funky comment" * and it's possible to read and modify its modifiable text. * * Example: * * </%url> * </{"wp-bit":"query/post-author"}> * </2> * * Funky comments are tag closers with invalid tag names. Note * that in HTML these are turn into bogus comments. Nonetheless, * the Tag Processor recognizes them in a stream of HTML and * exposes them for inspection and modification. * * @since 6.5.0 * * @access private */ const STATE_FUNKY_COMMENT = 'STATE_WP_FUNKY'; /** * Indicates that a comment was created when encountering abruptly-closed HTML comment. * * Example: * * <!--> * <!---> * * @since 6.5.0 */ const COMMENT_AS_ABRUPTLY_CLOSED_COMMENT = 'COMMENT_AS_ABRUPTLY_CLOSED_COMMENT'; /** * Indicates that a comment would be parsed as a CDATA node, * were HTML to allow CDATA nodes outside of foreign content. * * Example: * * <![CDATA[This is a CDATA node.]]> * * This is an HTML comment, but it looks like a CDATA node. * * @since 6.5.0 */ const COMMENT_AS_CDATA_LOOKALIKE = 'COMMENT_AS_CDATA_LOOKALIKE'; /** * Indicates that a comment was created when encountering * normative HTML comment syntax. * * Example: * * <!-- this is a comment --> * * @since 6.5.0 */ const COMMENT_AS_HTML_COMMENT = 'COMMENT_AS_HTML_COMMENT'; /** * Indicates that a comment would be parsed as a Processing * Instruction node, were they to exist within HTML. * * Example: * * <?wp __( 'Like' ) ?> * * This is an HTML comment, but it looks like a CDATA node. * * @since 6.5.0 */ const COMMENT_AS_PI_NODE_LOOKALIKE = 'COMMENT_AS_PI_NODE_LOOKALIKE'; /** * Indicates that a comment was created when encountering invalid * HTML input, a so-called "bogus comment." * * Example: * * <?nothing special> * <!{nothing special}> * * @since 6.5.0 */ const COMMENT_AS_INVALID_HTML = 'COMMENT_AS_INVALID_HTML'; /** * No-quirks mode document compatability mode. * * > In no-quirks mode, the behavior is (hopefully) the desired behavior * > described by the modern HTML and CSS specifications. * * @see self::$compat_mode * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode * * @since 6.7.0 * * @var string */ const NO_QUIRKS_MODE = 'no-quirks-mode'; /** * Quirks mode document compatability mode. * * > In quirks mode, layout emulates behavior in Navigator 4 and Internet * > Explorer 5. This is essential in order to support websites that were * > built before the widespread adoption of web standards. * * @see self::$compat_mode * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode * * @since 6.7.0 * * @var string */ const QUIRKS_MODE = 'quirks-mode'; /** * Indicates that a span of text may contain any combination of significant * kinds of characters: NULL bytes, whitespace, and others. * * @see self::$text_node_classification * @see self::subdivide_text_appropriately * * @since 6.7.0 */ const TEXT_IS_GENERIC = 'TEXT_IS_GENERIC'; /** * Indicates that a span of text comprises a sequence only of NULL bytes. * * @see self::$text_node_classification * @see self::subdivide_text_appropriately * * @since 6.7.0 */ const TEXT_IS_NULL_SEQUENCE = 'TEXT_IS_NULL_SEQUENCE'; /** * Indicates that a span of decoded text comprises only whitespace. * * @see self::$text_node_classification * @see self::subdivide_text_appropriately * * @since 6.7.0 */ const TEXT_IS_WHITESPACE = 'TEXT_IS_WHITESPACE'; } <?php /** * HTML API: WP_HTML_Decoder class * * Decodes spans of raw text found inside HTML content. * * @package WordPress * @subpackage HTML-API * @since 6.6.0 */ class WP_HTML_Decoder { /** * Indicates if an attribute value starts with a given raw string value. * * Use this method to determine if an attribute value starts with a given string, regardless * of how it might be encoded in HTML. For instance, `http:` could be represented as `http:` * or as `http:` or as `http:` or as `http:`, or in many other ways. * * Example: * * $value = 'http://wordpress.org/'; * true === WP_HTML_Decoder::attribute_starts_with( $value, 'http:', 'ascii-case-insensitive' ); * false === WP_HTML_Decoder::attribute_starts_with( $value, 'https:', 'ascii-case-insensitive' ); * * @since 6.6.0 * * @param string $haystack String containing the raw non-decoded attribute value. * @param string $search_text Does the attribute value start with this plain string. * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. * Default 'case-sensitive'. * @return bool Whether the attribute value starts with the given string. */ public static function attribute_starts_with( $haystack, $search_text, $case_sensitivity = 'case-sensitive' ): bool { $search_length = strlen( $search_text ); $loose_case = 'ascii-case-insensitive' === $case_sensitivity; $haystack_end = strlen( $haystack ); $search_at = 0; $haystack_at = 0; while ( $search_at < $search_length && $haystack_at < $haystack_end ) { $chars_match = $loose_case ? strtolower( $haystack[ $haystack_at ] ) === strtolower( $search_text[ $search_at ] ) : $haystack[ $haystack_at ] === $search_text[ $search_at ]; $is_introducer = '&' === $haystack[ $haystack_at ]; $next_chunk = $is_introducer ? self::read_character_reference( 'attribute', $haystack, $haystack_at, $token_length ) : null; // If there's no character reference and the characters don't match, the match fails. if ( null === $next_chunk && ! $chars_match ) { return false; } // If there's no character reference but the character do match, then it could still match. if ( null === $next_chunk && $chars_match ) { ++$haystack_at; ++$search_at; continue; } // If there is a character reference, then the decoded value must exactly match what follows in the search string. if ( 0 !== substr_compare( $search_text, $next_chunk, $search_at, strlen( $next_chunk ), $loose_case ) ) { return false; } // The character reference matched, so continue checking. $haystack_at += $token_length; $search_at += strlen( $next_chunk ); } return true; } /** * Returns a string containing the decoded value of a given HTML text node. * * Text nodes appear in HTML DATA sections, which are the text segments inside * and around tags, excepting SCRIPT and STYLE elements (and some others), * whose inner text is not decoded. Use this function to read the decoded * value of such a text span in an HTML document. * * Example: * * '“😄”' === WP_HTML_Decode::decode_text_node( '“😄”' ); * * @since 6.6.0 * * @param string $text Text containing raw and non-decoded text node to decode. * @return string Decoded UTF-8 value of given text node. */ public static function decode_text_node( $text ): string { return static::decode( 'data', $text ); } /** * Returns a string containing the decoded value of a given HTML attribute. * * Text found inside an HTML attribute has different parsing rules than for * text found inside other markup, or DATA segments. Use this function to * read the decoded value of an HTML string inside a quoted attribute. * * Example: * * '“😄”' === WP_HTML_Decode::decode_attribute( '“😄”' ); * * @since 6.6.0 * * @param string $text Text containing raw and non-decoded attribute value to decode. * @return string Decoded UTF-8 value of given attribute value. */ public static function decode_attribute( $text ): string { return static::decode( 'attribute', $text ); } /** * Decodes a span of HTML text, depending on the context in which it's found. * * This is a low-level method; prefer calling WP_HTML_Decoder::decode_attribute() or * WP_HTML_Decoder::decode_text_node() instead. It's provided for cases where this * may be difficult to do from calling code. * * Example: * * '©' = WP_HTML_Decoder::decode( 'data', '©' ); * * @since 6.6.0 * * @access private * * @param string $context `attribute` for decoding attribute values, `data` otherwise. * @param string $text Text document containing span of text to decode. * @return string Decoded UTF-8 string. */ public static function decode( $context, $text ): string { $decoded = ''; $end = strlen( $text ); $at = 0; $was_at = 0; while ( $at < $end ) { $next_character_reference_at = strpos( $text, '&', $at ); if ( false === $next_character_reference_at ) { break; } $character_reference = self::read_character_reference( $context, $text, $next_character_reference_at, $token_length ); if ( isset( $character_reference ) ) { $at = $next_character_reference_at; $decoded .= substr( $text, $was_at, $at - $was_at ); $decoded .= $character_reference; $at += $token_length; $was_at = $at; continue; } ++$at; } if ( 0 === $was_at ) { return $text; } if ( $was_at < $end ) { $decoded .= substr( $text, $was_at, $end - $was_at ); } return $decoded; } /** * Attempt to read a character reference at the given location in a given string, * depending on the context in which it's found. * * If a character reference is found, this function will return the translated value * that the reference maps to. It will then set `$match_byte_length` the * number of bytes of input it read while consuming the character reference. This * gives calling code the opportunity to advance its cursor when traversing a string * and decoding. * * Example: * * null === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships…', 0 ); * '…' === WP_HTML_Decoder::read_character_reference( 'attribute', 'Ships…', 5, $token_length ); * 8 === $token_length; // `…` * * null === WP_HTML_Decoder::read_character_reference( 'attribute', '¬in', 0 ); * '∉' === WP_HTML_Decoder::read_character_reference( 'attribute', '∉', 0, $token_length ); * 7 === $token_length; // `∉` * * '¬' === WP_HTML_Decoder::read_character_reference( 'data', '¬in', 0, $token_length ); * 4 === $token_length; // `¬` * '∉' === WP_HTML_Decoder::read_character_reference( 'data', '∉', 0, $token_length ); * 7 === $token_length; // `∉` * * @since 6.6.0 * * @global WP_Token_Map $html5_named_character_references Mappings for HTML5 named character references. * * @param string $context `attribute` for decoding attribute values, `data` otherwise. * @param string $text Text document containing span of text to decode. * @param int $at Optional. Byte offset into text where span begins, defaults to the beginning (0). * @param int &$match_byte_length Optional. Set to byte-length of character reference if provided and if a match * is found, otherwise not set. Default null. * @return string|false Decoded character reference in UTF-8 if found, otherwise `false`. */ public static function read_character_reference( $context, $text, $at = 0, &$match_byte_length = null ) { /** * Mappings for HTML5 named character references. * * @var WP_Token_Map $html5_named_character_references */ global $html5_named_character_references; $length = strlen( $text ); if ( $at + 1 >= $length ) { return null; } if ( '&' !== $text[ $at ] ) { return null; } /* * Numeric character references. * * When truncated, these will encode the code point found by parsing the * digits that are available. For example, when `🅰` is truncated * to `DZ` it will encode `DZ`. It does not: * - know how to parse the original `🅰`. * - fail to parse and return plaintext `DZ`. * - fail to parse and return the replacement character `�` */ if ( '#' === $text[ $at + 1 ] ) { if ( $at + 2 >= $length ) { return null; } /** Tracks inner parsing within the numeric character reference. */ $digits_at = $at + 2; if ( 'x' === $text[ $digits_at ] || 'X' === $text[ $digits_at ] ) { $numeric_base = 16; $numeric_digits = '0123456789abcdefABCDEF'; $max_digits = 6; //  ++$digits_at; } else { $numeric_base = 10; $numeric_digits = '0123456789'; $max_digits = 7; //  } // Cannot encode invalid Unicode code points. Max is to U+10FFFF. $zero_count = strspn( $text, '0', $digits_at ); $digit_count = strspn( $text, $numeric_digits, $digits_at + $zero_count ); $after_digits = $digits_at + $zero_count + $digit_count; $has_semicolon = $after_digits < $length && ';' === $text[ $after_digits ]; $end_of_span = $has_semicolon ? $after_digits + 1 : $after_digits; // `&#` or `&#x` without digits returns into plaintext. if ( 0 === $digit_count && 0 === $zero_count ) { return null; } // Whereas `&#` and only zeros is invalid. if ( 0 === $digit_count ) { $match_byte_length = $end_of_span - $at; return '�'; } // If there are too many digits then it's not worth parsing. It's invalid. if ( $digit_count > $max_digits ) { $match_byte_length = $end_of_span - $at; return '�'; } $digits = substr( $text, $digits_at + $zero_count, $digit_count ); $code_point = intval( $digits, $numeric_base ); /* * Noncharacters, 0x0D, and non-ASCII-whitespace control characters. * * > A noncharacter is a code point that is in the range U+FDD0 to U+FDEF, * > inclusive, or U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, * > U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, * > U+6FFFF, U+7FFFE, U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, * > U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, * > U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, or U+10FFFF. * * A C0 control is a code point that is in the range of U+00 to U+1F, * but ASCII whitespace includes U+09, U+0A, U+0C, and U+0D. * * These characters are invalid but still decode as any valid character. * This comment is here to note and explain why there's no check to * remove these characters or replace them. * * @see https://infra.spec.whatwg.org/#noncharacter */ /* * Code points in the C1 controls area need to be remapped as if they * were stored in Windows-1252. Note! This transformation only happens * for numeric character references. The raw code points in the byte * stream are not translated. * * > If the number is one of the numbers in the first column of * > the following table, then find the row with that number in * > the first column, and set the character reference code to * > the number in the second column of that row. */ if ( $code_point >= 0x80 && $code_point <= 0x9F ) { $windows_1252_mapping = array( 0x20AC, // 0x80 -> EURO SIGN (€). 0x81, // 0x81 -> (no change). 0x201A, // 0x82 -> SINGLE LOW-9 QUOTATION MARK (‚). 0x0192, // 0x83 -> LATIN SMALL LETTER F WITH HOOK (ƒ). 0x201E, // 0x84 -> DOUBLE LOW-9 QUOTATION MARK („). 0x2026, // 0x85 -> HORIZONTAL ELLIPSIS (…). 0x2020, // 0x86 -> DAGGER (†). 0x2021, // 0x87 -> DOUBLE DAGGER (‡). 0x02C6, // 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT (ˆ). 0x2030, // 0x89 -> PER MILLE SIGN (‰). 0x0160, // 0x8A -> LATIN CAPITAL LETTER S WITH CARON (Š). 0x2039, // 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK (‹). 0x0152, // 0x8C -> LATIN CAPITAL LIGATURE OE (Œ). 0x8D, // 0x8D -> (no change). 0x017D, // 0x8E -> LATIN CAPITAL LETTER Z WITH CARON (Ž). 0x8F, // 0x8F -> (no change). 0x90, // 0x90 -> (no change). 0x2018, // 0x91 -> LEFT SINGLE QUOTATION MARK (‘). 0x2019, // 0x92 -> RIGHT SINGLE QUOTATION MARK (’). 0x201C, // 0x93 -> LEFT DOUBLE QUOTATION MARK (“). 0x201D, // 0x94 -> RIGHT DOUBLE QUOTATION MARK (”). 0x2022, // 0x95 -> BULLET (•). 0x2013, // 0x96 -> EN DASH (–). 0x2014, // 0x97 -> EM DASH (—). 0x02DC, // 0x98 -> SMALL TILDE (˜). 0x2122, // 0x99 -> TRADE MARK SIGN (™). 0x0161, // 0x9A -> LATIN SMALL LETTER S WITH CARON (š). 0x203A, // 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (›). 0x0153, // 0x9C -> LATIN SMALL LIGATURE OE (œ). 0x9D, // 0x9D -> (no change). 0x017E, // 0x9E -> LATIN SMALL LETTER Z WITH CARON (ž). 0x0178, // 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS (Ÿ). ); $code_point = $windows_1252_mapping[ $code_point - 0x80 ]; } $match_byte_length = $end_of_span - $at; return self::code_point_to_utf8_bytes( $code_point ); } /** Tracks inner parsing within the named character reference. */ $name_at = $at + 1; // Minimum named character reference is two characters. E.g. `GT`. if ( $name_at + 2 > $length ) { return null; } $name_length = 0; $replacement = $html5_named_character_references->read_token( $text, $name_at, $name_length ); if ( false === $replacement ) { return null; } $after_name = $name_at + $name_length; // If the match ended with a semicolon then it should always be decoded. if ( ';' === $text[ $name_at + $name_length - 1 ] ) { $match_byte_length = $after_name - $at; return $replacement; } /* * At this point though there's a match for an entry in the named * character reference table but the match doesn't end in `;`. * It may be allowed if it's followed by something unambiguous. */ $ambiguous_follower = ( $after_name < $length && $name_at < $length && ( ctype_alnum( $text[ $after_name ] ) || '=' === $text[ $after_name ] ) ); // It's non-ambiguous, safe to leave it in. if ( ! $ambiguous_follower ) { $match_byte_length = $after_name - $at; return $replacement; } // It's ambiguous, which isn't allowed inside attributes. if ( 'attribute' === $context ) { return null; } $match_byte_length = $after_name - $at; return $replacement; } /** * Encode a code point number into the UTF-8 encoding. * * This encoder implements the UTF-8 encoding algorithm for converting * a code point into a byte sequence. If it receives an invalid code * point it will return the Unicode Replacement Character U+FFFD `�`. * * Example: * * '🅰' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0x1f170 ); * * // Half of a surrogate pair is an invalid code point. * '�' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0xd83c ); * * @since 6.6.0 * * @see https://www.rfc-editor.org/rfc/rfc3629 For the UTF-8 standard. * * @param int $code_point Which code point to convert. * @return string Converted code point, or `�` if invalid. */ public static function code_point_to_utf8_bytes( $code_point ): string { // Pre-check to ensure a valid code point. if ( $code_point <= 0 || ( $code_point >= 0xD800 && $code_point <= 0xDFFF ) || $code_point > 0x10FFFF ) { return '�'; } if ( $code_point <= 0x7F ) { return chr( $code_point ); } if ( $code_point <= 0x7FF ) { $byte1 = chr( ( $code_point >> 6 ) | 0xC0 ); $byte2 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}"; } if ( $code_point <= 0xFFFF ) { $byte1 = chr( ( $code_point >> 12 ) | 0xE0 ); $byte2 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); $byte3 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}"; } // Any values above U+10FFFF are eliminated above in the pre-check. $byte1 = chr( ( $code_point >> 18 ) | 0xF0 ); $byte2 = chr( ( $code_point >> 12 ) & 0x3F | 0x80 ); $byte3 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); $byte4 = chr( $code_point & 0x3F | 0x80 ); return "{$byte1}{$byte2}{$byte3}{$byte4}"; } } <?php /** * HTML API: WP_HTML_Open_Elements class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used by the HTML processor during HTML parsing * for managing the stack of open elements. * * This class is designed for internal use by the HTML processor. * * > Initially, the stack of open elements is empty. The stack grows * > downwards; the topmost node on the stack is the first one added * > to the stack, and the bottommost node of the stack is the most * > recently added node in the stack (notwithstanding when the stack * > is manipulated in a random access fashion as part of the handling * > for misnested tags). * * @since 6.4.0 * * @access private * * @see https://html.spec.whatwg.org/#stack-of-open-elements * @see WP_HTML_Processor */ class WP_HTML_Open_Elements { /** * Holds the stack of open element references. * * @since 6.4.0 * * @var WP_HTML_Token[] */ public $stack = array(); /** * Whether a P element is in button scope currently. * * This class optimizes scope lookup by pre-calculating * this value when elements are added and removed to the * stack of open elements which might change its value. * This avoids frequent iteration over the stack. * * @since 6.4.0 * * @var bool */ private $has_p_in_button_scope = false; /** * A function that will be called when an item is popped off the stack of open elements. * * The function will be called with the popped item as its argument. * * @since 6.6.0 * * @var Closure|null */ private $pop_handler = null; /** * A function that will be called when an item is pushed onto the stack of open elements. * * The function will be called with the pushed item as its argument. * * @since 6.6.0 * * @var Closure|null */ private $push_handler = null; /** * Sets a pop handler that will be called when an item is popped off the stack of * open elements. * * The function will be called with the pushed item as its argument. * * @since 6.6.0 * * @param Closure $handler The handler function. */ public function set_pop_handler( Closure $handler ): void { $this->pop_handler = $handler; } /** * Sets a push handler that will be called when an item is pushed onto the stack of * open elements. * * The function will be called with the pushed item as its argument. * * @since 6.6.0 * * @param Closure $handler The handler function. */ public function set_push_handler( Closure $handler ): void { $this->push_handler = $handler; } /** * Returns the name of the node at the nth position on the stack * of open elements, or `null` if no such position exists. * * Note that this uses a 1-based index, which represents the * "nth item" on the stack, counting from the top, where the * top-most element is the 1st, the second is the 2nd, etc... * * @since 6.7.0 * * @param int $nth Retrieve the nth item on the stack, with 1 being * the top element, 2 being the second, etc... * @return WP_HTML_Token|null Name of the node on the stack at the given location, * or `null` if the location isn't on the stack. */ public function at( int $nth ): ?WP_HTML_Token { foreach ( $this->walk_down() as $item ) { if ( 0 === --$nth ) { return $item; } } return null; } /** * Reports if a node of a given name is in the stack of open elements. * * @since 6.7.0 * * @param string $node_name Name of node for which to check. * @return bool Whether a node of the given name is in the stack of open elements. */ public function contains( string $node_name ): bool { foreach ( $this->walk_up() as $item ) { if ( $node_name === $item->node_name ) { return true; } } return false; } /** * Reports if a specific node is in the stack of open elements. * * @since 6.4.0 * * @param WP_HTML_Token $token Look for this node in the stack. * @return bool Whether the referenced node is in the stack of open elements. */ public function contains_node( WP_HTML_Token $token ): bool { foreach ( $this->walk_up() as $item ) { if ( $token === $item ) { return true; } } return false; } /** * Returns how many nodes are currently in the stack of open elements. * * @since 6.4.0 * * @return int How many node are in the stack of open elements. */ public function count(): int { return count( $this->stack ); } /** * Returns the node at the end of the stack of open elements, * if one exists. If the stack is empty, returns null. * * @since 6.4.0 * * @return WP_HTML_Token|null Last node in the stack of open elements, if one exists, otherwise null. */ public function current_node(): ?WP_HTML_Token { $current_node = end( $this->stack ); return $current_node ? $current_node : null; } /** * Indicates if the current node is of a given type or name. * * It's possible to pass either a node type or a node name to this function. * In the case there is no current element it will always return `false`. * * Example: * * // Is the current node a text node? * $stack->current_node_is( '#text' ); * * // Is the current node a DIV element? * $stack->current_node_is( 'DIV' ); * * // Is the current node any element/tag? * $stack->current_node_is( '#tag' ); * * @see WP_HTML_Tag_Processor::get_token_type * @see WP_HTML_Tag_Processor::get_token_name * * @since 6.7.0 * * @access private * * @param string $identity Check if the current node has this name or type (depending on what is provided). * @return bool Whether there is a current element that matches the given identity, whether a token name or type. */ public function current_node_is( string $identity ): bool { $current_node = end( $this->stack ); if ( false === $current_node ) { return false; } $current_node_name = $current_node->node_name; return ( $current_node_name === $identity || ( '#doctype' === $identity && 'html' === $current_node_name ) || ( '#tag' === $identity && ctype_upper( $current_node_name ) ) ); } /** * Returns whether an element is in a specific scope. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#has-an-element-in-the-specific-scope * * @param string $tag_name Name of tag check. * @param string[] $termination_list List of elements that terminate the search. * @return bool Whether the element was found in a specific scope. */ public function has_element_in_specific_scope( string $tag_name, $termination_list ): bool { foreach ( $this->walk_up() as $node ) { $namespaced_name = 'html' === $node->namespace ? $node->node_name : "{$node->namespace} {$node->node_name}"; if ( $namespaced_name === $tag_name ) { return true; } if ( '(internal: H1 through H6 - do not use)' === $tag_name && in_array( $namespaced_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { return true; } if ( in_array( $namespaced_name, $termination_list, true ) ) { return false; } } return false; } /** * Returns whether a particular element is in scope. * * > The stack of open elements is said to have a particular element in * > scope when it has that element in the specific scope consisting of * > the following element types: * > * > - applet * > - caption * > - html * > - table * > - td * > - th * > - marquee * > - object * > - template * > - MathML mi * > - MathML mo * > - MathML mn * > - MathML ms * > - MathML mtext * > - MathML annotation-xml * > - SVG foreignObject * > - SVG desc * > - SVG title * * @since 6.4.0 * @since 6.7.0 Full support. * * @see https://html.spec.whatwg.org/#has-an-element-in-scope * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'TEMPLATE', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } /** * Returns whether a particular element is in list item scope. * * > The stack of open elements is said to have a particular element * > in list item scope when it has that element in the specific scope * > consisting of the following element types: * > * > - All the element types listed above for the has an element in scope algorithm. * > - ol in the HTML namespace * > - ul in the HTML namespace * * @since 6.4.0 * @since 6.5.0 Implemented: no longer throws on every invocation. * @since 6.7.0 Supports all required HTML elements. * * @see https://html.spec.whatwg.org/#has-an-element-in-list-item-scope * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_list_item_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'BUTTON', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'OL', 'TEMPLATE', 'UL', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } /** * Returns whether a particular element is in button scope. * * > The stack of open elements is said to have a particular element * > in button scope when it has that element in the specific scope * > consisting of the following element types: * > * > - All the element types listed above for the has an element in scope algorithm. * > - button in the HTML namespace * * @since 6.4.0 * @since 6.7.0 Supports all required HTML elements. * * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_button_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'APPLET', 'BUTTON', 'CAPTION', 'HTML', 'TABLE', 'TD', 'TH', 'MARQUEE', 'OBJECT', 'TEMPLATE', 'math MI', 'math MO', 'math MN', 'math MS', 'math MTEXT', 'math ANNOTATION-XML', 'svg FOREIGNOBJECT', 'svg DESC', 'svg TITLE', ) ); } /** * Returns whether a particular element is in table scope. * * > The stack of open elements is said to have a particular element * > in table scope when it has that element in the specific scope * > consisting of the following element types: * > * > - html in the HTML namespace * > - table in the HTML namespace * > - template in the HTML namespace * * @since 6.4.0 * @since 6.7.0 Full implementation. * * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_table_scope( string $tag_name ): bool { return $this->has_element_in_specific_scope( $tag_name, array( 'HTML', 'TABLE', 'TEMPLATE', ) ); } /** * Returns whether a particular element is in select scope. * * This test differs from the others like it, in that its rules are inverted. * Instead of arriving at a match when one of any tag in a termination group * is reached, this one terminates if any other tag is reached. * * > The stack of open elements is said to have a particular element in select scope when it has * > that element in the specific scope consisting of all element types except the following: * > - optgroup in the HTML namespace * > - option in the HTML namespace * * @since 6.4.0 Stub implementation (throws). * @since 6.7.0 Full implementation. * * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope * * @param string $tag_name Name of tag to check. * @return bool Whether the given element is in SELECT scope. */ public function has_element_in_select_scope( string $tag_name ): bool { foreach ( $this->walk_up() as $node ) { if ( $node->node_name === $tag_name ) { return true; } if ( 'OPTION' !== $node->node_name && 'OPTGROUP' !== $node->node_name ) { return false; } } return false; } /** * Returns whether a P is in BUTTON scope. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope * * @return bool Whether a P is in BUTTON scope. */ public function has_p_in_button_scope(): bool { return $this->has_p_in_button_scope; } /** * Pops a node off of the stack of open elements. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#stack-of-open-elements * * @return bool Whether a node was popped off of the stack. */ public function pop(): bool { $item = array_pop( $this->stack ); if ( null === $item ) { return false; } $this->after_element_pop( $item ); return true; } /** * Pops nodes off of the stack of open elements until an HTML tag with the given name has been popped. * * @since 6.4.0 * * @see WP_HTML_Open_Elements::pop * * @param string $html_tag_name Name of tag that needs to be popped off of the stack of open elements. * @return bool Whether a tag of the given name was found and popped off of the stack of open elements. */ public function pop_until( string $html_tag_name ): bool { foreach ( $this->walk_up() as $item ) { $this->pop(); if ( 'html' !== $item->namespace ) { continue; } if ( '(internal: H1 through H6 - do not use)' === $html_tag_name && in_array( $item->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { return true; } if ( $html_tag_name === $item->node_name ) { return true; } } return false; } /** * Pushes a node onto the stack of open elements. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#stack-of-open-elements * * @param WP_HTML_Token $stack_item Item to add onto stack. */ public function push( WP_HTML_Token $stack_item ): void { $this->stack[] = $stack_item; $this->after_element_push( $stack_item ); } /** * Removes a specific node from the stack of open elements. * * @since 6.4.0 * * @param WP_HTML_Token $token The node to remove from the stack of open elements. * @return bool Whether the node was found and removed from the stack of open elements. */ public function remove_node( WP_HTML_Token $token ): bool { foreach ( $this->walk_up() as $position_from_end => $item ) { if ( $token->bookmark_name !== $item->bookmark_name ) { continue; } $position_from_start = $this->count() - $position_from_end - 1; array_splice( $this->stack, $position_from_start, 1 ); $this->after_element_pop( $item ); return true; } return false; } /** * Steps through the stack of open elements, starting with the top element * (added first) and walking downwards to the one added last. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $html = '<em><strong><a>We are here'; * foreach ( $stack->walk_down() as $node ) { * echo "{$node->node_name} -> "; * } * > EM -> STRONG -> A -> * * To start with the most-recently added element and walk towards the top, * see WP_HTML_Open_Elements::walk_up(). * * @since 6.4.0 */ public function walk_down() { $count = count( $this->stack ); for ( $i = 0; $i < $count; $i++ ) { yield $this->stack[ $i ]; } } /** * Steps through the stack of open elements, starting with the bottom element * (added last) and walking upwards to the one added first. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $html = '<em><strong><a>We are here'; * foreach ( $stack->walk_up() as $node ) { * echo "{$node->node_name} -> "; * } * > A -> STRONG -> EM -> * * To start with the first added element and walk towards the bottom, * see WP_HTML_Open_Elements::walk_down(). * * @since 6.4.0 * @since 6.5.0 Accepts $above_this_node to start traversal above a given node, if it exists. * * @param WP_HTML_Token|null $above_this_node Optional. Start traversing above this node, * if provided and if the node exists. */ public function walk_up( ?WP_HTML_Token $above_this_node = null ) { $has_found_node = null === $above_this_node; for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) { $node = $this->stack[ $i ]; if ( ! $has_found_node ) { $has_found_node = $node === $above_this_node; continue; } yield $node; } } /* * Internal helpers. */ /** * Updates internal flags after adding an element. * * Certain conditions (such as "has_p_in_button_scope") are maintained here as * flags that are only modified when adding and removing elements. This allows * the HTML Processor to quickly check for these conditions instead of iterating * over the open stack elements upon each new tag it encounters. These flags, * however, need to be maintained as items are added and removed from the stack. * * @since 6.4.0 * * @param WP_HTML_Token $item Element that was added to the stack of open elements. */ public function after_element_push( WP_HTML_Token $item ): void { $namespaced_name = 'html' === $item->namespace ? $item->node_name : "{$item->namespace} {$item->node_name}"; /* * When adding support for new elements, expand this switch to trap * cases where the precalculated value needs to change. */ switch ( $namespaced_name ) { case 'APPLET': case 'BUTTON': case 'CAPTION': case 'HTML': case 'TABLE': case 'TD': case 'TH': case 'MARQUEE': case 'OBJECT': case 'TEMPLATE': case 'math MI': case 'math MO': case 'math MN': case 'math MS': case 'math MTEXT': case 'math ANNOTATION-XML': case 'svg FOREIGNOBJECT': case 'svg DESC': case 'svg TITLE': $this->has_p_in_button_scope = false; break; case 'P': $this->has_p_in_button_scope = true; break; } if ( null !== $this->push_handler ) { ( $this->push_handler )( $item ); } } /** * Updates internal flags after removing an element. * * Certain conditions (such as "has_p_in_button_scope") are maintained here as * flags that are only modified when adding and removing elements. This allows * the HTML Processor to quickly check for these conditions instead of iterating * over the open stack elements upon each new tag it encounters. These flags, * however, need to be maintained as items are added and removed from the stack. * * @since 6.4.0 * * @param WP_HTML_Token $item Element that was removed from the stack of open elements. */ public function after_element_pop( WP_HTML_Token $item ): void { /* * When adding support for new elements, expand this switch to trap * cases where the precalculated value needs to change. */ switch ( $item->node_name ) { case 'APPLET': case 'BUTTON': case 'CAPTION': case 'HTML': case 'P': case 'TABLE': case 'TD': case 'TH': case 'MARQUEE': case 'OBJECT': case 'TEMPLATE': case 'math MI': case 'math MO': case 'math MN': case 'math MS': case 'math MTEXT': case 'math ANNOTATION-XML': case 'svg FOREIGNOBJECT': case 'svg DESC': case 'svg TITLE': $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); break; } if ( null !== $this->pop_handler ) { ( $this->pop_handler )( $item ); } } /** * Clear the stack back to a table context. * * > When the steps above require the UA to clear the stack back to a table context, it means * > that the UA must, while the current node is not a table, template, or html element, pop * > elements from the stack of open elements. * * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-context * * @since 6.7.0 */ public function clear_to_table_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TABLE' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } /** * Clear the stack back to a table body context. * * > When the steps above require the UA to clear the stack back to a table body context, it * > means that the UA must, while the current node is not a tbody, tfoot, thead, template, or * > html element, pop elements from the stack of open elements. * * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-body-context * * @since 6.7.0 */ public function clear_to_table_body_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TBODY' === $item->node_name || 'TFOOT' === $item->node_name || 'THEAD' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } /** * Clear the stack back to a table row context. * * > When the steps above require the UA to clear the stack back to a table row context, it * > means that the UA must, while the current node is not a tr, template, or html element, pop * > elements from the stack of open elements. * * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-row-context * * @since 6.7.0 */ public function clear_to_table_row_context(): void { foreach ( $this->walk_up() as $item ) { if ( 'TR' === $item->node_name || 'TEMPLATE' === $item->node_name || 'HTML' === $item->node_name ) { break; } $this->pop(); } } /** * Wakeup magic method. * * @since 6.6.0 */ public function __wakeup() { throw new \LogicException( __CLASS__ . ' should never be unserialized' ); } } <?php /** * Auto-generated class for looking up HTML named character references. * * ⚠️ !!! THIS ENTIRE FILE IS AUTOMATICALLY GENERATED !!! ⚠️ * Do not modify this file directly. * * To regenerate, run the generation script directly. * * Example: * * php tests/phpunit/data/html5-entities/generate-html5-named-character-references.php * * @package WordPress * @since 6.6.0 */ // phpcs:disable global $html5_named_character_references; /** * Set of named character references in the HTML5 specification. * * This list will never change, according to the spec. Each named * character reference is case-sensitive and the presence or absence * of the semicolon is significant. Without the semicolon, the rules * for an ambiguous ampersand govern whether the following text is * to be interpreted as a character reference or not. * * The list of entities is sourced directly from the WHATWG server * and cached in the test directory to avoid needing to download it * every time this file is updated. * * @link https://html.spec.whatwg.org/entities.json. */ $html5_named_character_references = WP_Token_Map::from_precomputed_table( array( "storage_version" => "6.6.0-trunk", "key_length" => 2, "groups" => "AE\x00AM\x00Aa\x00Ab\x00Ac\x00Af\x00Ag\x00Al\x00Am\x00An\x00Ao\x00Ap\x00Ar\x00As\x00At\x00Au\x00Ba\x00Bc\x00Be\x00Bf\x00Bo\x00Br\x00Bs\x00Bu\x00CH\x00CO\x00Ca\x00Cc\x00Cd\x00Ce\x00Cf\x00Ch\x00Ci\x00Cl\x00Co\x00Cr\x00Cs\x00Cu\x00DD\x00DJ\x00DS\x00DZ\x00Da\x00Dc\x00De\x00Df\x00Di\x00Do\x00Ds\x00EN\x00ET\x00Ea\x00Ec\x00Ed\x00Ef\x00Eg\x00El\x00Em\x00Eo\x00Ep\x00Eq\x00Es\x00Et\x00Eu\x00Ex\x00Fc\x00Ff\x00Fi\x00Fo\x00Fs\x00GJ\x00GT\x00Ga\x00Gb\x00Gc\x00Gd\x00Gf\x00Gg\x00Go\x00Gr\x00Gs\x00Gt\x00HA\x00Ha\x00Hc\x00Hf\x00Hi\x00Ho\x00Hs\x00Hu\x00IE\x00IJ\x00IO\x00Ia\x00Ic\x00Id\x00If\x00Ig\x00Im\x00In\x00Io\x00Is\x00It\x00Iu\x00Jc\x00Jf\x00Jo\x00Js\x00Ju\x00KH\x00KJ\x00Ka\x00Kc\x00Kf\x00Ko\x00Ks\x00LJ\x00LT\x00La\x00Lc\x00Le\x00Lf\x00Ll\x00Lm\x00Lo\x00Ls\x00Lt\x00Ma\x00Mc\x00Me\x00Mf\x00Mi\x00Mo\x00Ms\x00Mu\x00NJ\x00Na\x00Nc\x00Ne\x00Nf\x00No\x00Ns\x00Nt\x00Nu\x00OE\x00Oa\x00Oc\x00Od\x00Of\x00Og\x00Om\x00Oo\x00Op\x00Or\x00Os\x00Ot\x00Ou\x00Ov\x00Pa\x00Pc\x00Pf\x00Ph\x00Pi\x00Pl\x00Po\x00Pr\x00Ps\x00QU\x00Qf\x00Qo\x00Qs\x00RB\x00RE\x00Ra\x00Rc\x00Re\x00Rf\x00Rh\x00Ri\x00Ro\x00Rr\x00Rs\x00Ru\x00SH\x00SO\x00Sa\x00Sc\x00Sf\x00Sh\x00Si\x00Sm\x00So\x00Sq\x00Ss\x00St\x00Su\x00TH\x00TR\x00TS\x00Ta\x00Tc\x00Tf\x00Th\x00Ti\x00To\x00Tr\x00Ts\x00Ua\x00Ub\x00Uc\x00Ud\x00Uf\x00Ug\x00Um\x00Un\x00Uo\x00Up\x00Ur\x00Us\x00Ut\x00Uu\x00VD\x00Vb\x00Vc\x00Vd\x00Ve\x00Vf\x00Vo\x00Vs\x00Vv\x00Wc\x00We\x00Wf\x00Wo\x00Ws\x00Xf\x00Xi\x00Xo\x00Xs\x00YA\x00YI\x00YU\x00Ya\x00Yc\x00Yf\x00Yo\x00Ys\x00Yu\x00ZH\x00Za\x00Zc\x00Zd\x00Ze\x00Zf\x00Zo\x00Zs\x00aa\x00ab\x00ac\x00ae\x00af\x00ag\x00al\x00am\x00an\x00ao\x00ap\x00ar\x00as\x00at\x00au\x00aw\x00bN\x00ba\x00bb\x00bc\x00bd\x00be\x00bf\x00bi\x00bk\x00bl\x00bn\x00bo\x00bp\x00br\x00bs\x00bu\x00ca\x00cc\x00cd\x00ce\x00cf\x00ch\x00ci\x00cl\x00co\x00cr\x00cs\x00ct\x00cu\x00cw\x00cy\x00dA\x00dH\x00da\x00db\x00dc\x00dd\x00de\x00df\x00dh\x00di\x00dj\x00dl\x00do\x00dr\x00ds\x00dt\x00du\x00dw\x00dz\x00eD\x00ea\x00ec\x00ed\x00ee\x00ef\x00eg\x00el\x00em\x00en\x00eo\x00ep\x00eq\x00er\x00es\x00et\x00eu\x00ex\x00fa\x00fc\x00fe\x00ff\x00fi\x00fj\x00fl\x00fn\x00fo\x00fp\x00fr\x00fs\x00gE\x00ga\x00gb\x00gc\x00gd\x00ge\x00gf\x00gg\x00gi\x00gj\x00gl\x00gn\x00go\x00gr\x00gs\x00gt\x00gv\x00hA\x00ha\x00hb\x00hc\x00he\x00hf\x00hk\x00ho\x00hs\x00hy\x00ia\x00ic\x00ie\x00if\x00ig\x00ii\x00ij\x00im\x00in\x00io\x00ip\x00iq\x00is\x00it\x00iu\x00jc\x00jf\x00jm\x00jo\x00js\x00ju\x00ka\x00kc\x00kf\x00kg\x00kh\x00kj\x00ko\x00ks\x00lA\x00lB\x00lE\x00lH\x00la\x00lb\x00lc\x00ld\x00le\x00lf\x00lg\x00lh\x00lj\x00ll\x00lm\x00ln\x00lo\x00lp\x00lr\x00ls\x00lt\x00lu\x00lv\x00mD\x00ma\x00mc\x00md\x00me\x00mf\x00mh\x00mi\x00ml\x00mn\x00mo\x00mp\x00ms\x00mu\x00nG\x00nL\x00nR\x00nV\x00na\x00nb\x00nc\x00nd\x00ne\x00nf\x00ng\x00nh\x00ni\x00nj\x00nl\x00nm\x00no\x00np\x00nr\x00ns\x00nt\x00nu\x00nv\x00nw\x00oS\x00oa\x00oc\x00od\x00oe\x00of\x00og\x00oh\x00oi\x00ol\x00om\x00oo\x00op\x00or\x00os\x00ot\x00ou\x00ov\x00pa\x00pc\x00pe\x00pf\x00ph\x00pi\x00pl\x00pm\x00po\x00pr\x00ps\x00pu\x00qf\x00qi\x00qo\x00qp\x00qs\x00qu\x00rA\x00rB\x00rH\x00ra\x00rb\x00rc\x00rd\x00re\x00rf\x00rh\x00ri\x00rl\x00rm\x00rn\x00ro\x00rp\x00rr\x00rs\x00rt\x00ru\x00rx\x00sa\x00sb\x00sc\x00sd\x00se\x00sf\x00sh\x00si\x00sl\x00sm\x00so\x00sp\x00sq\x00sr\x00ss\x00st\x00su\x00sw\x00sz\x00ta\x00tb\x00tc\x00td\x00te\x00tf\x00th\x00ti\x00to\x00tp\x00tr\x00ts\x00tw\x00uA\x00uH\x00ua\x00ub\x00uc\x00ud\x00uf\x00ug\x00uh\x00ul\x00um\x00uo\x00up\x00ur\x00us\x00ut\x00uu\x00uw\x00vA\x00vB\x00vD\x00va\x00vc\x00vd\x00ve\x00vf\x00vl\x00vn\x00vo\x00vp\x00vr\x00vs\x00vz\x00wc\x00we\x00wf\x00wo\x00wp\x00wr\x00ws\x00xc\x00xd\x00xf\x00xh\x00xi\x00xl\x00xm\x00xn\x00xo\x00xr\x00xs\x00xu\x00xv\x00xw\x00ya\x00yc\x00ye\x00yf\x00yi\x00yo\x00ys\x00yu\x00za\x00zc\x00zd\x00ze\x00zf\x00zh\x00zi\x00zo\x00zs\x00zw\x00", "large_words" => array( // AElig;[Æ] AElig[Æ]. "\x04lig;\x02Æ\x03lig\x02Æ", // AMP;[&] AMP[&]. "\x02P;\x01&\x01P\x01&", // Aacute;[Á] Aacute[Á]. "\x05cute;\x02Á\x04cute\x02Á", // Abreve;[Ă]. "\x05reve;\x02Ă", // Acirc;[Â] Acirc[Â] Acy;[А]. "\x04irc;\x02Â\x03irc\x02Â\x02y;\x02А", // Afr;[𝔄]. "\x02r;\x04𝔄", // Agrave;[À] Agrave[À]. "\x05rave;\x02À\x04rave\x02À", // Alpha;[Α]. "\x04pha;\x02Α", // Amacr;[Ā]. "\x04acr;\x02Ā", // And;[⩓]. "\x02d;\x03⩓", // Aogon;[Ą] Aopf;[𝔸]. "\x04gon;\x02Ą\x03pf;\x04𝔸", // ApplyFunction;[]. "\x0cplyFunction;\x03", // Aring;[Å] Aring[Å]. "\x04ing;\x02Å\x03ing\x02Å", // Assign;[≔] Ascr;[𝒜]. "\x05sign;\x03≔\x03cr;\x04𝒜", // Atilde;[Ã] Atilde[Ã]. "\x05ilde;\x02Ã\x04ilde\x02Ã", // Auml;[Ä] Auml[Ä]. "\x03ml;\x02Ä\x02ml\x02Ä", // Backslash;[∖] Barwed;[⌆] Barv;[⫧]. "\x08ckslash;\x03∖\x05rwed;\x03⌆\x03rv;\x03⫧", // Bcy;[Б]. "\x02y;\x02Б", // Bernoullis;[ℬ] Because;[∵] Beta;[Β]. "\x09rnoullis;\x03ℬ\x06cause;\x03∵\x03ta;\x02Β", // Bfr;[𝔅]. "\x02r;\x04𝔅", // Bopf;[𝔹]. "\x03pf;\x04𝔹", // Breve;[˘]. "\x04eve;\x02˘", // Bscr;[ℬ]. "\x03cr;\x03ℬ", // Bumpeq;[≎]. "\x05mpeq;\x03≎", // CHcy;[Ч]. "\x03cy;\x02Ч", // COPY;[©] COPY[©]. "\x03PY;\x02©\x02PY\x02©", // CapitalDifferentialD;[ⅅ] Cayleys;[ℭ] Cacute;[Ć] Cap;[⋒]. "\x13pitalDifferentialD;\x03ⅅ\x06yleys;\x03ℭ\x05cute;\x02Ć\x02p;\x03⋒", // Cconint;[∰] Ccaron;[Č] Ccedil;[Ç] Ccedil[Ç] Ccirc;[Ĉ]. "\x06onint;\x03∰\x05aron;\x02Č\x05edil;\x02Ç\x04edil\x02Ç\x04irc;\x02Ĉ", // Cdot;[Ċ]. "\x03ot;\x02Ċ", // CenterDot;[·] Cedilla;[¸]. "\x08nterDot;\x02·\x06dilla;\x02¸", // Cfr;[ℭ]. "\x02r;\x03ℭ", // Chi;[Χ]. "\x02i;\x02Χ", // CircleMinus;[⊖] CircleTimes;[⊗] CirclePlus;[⊕] CircleDot;[⊙]. "\x0arcleMinus;\x03⊖\x0arcleTimes;\x03⊗\x09rclePlus;\x03⊕\x08rcleDot;\x03⊙", // ClockwiseContourIntegral;[∲] CloseCurlyDoubleQuote;[”] CloseCurlyQuote;[’]. "\x17ockwiseContourIntegral;\x03∲\x14oseCurlyDoubleQuote;\x03”\x0eoseCurlyQuote;\x03’", // CounterClockwiseContourIntegral;[∳] ContourIntegral;[∮] Congruent;[≡] Coproduct;[∐] Colone;[⩴] Conint;[∯] Colon;[∷] Copf;[ℂ]. "\x1eunterClockwiseContourIntegral;\x03∳\x0entourIntegral;\x03∮\x08ngruent;\x03≡\x08product;\x03∐\x05lone;\x03⩴\x05nint;\x03∯\x04lon;\x03∷\x03pf;\x03ℂ", // Cross;[⨯]. "\x04oss;\x03⨯", // Cscr;[𝒞]. "\x03cr;\x04𝒞", // CupCap;[≍] Cup;[⋓]. "\x05pCap;\x03≍\x02p;\x03⋓", // DDotrahd;[⤑] DD;[ⅅ]. "\x07otrahd;\x03⤑\x01;\x03ⅅ", // DJcy;[Ђ]. "\x03cy;\x02Ђ", // DScy;[Ѕ]. "\x03cy;\x02Ѕ", // DZcy;[Џ]. "\x03cy;\x02Џ", // Dagger;[‡] Dashv;[⫤] Darr;[↡]. "\x05gger;\x03‡\x04shv;\x03⫤\x03rr;\x03↡", // Dcaron;[Ď] Dcy;[Д]. "\x05aron;\x02Ď\x02y;\x02Д", // Delta;[Δ] Del;[∇]. "\x04lta;\x02Δ\x02l;\x03∇", // Dfr;[𝔇]. "\x02r;\x04𝔇", // DiacriticalDoubleAcute;[˝] DiacriticalAcute;[´] DiacriticalGrave;[`] DiacriticalTilde;[˜] DiacriticalDot;[˙] DifferentialD;[ⅆ] Diamond;[⋄]. "\x15acriticalDoubleAcute;\x02˝\x0facriticalAcute;\x02´\x0facriticalGrave;\x01`\x0facriticalTilde;\x02˜\x0dacriticalDot;\x02˙\x0cfferentialD;\x03ⅆ\x06amond;\x03⋄", // DoubleLongLeftRightArrow;[⟺] DoubleContourIntegral;[∯] DoubleLeftRightArrow;[⇔] DoubleLongRightArrow;[⟹] DoubleLongLeftArrow;[⟸] DownLeftRightVector;[⥐] DownRightTeeVector;[⥟] DownRightVectorBar;[⥗] DoubleUpDownArrow;[⇕] DoubleVerticalBar;[∥] DownLeftTeeVector;[⥞] DownLeftVectorBar;[⥖] DoubleRightArrow;[⇒] DownArrowUpArrow;[⇵] DoubleDownArrow;[⇓] DoubleLeftArrow;[⇐] DownRightVector;[⇁] DoubleRightTee;[⊨] DownLeftVector;[↽] DoubleLeftTee;[⫤] DoubleUpArrow;[⇑] DownArrowBar;[⤓] DownTeeArrow;[↧] DoubleDot;[¨] DownArrow;[↓] DownBreve;[̑] Downarrow;[⇓] DotEqual;[≐] DownTee;[⊤] DotDot;[⃜] Dopf;[𝔻] Dot;[¨]. "\x17ubleLongLeftRightArrow;\x03⟺\x14ubleContourIntegral;\x03∯\x13ubleLeftRightArrow;\x03⇔\x13ubleLongRightArrow;\x03⟹\x12ubleLongLeftArrow;\x03⟸\x12wnLeftRightVector;\x03⥐\x11wnRightTeeVector;\x03⥟\x11wnRightVectorBar;\x03⥗\x10ubleUpDownArrow;\x03⇕\x10ubleVerticalBar;\x03∥\x10wnLeftTeeVector;\x03⥞\x10wnLeftVectorBar;\x03⥖\x0fubleRightArrow;\x03⇒\x0fwnArrowUpArrow;\x03⇵\x0eubleDownArrow;\x03⇓\x0eubleLeftArrow;\x03⇐\x0ewnRightVector;\x03⇁\x0dubleRightTee;\x03⊨\x0dwnLeftVector;\x03↽\x0cubleLeftTee;\x03⫤\x0cubleUpArrow;\x03⇑\x0bwnArrowBar;\x03⤓\x0bwnTeeArrow;\x03↧\x08ubleDot;\x02¨\x08wnArrow;\x03↓\x08wnBreve;\x02̑\x08wnarrow;\x03⇓\x07tEqual;\x03≐\x06wnTee;\x03⊤\x05tDot;\x03⃜\x03pf;\x04𝔻\x02t;\x02¨", // Dstrok;[Đ] Dscr;[𝒟]. "\x05trok;\x02Đ\x03cr;\x04𝒟", // ENG;[Ŋ]. "\x02G;\x02Ŋ", // ETH;[Ð] ETH[Ð]. "\x02H;\x02Ð\x01H\x02Ð", // Eacute;[É] Eacute[É]. "\x05cute;\x02É\x04cute\x02É", // Ecaron;[Ě] Ecirc;[Ê] Ecirc[Ê] Ecy;[Э]. "\x05aron;\x02Ě\x04irc;\x02Ê\x03irc\x02Ê\x02y;\x02Э", // Edot;[Ė]. "\x03ot;\x02Ė", // Efr;[𝔈]. "\x02r;\x04𝔈", // Egrave;[È] Egrave[È]. "\x05rave;\x02È\x04rave\x02È", // Element;[∈]. "\x06ement;\x03∈", // EmptyVerySmallSquare;[▫] EmptySmallSquare;[◻] Emacr;[Ē]. "\x13ptyVerySmallSquare;\x03▫\x0fptySmallSquare;\x03◻\x04acr;\x02Ē", // Eogon;[Ę] Eopf;[𝔼]. "\x04gon;\x02Ę\x03pf;\x04𝔼", // Epsilon;[Ε]. "\x06silon;\x02Ε", // Equilibrium;[⇌] EqualTilde;[≂] Equal;[⩵]. "\x0auilibrium;\x03⇌\x09ualTilde;\x03≂\x04ual;\x03⩵", // Escr;[ℰ] Esim;[⩳]. "\x03cr;\x03ℰ\x03im;\x03⩳", // Eta;[Η]. "\x02a;\x02Η", // Euml;[Ë] Euml[Ë]. "\x03ml;\x02Ë\x02ml\x02Ë", // ExponentialE;[ⅇ] Exists;[∃]. "\x0bponentialE;\x03ⅇ\x05ists;\x03∃", // Fcy;[Ф]. "\x02y;\x02Ф", // Ffr;[𝔉]. "\x02r;\x04𝔉", // FilledVerySmallSquare;[▪] FilledSmallSquare;[◼]. "\x14lledVerySmallSquare;\x03▪\x10lledSmallSquare;\x03◼", // Fouriertrf;[ℱ] ForAll;[∀] Fopf;[𝔽]. "\x09uriertrf;\x03ℱ\x05rAll;\x03∀\x03pf;\x04𝔽", // Fscr;[ℱ]. "\x03cr;\x03ℱ", // GJcy;[Ѓ]. "\x03cy;\x02Ѓ", // GT;[>]. "\x01;\x01>", // Gammad;[Ϝ] Gamma;[Γ]. "\x05mmad;\x02Ϝ\x04mma;\x02Γ", // Gbreve;[Ğ]. "\x05reve;\x02Ğ", // Gcedil;[Ģ] Gcirc;[Ĝ] Gcy;[Г]. "\x05edil;\x02Ģ\x04irc;\x02Ĝ\x02y;\x02Г", // Gdot;[Ġ]. "\x03ot;\x02Ġ", // Gfr;[𝔊]. "\x02r;\x04𝔊", // Gg;[⋙]. "\x01;\x03⋙", // Gopf;[𝔾]. "\x03pf;\x04𝔾", // GreaterSlantEqual;[⩾] GreaterEqualLess;[⋛] GreaterFullEqual;[≧] GreaterGreater;[⪢] GreaterEqual;[≥] GreaterTilde;[≳] GreaterLess;[≷]. "\x10eaterSlantEqual;\x03⩾\x0featerEqualLess;\x03⋛\x0featerFullEqual;\x03≧\x0deaterGreater;\x03⪢\x0beaterEqual;\x03≥\x0beaterTilde;\x03≳\x0aeaterLess;\x03≷", // Gscr;[𝒢]. "\x03cr;\x04𝒢", // Gt;[≫]. "\x01;\x03≫", // HARDcy;[Ъ]. "\x05RDcy;\x02Ъ", // Hacek;[ˇ] Hat;[^]. "\x04cek;\x02ˇ\x02t;\x01^", // Hcirc;[Ĥ]. "\x04irc;\x02Ĥ", // Hfr;[ℌ]. "\x02r;\x03ℌ", // HilbertSpace;[ℋ]. "\x0blbertSpace;\x03ℋ", // HorizontalLine;[─] Hopf;[ℍ]. "\x0drizontalLine;\x03─\x03pf;\x03ℍ", // Hstrok;[Ħ] Hscr;[ℋ]. "\x05trok;\x02Ħ\x03cr;\x03ℋ", // HumpDownHump;[≎] HumpEqual;[≏]. "\x0bmpDownHump;\x03≎\x08mpEqual;\x03≏", // IEcy;[Е]. "\x03cy;\x02Е", // IJlig;[IJ]. "\x04lig;\x02IJ", // IOcy;[Ё]. "\x03cy;\x02Ё", // Iacute;[Í] Iacute[Í]. "\x05cute;\x02Í\x04cute\x02Í", // Icirc;[Î] Icirc[Î] Icy;[И]. "\x04irc;\x02Î\x03irc\x02Î\x02y;\x02И", // Idot;[İ]. "\x03ot;\x02İ", // Ifr;[ℑ]. "\x02r;\x03ℑ", // Igrave;[Ì] Igrave[Ì]. "\x05rave;\x02Ì\x04rave\x02Ì", // ImaginaryI;[ⅈ] Implies;[⇒] Imacr;[Ī] Im;[ℑ]. "\x09aginaryI;\x03ⅈ\x06plies;\x03⇒\x04acr;\x02Ī\x01;\x03ℑ", // InvisibleComma;[] InvisibleTimes;[] Intersection;[⋂] Integral;[∫] Int;[∬]. "\x0dvisibleComma;\x03\x0dvisibleTimes;\x03\x0btersection;\x03⋂\x07tegral;\x03∫\x02t;\x03∬", // Iogon;[Į] Iopf;[𝕀] Iota;[Ι]. "\x04gon;\x02Į\x03pf;\x04𝕀\x03ta;\x02Ι", // Iscr;[ℐ]. "\x03cr;\x03ℐ", // Itilde;[Ĩ]. "\x05ilde;\x02Ĩ", // Iukcy;[І] Iuml;[Ï] Iuml[Ï]. "\x04kcy;\x02І\x03ml;\x02Ï\x02ml\x02Ï", // Jcirc;[Ĵ] Jcy;[Й]. "\x04irc;\x02Ĵ\x02y;\x02Й", // Jfr;[𝔍]. "\x02r;\x04𝔍", // Jopf;[𝕁]. "\x03pf;\x04𝕁", // Jsercy;[Ј] Jscr;[𝒥]. "\x05ercy;\x02Ј\x03cr;\x04𝒥", // Jukcy;[Є]. "\x04kcy;\x02Є", // KHcy;[Х]. "\x03cy;\x02Х", // KJcy;[Ќ]. "\x03cy;\x02Ќ", // Kappa;[Κ]. "\x04ppa;\x02Κ", // Kcedil;[Ķ] Kcy;[К]. "\x05edil;\x02Ķ\x02y;\x02К", // Kfr;[𝔎]. "\x02r;\x04𝔎", // Kopf;[𝕂]. "\x03pf;\x04𝕂", // Kscr;[𝒦]. "\x03cr;\x04𝒦", // LJcy;[Љ]. "\x03cy;\x02Љ", // LT;[<]. "\x01;\x01<", // Laplacetrf;[ℒ] Lacute;[Ĺ] Lambda;[Λ] Lang;[⟪] Larr;[↞]. "\x09placetrf;\x03ℒ\x05cute;\x02Ĺ\x05mbda;\x02Λ\x03ng;\x03⟪\x03rr;\x03↞", // Lcaron;[Ľ] Lcedil;[Ļ] Lcy;[Л]. "\x05aron;\x02Ľ\x05edil;\x02Ļ\x02y;\x02Л", // LeftArrowRightArrow;[⇆] LeftDoubleBracket;[⟦] LeftDownTeeVector;[⥡] LeftDownVectorBar;[⥙] LeftTriangleEqual;[⊴] LeftAngleBracket;[⟨] LeftUpDownVector;[⥑] LessEqualGreater;[⋚] LeftRightVector;[⥎] LeftTriangleBar;[⧏] LeftUpTeeVector;[⥠] LeftUpVectorBar;[⥘] LeftDownVector;[⇃] LeftRightArrow;[↔] Leftrightarrow;[⇔] LessSlantEqual;[⩽] LeftTeeVector;[⥚] LeftVectorBar;[⥒] LessFullEqual;[≦] LeftArrowBar;[⇤] LeftTeeArrow;[↤] LeftTriangle;[⊲] LeftUpVector;[↿] LeftCeiling;[⌈] LessGreater;[≶] LeftVector;[↼] LeftArrow;[←] LeftFloor;[⌊] Leftarrow;[⇐] LessTilde;[≲] LessLess;[⪡] LeftTee;[⊣]. "\x12ftArrowRightArrow;\x03⇆\x10ftDoubleBracket;\x03⟦\x10ftDownTeeVector;\x03⥡\x10ftDownVectorBar;\x03⥙\x10ftTriangleEqual;\x03⊴\x0fftAngleBracket;\x03⟨\x0fftUpDownVector;\x03⥑\x0fssEqualGreater;\x03⋚\x0eftRightVector;\x03⥎\x0eftTriangleBar;\x03⧏\x0eftUpTeeVector;\x03⥠\x0eftUpVectorBar;\x03⥘\x0dftDownVector;\x03⇃\x0dftRightArrow;\x03↔\x0dftrightarrow;\x03⇔\x0dssSlantEqual;\x03⩽\x0cftTeeVector;\x03⥚\x0cftVectorBar;\x03⥒\x0cssFullEqual;\x03≦\x0bftArrowBar;\x03⇤\x0bftTeeArrow;\x03↤\x0bftTriangle;\x03⊲\x0bftUpVector;\x03↿\x0aftCeiling;\x03⌈\x0assGreater;\x03≶\x09ftVector;\x03↼\x08ftArrow;\x03←\x08ftFloor;\x03⌊\x08ftarrow;\x03⇐\x08ssTilde;\x03≲\x07ssLess;\x03⪡\x06ftTee;\x03⊣", // Lfr;[𝔏]. "\x02r;\x04𝔏", // Lleftarrow;[⇚] Ll;[⋘]. "\x09eftarrow;\x03⇚\x01;\x03⋘", // Lmidot;[Ŀ]. "\x05idot;\x02Ŀ", // LongLeftRightArrow;[⟷] Longleftrightarrow;[⟺] LowerRightArrow;[↘] LongRightArrow;[⟶] Longrightarrow;[⟹] LowerLeftArrow;[↙] LongLeftArrow;[⟵] Longleftarrow;[⟸] Lopf;[𝕃]. "\x11ngLeftRightArrow;\x03⟷\x11ngleftrightarrow;\x03⟺\x0ewerRightArrow;\x03↘\x0dngRightArrow;\x03⟶\x0dngrightarrow;\x03⟹\x0dwerLeftArrow;\x03↙\x0cngLeftArrow;\x03⟵\x0cngleftarrow;\x03⟸\x03pf;\x04𝕃", // Lstrok;[Ł] Lscr;[ℒ] Lsh;[↰]. "\x05trok;\x02Ł\x03cr;\x03ℒ\x02h;\x03↰", // Lt;[≪]. "\x01;\x03≪", // Map;[⤅]. "\x02p;\x03⤅", // Mcy;[М]. "\x02y;\x02М", // MediumSpace;[ ] Mellintrf;[ℳ]. "\x0adiumSpace;\x03 \x08llintrf;\x03ℳ", // Mfr;[𝔐]. "\x02r;\x04𝔐", // MinusPlus;[∓]. "\x08nusPlus;\x03∓", // Mopf;[𝕄]. "\x03pf;\x04𝕄", // Mscr;[ℳ]. "\x03cr;\x03ℳ", // Mu;[Μ]. "\x01;\x02Μ", // NJcy;[Њ]. "\x03cy;\x02Њ", // Nacute;[Ń]. "\x05cute;\x02Ń", // Ncaron;[Ň] Ncedil;[Ņ] Ncy;[Н]. "\x05aron;\x02Ň\x05edil;\x02Ņ\x02y;\x02Н", // NegativeVeryThinSpace;[] NestedGreaterGreater;[≫] NegativeMediumSpace;[] NegativeThickSpace;[] NegativeThinSpace;[] NestedLessLess;[≪] NewLine;[\xa]. "\x14gativeVeryThinSpace;\x03\x13stedGreaterGreater;\x03≫\x12gativeMediumSpace;\x03\x11gativeThickSpace;\x03\x10gativeThinSpace;\x03\x0dstedLessLess;\x03≪\x06wLine;\x01\xa", // Nfr;[𝔑]. "\x02r;\x04𝔑", // NotNestedGreaterGreater;[⪢̸] NotSquareSupersetEqual;[⋣] NotPrecedesSlantEqual;[⋠] NotRightTriangleEqual;[⋭] NotSucceedsSlantEqual;[⋡] NotDoubleVerticalBar;[∦] NotGreaterSlantEqual;[⩾̸] NotLeftTriangleEqual;[⋬] NotSquareSubsetEqual;[⋢] NotGreaterFullEqual;[≧̸] NotRightTriangleBar;[⧐̸] NotLeftTriangleBar;[⧏̸] NotGreaterGreater;[≫̸] NotLessSlantEqual;[⩽̸] NotNestedLessLess;[⪡̸] NotReverseElement;[∌] NotSquareSuperset;[⊐̸] NotTildeFullEqual;[≇] NonBreakingSpace;[ ] NotPrecedesEqual;[⪯̸] NotRightTriangle;[⋫] NotSucceedsEqual;[⪰̸] NotSucceedsTilde;[≿̸] NotSupersetEqual;[⊉] NotGreaterEqual;[≱] NotGreaterTilde;[≵] NotHumpDownHump;[≎̸] NotLeftTriangle;[⋪] NotSquareSubset;[⊏̸] NotGreaterLess;[≹] NotLessGreater;[≸] NotSubsetEqual;[⊈] NotVerticalBar;[∤] NotEqualTilde;[≂̸] NotTildeEqual;[≄] NotTildeTilde;[≉] NotCongruent;[≢] NotHumpEqual;[≏̸] NotLessEqual;[≰] NotLessTilde;[≴] NotLessLess;[≪̸] NotPrecedes;[⊀] NotSucceeds;[⊁] NotSuperset;[⊃⃒] NotElement;[∉] NotGreater;[≯] NotCupCap;[≭] NotExists;[∄] NotSubset;[⊂⃒] NotEqual;[≠] NotTilde;[≁] NoBreak;[] NotLess;[≮] Nopf;[ℕ] Not;[⫬]. "\x16tNestedGreaterGreater;\x05⪢̸\x15tSquareSupersetEqual;\x03⋣\x14tPrecedesSlantEqual;\x03⋠\x14tRightTriangleEqual;\x03⋭\x14tSucceedsSlantEqual;\x03⋡\x13tDoubleVerticalBar;\x03∦\x13tGreaterSlantEqual;\x05⩾̸\x13tLeftTriangleEqual;\x03⋬\x13tSquareSubsetEqual;\x03⋢\x12tGreaterFullEqual;\x05≧̸\x12tRightTriangleBar;\x05⧐̸\x11tLeftTriangleBar;\x05⧏̸\x10tGreaterGreater;\x05≫̸\x10tLessSlantEqual;\x05⩽̸\x10tNestedLessLess;\x05⪡̸\x10tReverseElement;\x03∌\x10tSquareSuperset;\x05⊐̸\x10tTildeFullEqual;\x03≇\x0fnBreakingSpace;\x02 \x0ftPrecedesEqual;\x05⪯̸\x0ftRightTriangle;\x03⋫\x0ftSucceedsEqual;\x05⪰̸\x0ftSucceedsTilde;\x05≿̸\x0ftSupersetEqual;\x03⊉\x0etGreaterEqual;\x03≱\x0etGreaterTilde;\x03≵\x0etHumpDownHump;\x05≎̸\x0etLeftTriangle;\x03⋪\x0etSquareSubset;\x05⊏̸\x0dtGreaterLess;\x03≹\x0dtLessGreater;\x03≸\x0dtSubsetEqual;\x03⊈\x0dtVerticalBar;\x03∤\x0ctEqualTilde;\x05≂̸\x0ctTildeEqual;\x03≄\x0ctTildeTilde;\x03≉\x0btCongruent;\x03≢\x0btHumpEqual;\x05≏̸\x0btLessEqual;\x03≰\x0btLessTilde;\x03≴\x0atLessLess;\x05≪̸\x0atPrecedes;\x03⊀\x0atSucceeds;\x03⊁\x0atSuperset;\x06⊃⃒\x09tElement;\x03∉\x09tGreater;\x03≯\x08tCupCap;\x03≭\x08tExists;\x03∄\x08tSubset;\x06⊂⃒\x07tEqual;\x03≠\x07tTilde;\x03≁\x06Break;\x03\x06tLess;\x03≮\x03pf;\x03ℕ\x02t;\x03⫬", // Nscr;[𝒩]. "\x03cr;\x04𝒩", // Ntilde;[Ñ] Ntilde[Ñ]. "\x05ilde;\x02Ñ\x04ilde\x02Ñ", // Nu;[Ν]. "\x01;\x02Ν", // OElig;[Œ]. "\x04lig;\x02Œ", // Oacute;[Ó] Oacute[Ó]. "\x05cute;\x02Ó\x04cute\x02Ó", // Ocirc;[Ô] Ocirc[Ô] Ocy;[О]. "\x04irc;\x02Ô\x03irc\x02Ô\x02y;\x02О", // Odblac;[Ő]. "\x05blac;\x02Ő", // Ofr;[𝔒]. "\x02r;\x04𝔒", // Ograve;[Ò] Ograve[Ò]. "\x05rave;\x02Ò\x04rave\x02Ò", // Omicron;[Ο] Omacr;[Ō] Omega;[Ω]. "\x06icron;\x02Ο\x04acr;\x02Ō\x04ega;\x02Ω", // Oopf;[𝕆]. "\x03pf;\x04𝕆", // OpenCurlyDoubleQuote;[“] OpenCurlyQuote;[‘]. "\x13enCurlyDoubleQuote;\x03“\x0denCurlyQuote;\x03‘", // Or;[⩔]. "\x01;\x03⩔", // Oslash;[Ø] Oslash[Ø] Oscr;[𝒪]. "\x05lash;\x02Ø\x04lash\x02Ø\x03cr;\x04𝒪", // Otilde;[Õ] Otimes;[⨷] Otilde[Õ]. "\x05ilde;\x02Õ\x05imes;\x03⨷\x04ilde\x02Õ", // Ouml;[Ö] Ouml[Ö]. "\x03ml;\x02Ö\x02ml\x02Ö", // OverParenthesis;[⏜] OverBracket;[⎴] OverBrace;[⏞] OverBar;[‾]. "\x0eerParenthesis;\x03⏜\x0aerBracket;\x03⎴\x08erBrace;\x03⏞\x06erBar;\x03‾", // PartialD;[∂]. "\x07rtialD;\x03∂", // Pcy;[П]. "\x02y;\x02П", // Pfr;[𝔓]. "\x02r;\x04𝔓", // Phi;[Φ]. "\x02i;\x02Φ", // Pi;[Π]. "\x01;\x02Π", // PlusMinus;[±]. "\x08usMinus;\x02±", // Poincareplane;[ℌ] Popf;[ℙ]. "\x0cincareplane;\x03ℌ\x03pf;\x03ℙ", // PrecedesSlantEqual;[≼] PrecedesEqual;[⪯] PrecedesTilde;[≾] Proportional;[∝] Proportion;[∷] Precedes;[≺] Product;[∏] Prime;[″] Pr;[⪻]. "\x11ecedesSlantEqual;\x03≼\x0cecedesEqual;\x03⪯\x0cecedesTilde;\x03≾\x0boportional;\x03∝\x09oportion;\x03∷\x07ecedes;\x03≺\x06oduct;\x03∏\x04ime;\x03″\x01;\x03⪻", // Pscr;[𝒫] Psi;[Ψ]. "\x03cr;\x04𝒫\x02i;\x02Ψ", // QUOT;[\"] QUOT[\"]. "\x03OT;\x01\"\x02OT\x01\"", // Qfr;[𝔔]. "\x02r;\x04𝔔", // Qopf;[ℚ]. "\x03pf;\x03ℚ", // Qscr;[𝒬]. "\x03cr;\x04𝒬", // RBarr;[⤐]. "\x04arr;\x03⤐", // REG;[®] REG[®]. "\x02G;\x02®\x01G\x02®", // Racute;[Ŕ] Rarrtl;[⤖] Rang;[⟫] Rarr;[↠]. "\x05cute;\x02Ŕ\x05rrtl;\x03⤖\x03ng;\x03⟫\x03rr;\x03↠", // Rcaron;[Ř] Rcedil;[Ŗ] Rcy;[Р]. "\x05aron;\x02Ř\x05edil;\x02Ŗ\x02y;\x02Р", // ReverseUpEquilibrium;[⥯] ReverseEquilibrium;[⇋] ReverseElement;[∋] Re;[ℜ]. "\x13verseUpEquilibrium;\x03⥯\x11verseEquilibrium;\x03⇋\x0dverseElement;\x03∋\x01;\x03ℜ", // Rfr;[ℜ]. "\x02r;\x03ℜ", // Rho;[Ρ]. "\x02o;\x02Ρ", // RightArrowLeftArrow;[⇄] RightDoubleBracket;[⟧] RightDownTeeVector;[⥝] RightDownVectorBar;[⥕] RightTriangleEqual;[⊵] RightAngleBracket;[⟩] RightUpDownVector;[⥏] RightTriangleBar;[⧐] RightUpTeeVector;[⥜] RightUpVectorBar;[⥔] RightDownVector;[⇂] RightTeeVector;[⥛] RightVectorBar;[⥓] RightArrowBar;[⇥] RightTeeArrow;[↦] RightTriangle;[⊳] RightUpVector;[↾] RightCeiling;[⌉] RightVector;[⇀] RightArrow;[→] RightFloor;[⌋] Rightarrow;[⇒] RightTee;[⊢]. "\x12ghtArrowLeftArrow;\x03⇄\x11ghtDoubleBracket;\x03⟧\x11ghtDownTeeVector;\x03⥝\x11ghtDownVectorBar;\x03⥕\x11ghtTriangleEqual;\x03⊵\x10ghtAngleBracket;\x03⟩\x10ghtUpDownVector;\x03⥏\x0fghtTriangleBar;\x03⧐\x0fghtUpTeeVector;\x03⥜\x0fghtUpVectorBar;\x03⥔\x0eghtDownVector;\x03⇂\x0dghtTeeVector;\x03⥛\x0dghtVectorBar;\x03⥓\x0cghtArrowBar;\x03⇥\x0cghtTeeArrow;\x03↦\x0cghtTriangle;\x03⊳\x0cghtUpVector;\x03↾\x0bghtCeiling;\x03⌉\x0aghtVector;\x03⇀\x09ghtArrow;\x03→\x09ghtFloor;\x03⌋\x09ghtarrow;\x03⇒\x07ghtTee;\x03⊢", // RoundImplies;[⥰] Ropf;[ℝ]. "\x0bundImplies;\x03⥰\x03pf;\x03ℝ", // Rrightarrow;[⇛]. "\x0aightarrow;\x03⇛", // Rscr;[ℛ] Rsh;[↱]. "\x03cr;\x03ℛ\x02h;\x03↱", // RuleDelayed;[⧴]. "\x0aleDelayed;\x03⧴", // SHCHcy;[Щ] SHcy;[Ш]. "\x05CHcy;\x02Щ\x03cy;\x02Ш", // SOFTcy;[Ь]. "\x05FTcy;\x02Ь", // Sacute;[Ś]. "\x05cute;\x02Ś", // Scaron;[Š] Scedil;[Ş] Scirc;[Ŝ] Scy;[С] Sc;[⪼]. "\x05aron;\x02Š\x05edil;\x02Ş\x04irc;\x02Ŝ\x02y;\x02С\x01;\x03⪼", // Sfr;[𝔖]. "\x02r;\x04𝔖", // ShortRightArrow;[→] ShortDownArrow;[↓] ShortLeftArrow;[←] ShortUpArrow;[↑]. "\x0eortRightArrow;\x03→\x0dortDownArrow;\x03↓\x0dortLeftArrow;\x03←\x0bortUpArrow;\x03↑", // Sigma;[Σ]. "\x04gma;\x02Σ", // SmallCircle;[∘]. "\x0aallCircle;\x03∘", // Sopf;[𝕊]. "\x03pf;\x04𝕊", // SquareSupersetEqual;[⊒] SquareIntersection;[⊓] SquareSubsetEqual;[⊑] SquareSuperset;[⊐] SquareSubset;[⊏] SquareUnion;[⊔] Square;[□] Sqrt;[√]. "\x12uareSupersetEqual;\x03⊒\x11uareIntersection;\x03⊓\x10uareSubsetEqual;\x03⊑\x0duareSuperset;\x03⊐\x0buareSubset;\x03⊏\x0auareUnion;\x03⊔\x05uare;\x03□\x03rt;\x03√", // Sscr;[𝒮]. "\x03cr;\x04𝒮", // Star;[⋆]. "\x03ar;\x03⋆", // SucceedsSlantEqual;[≽] SucceedsEqual;[⪰] SucceedsTilde;[≿] SupersetEqual;[⊇] SubsetEqual;[⊆] Succeeds;[≻] SuchThat;[∋] Superset;[⊃] Subset;[⋐] Supset;[⋑] Sub;[⋐] Sum;[∑] Sup;[⋑]. "\x11cceedsSlantEqual;\x03≽\x0ccceedsEqual;\x03⪰\x0ccceedsTilde;\x03≿\x0cpersetEqual;\x03⊇\x0absetEqual;\x03⊆\x07cceeds;\x03≻\x07chThat;\x03∋\x07perset;\x03⊃\x05bset;\x03⋐\x05pset;\x03⋑\x02b;\x03⋐\x02m;\x03∑\x02p;\x03⋑", // THORN;[Þ] THORN[Þ]. "\x04ORN;\x02Þ\x03ORN\x02Þ", // TRADE;[™]. "\x04ADE;\x03™", // TSHcy;[Ћ] TScy;[Ц]. "\x04Hcy;\x02Ћ\x03cy;\x02Ц", // Tab;[\x9] Tau;[Τ]. "\x02b;\x01\x9\x02u;\x02Τ", // Tcaron;[Ť] Tcedil;[Ţ] Tcy;[Т]. "\x05aron;\x02Ť\x05edil;\x02Ţ\x02y;\x02Т", // Tfr;[𝔗]. "\x02r;\x04𝔗", // ThickSpace;[ ] Therefore;[∴] ThinSpace;[ ] Theta;[Θ]. "\x09ickSpace;\x06 \x08erefore;\x03∴\x08inSpace;\x03 \x04eta;\x02Θ", // TildeFullEqual;[≅] TildeEqual;[≃] TildeTilde;[≈] Tilde;[∼]. "\x0dldeFullEqual;\x03≅\x09ldeEqual;\x03≃\x09ldeTilde;\x03≈\x04lde;\x03∼", // Topf;[𝕋]. "\x03pf;\x04𝕋", // TripleDot;[⃛]. "\x08ipleDot;\x03⃛", // Tstrok;[Ŧ] Tscr;[𝒯]. "\x05trok;\x02Ŧ\x03cr;\x04𝒯", // Uarrocir;[⥉] Uacute;[Ú] Uacute[Ú] Uarr;[↟]. "\x07rrocir;\x03⥉\x05cute;\x02Ú\x04cute\x02Ú\x03rr;\x03↟", // Ubreve;[Ŭ] Ubrcy;[Ў]. "\x05reve;\x02Ŭ\x04rcy;\x02Ў", // Ucirc;[Û] Ucirc[Û] Ucy;[У]. "\x04irc;\x02Û\x03irc\x02Û\x02y;\x02У", // Udblac;[Ű]. "\x05blac;\x02Ű", // Ufr;[𝔘]. "\x02r;\x04𝔘", // Ugrave;[Ù] Ugrave[Ù]. "\x05rave;\x02Ù\x04rave\x02Ù", // Umacr;[Ū]. "\x04acr;\x02Ū", // UnderParenthesis;[⏝] UnderBracket;[⎵] UnderBrace;[⏟] UnionPlus;[⊎] UnderBar;[_] Union;[⋃]. "\x0fderParenthesis;\x03⏝\x0bderBracket;\x03⎵\x09derBrace;\x03⏟\x08ionPlus;\x03⊎\x07derBar;\x01_\x04ion;\x03⋃", // Uogon;[Ų] Uopf;[𝕌]. "\x04gon;\x02Ų\x03pf;\x04𝕌", // UpArrowDownArrow;[⇅] UpperRightArrow;[↗] UpperLeftArrow;[↖] UpEquilibrium;[⥮] UpDownArrow;[↕] Updownarrow;[⇕] UpArrowBar;[⤒] UpTeeArrow;[↥] UpArrow;[↑] Uparrow;[⇑] Upsilon;[Υ] UpTee;[⊥] Upsi;[ϒ]. "\x0fArrowDownArrow;\x03⇅\x0eperRightArrow;\x03↗\x0dperLeftArrow;\x03↖\x0cEquilibrium;\x03⥮\x0aDownArrow;\x03↕\x0adownarrow;\x03⇕\x09ArrowBar;\x03⤒\x09TeeArrow;\x03↥\x06Arrow;\x03↑\x06arrow;\x03⇑\x06silon;\x02Υ\x04Tee;\x03⊥\x03si;\x02ϒ", // Uring;[Ů]. "\x04ing;\x02Ů", // Uscr;[𝒰]. "\x03cr;\x04𝒰", // Utilde;[Ũ]. "\x05ilde;\x02Ũ", // Uuml;[Ü] Uuml[Ü]. "\x03ml;\x02Ü\x02ml\x02Ü", // VDash;[⊫]. "\x04ash;\x03⊫", // Vbar;[⫫]. "\x03ar;\x03⫫", // Vcy;[В]. "\x02y;\x02В", // Vdashl;[⫦] Vdash;[⊩]. "\x05ashl;\x03⫦\x04ash;\x03⊩", // VerticalSeparator;[❘] VerticalTilde;[≀] VeryThinSpace;[ ] VerticalLine;[|] VerticalBar;[∣] Verbar;[‖] Vert;[‖] Vee;[⋁]. "\x10rticalSeparator;\x03❘\x0crticalTilde;\x03≀\x0cryThinSpace;\x03 \x0brticalLine;\x01|\x0articalBar;\x03∣\x05rbar;\x03‖\x03rt;\x03‖\x02e;\x03⋁", // Vfr;[𝔙]. "\x02r;\x04𝔙", // Vopf;[𝕍]. "\x03pf;\x04𝕍", // Vscr;[𝒱]. "\x03cr;\x04𝒱", // Vvdash;[⊪]. "\x05dash;\x03⊪", // Wcirc;[Ŵ]. "\x04irc;\x02Ŵ", // Wedge;[⋀]. "\x04dge;\x03⋀", // Wfr;[𝔚]. "\x02r;\x04𝔚", // Wopf;[𝕎]. "\x03pf;\x04𝕎", // Wscr;[𝒲]. "\x03cr;\x04𝒲", // Xfr;[𝔛]. "\x02r;\x04𝔛", // Xi;[Ξ]. "\x01;\x02Ξ", // Xopf;[𝕏]. "\x03pf;\x04𝕏", // Xscr;[𝒳]. "\x03cr;\x04𝒳", // YAcy;[Я]. "\x03cy;\x02Я", // YIcy;[Ї]. "\x03cy;\x02Ї", // YUcy;[Ю]. "\x03cy;\x02Ю", // Yacute;[Ý] Yacute[Ý]. "\x05cute;\x02Ý\x04cute\x02Ý", // Ycirc;[Ŷ] Ycy;[Ы]. "\x04irc;\x02Ŷ\x02y;\x02Ы", // Yfr;[𝔜]. "\x02r;\x04𝔜", // Yopf;[𝕐]. "\x03pf;\x04𝕐", // Yscr;[𝒴]. "\x03cr;\x04𝒴", // Yuml;[Ÿ]. "\x03ml;\x02Ÿ", // ZHcy;[Ж]. "\x03cy;\x02Ж", // Zacute;[Ź]. "\x05cute;\x02Ź", // Zcaron;[Ž] Zcy;[З]. "\x05aron;\x02Ž\x02y;\x02З", // Zdot;[Ż]. "\x03ot;\x02Ż", // ZeroWidthSpace;[] Zeta;[Ζ]. "\x0droWidthSpace;\x03\x03ta;\x02Ζ", // Zfr;[ℨ]. "\x02r;\x03ℨ", // Zopf;[ℤ]. "\x03pf;\x03ℤ", // Zscr;[𝒵]. "\x03cr;\x04𝒵", // aacute;[á] aacute[á]. "\x05cute;\x02á\x04cute\x02á", // abreve;[ă]. "\x05reve;\x02ă", // acirc;[â] acute;[´] acirc[â] acute[´] acE;[∾̳] acd;[∿] acy;[а] ac;[∾]. "\x04irc;\x02â\x04ute;\x02´\x03irc\x02â\x03ute\x02´\x02E;\x05∾̳\x02d;\x03∿\x02y;\x02а\x01;\x03∾", // aelig;[æ] aelig[æ]. "\x04lig;\x02æ\x03lig\x02æ", // afr;[𝔞] af;[]. "\x02r;\x04𝔞\x01;\x03", // agrave;[à] agrave[à]. "\x05rave;\x02à\x04rave\x02à", // alefsym;[ℵ] aleph;[ℵ] alpha;[α]. "\x06efsym;\x03ℵ\x04eph;\x03ℵ\x04pha;\x02α", // amacr;[ā] amalg;[⨿] amp;[&] amp[&]. "\x04acr;\x02ā\x04alg;\x03⨿\x02p;\x01&\x01p\x01&", // andslope;[⩘] angmsdaa;[⦨] angmsdab;[⦩] angmsdac;[⦪] angmsdad;[⦫] angmsdae;[⦬] angmsdaf;[⦭] angmsdag;[⦮] angmsdah;[⦯] angrtvbd;[⦝] angrtvb;[⊾] angzarr;[⍼] andand;[⩕] angmsd;[∡] angsph;[∢] angle;[∠] angrt;[∟] angst;[Å] andd;[⩜] andv;[⩚] ange;[⦤] and;[∧] ang;[∠]. "\x07dslope;\x03⩘\x07gmsdaa;\x03⦨\x07gmsdab;\x03⦩\x07gmsdac;\x03⦪\x07gmsdad;\x03⦫\x07gmsdae;\x03⦬\x07gmsdaf;\x03⦭\x07gmsdag;\x03⦮\x07gmsdah;\x03⦯\x07grtvbd;\x03⦝\x06grtvb;\x03⊾\x06gzarr;\x03⍼\x05dand;\x03⩕\x05gmsd;\x03∡\x05gsph;\x03∢\x04gle;\x03∠\x04grt;\x03∟\x04gst;\x02Å\x03dd;\x03⩜\x03dv;\x03⩚\x03ge;\x03⦤\x02d;\x03∧\x02g;\x03∠", // aogon;[ą] aopf;[𝕒]. "\x04gon;\x02ą\x03pf;\x04𝕒", // approxeq;[≊] apacir;[⩯] approx;[≈] apid;[≋] apos;['] apE;[⩰] ape;[≊] ap;[≈]. "\x07proxeq;\x03≊\x05acir;\x03⩯\x05prox;\x03≈\x03id;\x03≋\x03os;\x01'\x02E;\x03⩰\x02e;\x03≊\x01;\x03≈", // aring;[å] aring[å]. "\x04ing;\x02å\x03ing\x02å", // asympeq;[≍] asymp;[≈] ascr;[𝒶] ast;[*]. "\x06ympeq;\x03≍\x04ymp;\x03≈\x03cr;\x04𝒶\x02t;\x01*", // atilde;[ã] atilde[ã]. "\x05ilde;\x02ã\x04ilde\x02ã", // auml;[ä] auml[ä]. "\x03ml;\x02ä\x02ml\x02ä", // awconint;[∳] awint;[⨑]. "\x07conint;\x03∳\x04int;\x03⨑", // bNot;[⫭]. "\x03ot;\x03⫭", // backepsilon;[϶] backprime;[‵] backsimeq;[⋍] backcong;[≌] barwedge;[⌅] backsim;[∽] barvee;[⊽] barwed;[⌅]. "\x0ackepsilon;\x02϶\x08ckprime;\x03‵\x08cksimeq;\x03⋍\x07ckcong;\x03≌\x07rwedge;\x03⌅\x06cksim;\x03∽\x05rvee;\x03⊽\x05rwed;\x03⌅", // bbrktbrk;[⎶] bbrk;[⎵]. "\x07rktbrk;\x03⎶\x03rk;\x03⎵", // bcong;[≌] bcy;[б]. "\x04ong;\x03≌\x02y;\x02б", // bdquo;[„]. "\x04quo;\x03„", // because;[∵] bemptyv;[⦰] between;[≬] becaus;[∵] bernou;[ℬ] bepsi;[϶] beta;[β] beth;[ℶ]. "\x06cause;\x03∵\x06mptyv;\x03⦰\x06tween;\x03≬\x05caus;\x03∵\x05rnou;\x03ℬ\x04psi;\x02϶\x03ta;\x02β\x03th;\x03ℶ", // bfr;[𝔟]. "\x02r;\x04𝔟", // bigtriangledown;[▽] bigtriangleup;[△] bigotimes;[⨂] bigoplus;[⨁] bigsqcup;[⨆] biguplus;[⨄] bigwedge;[⋀] bigcirc;[◯] bigodot;[⨀] bigstar;[★] bigcap;[⋂] bigcup;[⋃] bigvee;[⋁]. "\x0egtriangledown;\x03▽\x0cgtriangleup;\x03△\x08gotimes;\x03⨂\x07goplus;\x03⨁\x07gsqcup;\x03⨆\x07guplus;\x03⨄\x07gwedge;\x03⋀\x06gcirc;\x03◯\x06godot;\x03⨀\x06gstar;\x03★\x05gcap;\x03⋂\x05gcup;\x03⋃\x05gvee;\x03⋁", // bkarow;[⤍]. "\x05arow;\x03⤍", // blacktriangleright;[▸] blacktriangledown;[▾] blacktriangleleft;[◂] blacktriangle;[▴] blacklozenge;[⧫] blacksquare;[▪] blank;[␣] blk12;[▒] blk14;[░] blk34;[▓] block;[█]. "\x11acktriangleright;\x03▸\x10acktriangledown;\x03▾\x10acktriangleleft;\x03◂\x0cacktriangle;\x03▴\x0backlozenge;\x03⧫\x0aacksquare;\x03▪\x04ank;\x03␣\x04k12;\x03▒\x04k14;\x03░\x04k34;\x03▓\x04ock;\x03█", // bnequiv;[≡⃥] bnot;[⌐] bne;[=⃥]. "\x06equiv;\x06≡⃥\x03ot;\x03⌐\x02e;\x04=⃥", // boxminus;[⊟] boxtimes;[⊠] boxplus;[⊞] bottom;[⊥] bowtie;[⋈] boxbox;[⧉] boxDL;[╗] boxDR;[╔] boxDl;[╖] boxDr;[╓] boxHD;[╦] boxHU;[╩] boxHd;[╤] boxHu;[╧] boxUL;[╝] boxUR;[╚] boxUl;[╜] boxUr;[╙] boxVH;[╬] boxVL;[╣] boxVR;[╠] boxVh;[╫] boxVl;[╢] boxVr;[╟] boxdL;[╕] boxdR;[╒] boxdl;[┐] boxdr;[┌] boxhD;[╥] boxhU;[╨] boxhd;[┬] boxhu;[┴] boxuL;[╛] boxuR;[╘] boxul;[┘] boxur;[└] boxvH;[╪] boxvL;[╡] boxvR;[╞] boxvh;[┼] boxvl;[┤] boxvr;[├] bopf;[𝕓] boxH;[═] boxV;[║] boxh;[─] boxv;[│] bot;[⊥]. "\x07xminus;\x03⊟\x07xtimes;\x03⊠\x06xplus;\x03⊞\x05ttom;\x03⊥\x05wtie;\x03⋈\x05xbox;\x03⧉\x04xDL;\x03╗\x04xDR;\x03╔\x04xDl;\x03╖\x04xDr;\x03╓\x04xHD;\x03╦\x04xHU;\x03╩\x04xHd;\x03╤\x04xHu;\x03╧\x04xUL;\x03╝\x04xUR;\x03╚\x04xUl;\x03╜\x04xUr;\x03╙\x04xVH;\x03╬\x04xVL;\x03╣\x04xVR;\x03╠\x04xVh;\x03╫\x04xVl;\x03╢\x04xVr;\x03╟\x04xdL;\x03╕\x04xdR;\x03╒\x04xdl;\x03┐\x04xdr;\x03┌\x04xhD;\x03╥\x04xhU;\x03╨\x04xhd;\x03┬\x04xhu;\x03┴\x04xuL;\x03╛\x04xuR;\x03╘\x04xul;\x03┘\x04xur;\x03└\x04xvH;\x03╪\x04xvL;\x03╡\x04xvR;\x03╞\x04xvh;\x03┼\x04xvl;\x03┤\x04xvr;\x03├\x03pf;\x04𝕓\x03xH;\x03═\x03xV;\x03║\x03xh;\x03─\x03xv;\x03│\x02t;\x03⊥", // bprime;[‵]. "\x05rime;\x03‵", // brvbar;[¦] breve;[˘] brvbar[¦]. "\x05vbar;\x02¦\x04eve;\x02˘\x04vbar\x02¦", // bsolhsub;[⟈] bsemi;[⁏] bsime;[⋍] bsolb;[⧅] bscr;[𝒷] bsim;[∽] bsol;[\\]. "\x07olhsub;\x03⟈\x04emi;\x03⁏\x04ime;\x03⋍\x04olb;\x03⧅\x03cr;\x04𝒷\x03im;\x03∽\x03ol;\x01\\", // bullet;[•] bumpeq;[≏] bumpE;[⪮] bumpe;[≏] bull;[•] bump;[≎]. "\x05llet;\x03•\x05mpeq;\x03≏\x04mpE;\x03⪮\x04mpe;\x03≏\x03ll;\x03•\x03mp;\x03≎", // capbrcup;[⩉] cacute;[ć] capand;[⩄] capcap;[⩋] capcup;[⩇] capdot;[⩀] caret;[⁁] caron;[ˇ] caps;[∩︀] cap;[∩]. "\x07pbrcup;\x03⩉\x05cute;\x02ć\x05pand;\x03⩄\x05pcap;\x03⩋\x05pcup;\x03⩇\x05pdot;\x03⩀\x04ret;\x03⁁\x04ron;\x02ˇ\x03ps;\x06∩︀\x02p;\x03∩", // ccupssm;[⩐] ccaron;[č] ccedil;[ç] ccaps;[⩍] ccedil[ç] ccirc;[ĉ] ccups;[⩌]. "\x06upssm;\x03⩐\x05aron;\x02č\x05edil;\x02ç\x04aps;\x03⩍\x04edil\x02ç\x04irc;\x02ĉ\x04ups;\x03⩌", // cdot;[ċ]. "\x03ot;\x02ċ", // centerdot;[·] cemptyv;[⦲] cedil;[¸] cedil[¸] cent;[¢] cent[¢]. "\x08nterdot;\x02·\x06mptyv;\x03⦲\x04dil;\x02¸\x03dil\x02¸\x03nt;\x02¢\x02nt\x02¢", // cfr;[𝔠]. "\x02r;\x04𝔠", // checkmark;[✓] check;[✓] chcy;[ч] chi;[χ]. "\x08eckmark;\x03✓\x04eck;\x03✓\x03cy;\x02ч\x02i;\x02χ", // circlearrowright;[↻] circlearrowleft;[↺] circledcirc;[⊚] circleddash;[⊝] circledast;[⊛] circledR;[®] circledS;[Ⓢ] cirfnint;[⨐] cirscir;[⧂] circeq;[≗] cirmid;[⫯] cirE;[⧃] circ;[ˆ] cire;[≗] cir;[○]. "\x0frclearrowright;\x03↻\x0erclearrowleft;\x03↺\x0arcledcirc;\x03⊚\x0arcleddash;\x03⊝\x09rcledast;\x03⊛\x07rcledR;\x02®\x07rcledS;\x03Ⓢ\x07rfnint;\x03⨐\x06rscir;\x03⧂\x05rceq;\x03≗\x05rmid;\x03⫯\x03rE;\x03⧃\x03rc;\x02ˆ\x03re;\x03≗\x02r;\x03○", // clubsuit;[♣] clubs;[♣]. "\x07ubsuit;\x03♣\x04ubs;\x03♣", // complement;[∁] complexes;[ℂ] coloneq;[≔] congdot;[⩭] colone;[≔] commat;[@] compfn;[∘] conint;[∮] coprod;[∐] copysr;[℗] colon;[:] comma;[,] comp;[∁] cong;[≅] copf;[𝕔] copy;[©] copy[©]. "\x09mplement;\x03∁\x08mplexes;\x03ℂ\x06loneq;\x03≔\x06ngdot;\x03⩭\x05lone;\x03≔\x05mmat;\x01@\x05mpfn;\x03∘\x05nint;\x03∮\x05prod;\x03∐\x05pysr;\x03℗\x04lon;\x01:\x04mma;\x01,\x03mp;\x03∁\x03ng;\x03≅\x03pf;\x04𝕔\x03py;\x02©\x02py\x02©", // crarr;[↵] cross;[✗]. "\x04arr;\x03↵\x04oss;\x03✗", // csube;[⫑] csupe;[⫒] cscr;[𝒸] csub;[⫏] csup;[⫐]. "\x04ube;\x03⫑\x04upe;\x03⫒\x03cr;\x04𝒸\x03ub;\x03⫏\x03up;\x03⫐", // ctdot;[⋯]. "\x04dot;\x03⋯", // curvearrowright;[↷] curvearrowleft;[↶] curlyeqprec;[⋞] curlyeqsucc;[⋟] curlywedge;[⋏] cupbrcap;[⩈] curlyvee;[⋎] cudarrl;[⤸] cudarrr;[⤵] cularrp;[⤽] curarrm;[⤼] cularr;[↶] cupcap;[⩆] cupcup;[⩊] cupdot;[⊍] curarr;[↷] curren;[¤] cuepr;[⋞] cuesc;[⋟] cupor;[⩅] curren[¤] cuvee;[⋎] cuwed;[⋏] cups;[∪︀] cup;[∪]. "\x0ervearrowright;\x03↷\x0drvearrowleft;\x03↶\x0arlyeqprec;\x03⋞\x0arlyeqsucc;\x03⋟\x09rlywedge;\x03⋏\x07pbrcap;\x03⩈\x07rlyvee;\x03⋎\x06darrl;\x03⤸\x06darrr;\x03⤵\x06larrp;\x03⤽\x06rarrm;\x03⤼\x05larr;\x03↶\x05pcap;\x03⩆\x05pcup;\x03⩊\x05pdot;\x03⊍\x05rarr;\x03↷\x05rren;\x02¤\x04epr;\x03⋞\x04esc;\x03⋟\x04por;\x03⩅\x04rren\x02¤\x04vee;\x03⋎\x04wed;\x03⋏\x03ps;\x06∪︀\x02p;\x03∪", // cwconint;[∲] cwint;[∱]. "\x07conint;\x03∲\x04int;\x03∱", // cylcty;[⌭]. "\x05lcty;\x03⌭", // dArr;[⇓]. "\x03rr;\x03⇓", // dHar;[⥥]. "\x03ar;\x03⥥", // dagger;[†] daleth;[ℸ] dashv;[⊣] darr;[↓] dash;[‐]. "\x05gger;\x03†\x05leth;\x03ℸ\x04shv;\x03⊣\x03rr;\x03↓\x03sh;\x03‐", // dbkarow;[⤏] dblac;[˝]. "\x06karow;\x03⤏\x04lac;\x02˝", // dcaron;[ď] dcy;[д]. "\x05aron;\x02ď\x02y;\x02д", // ddagger;[‡] ddotseq;[⩷] ddarr;[⇊] dd;[ⅆ]. "\x06agger;\x03‡\x06otseq;\x03⩷\x04arr;\x03⇊\x01;\x03ⅆ", // demptyv;[⦱] delta;[δ] deg;[°] deg[°]. "\x06mptyv;\x03⦱\x04lta;\x02δ\x02g;\x02°\x01g\x02°", // dfisht;[⥿] dfr;[𝔡]. "\x05isht;\x03⥿\x02r;\x04𝔡", // dharl;[⇃] dharr;[⇂]. "\x04arl;\x03⇃\x04arr;\x03⇂", // divideontimes;[⋇] diamondsuit;[♦] diamond;[⋄] digamma;[ϝ] divide;[÷] divonx;[⋇] diams;[♦] disin;[⋲] divide[÷] diam;[⋄] die;[¨] div;[÷]. "\x0cvideontimes;\x03⋇\x0aamondsuit;\x03♦\x06amond;\x03⋄\x06gamma;\x02ϝ\x05vide;\x02÷\x05vonx;\x03⋇\x04ams;\x03♦\x04sin;\x03⋲\x04vide\x02÷\x03am;\x03⋄\x02e;\x02¨\x02v;\x02÷", // djcy;[ђ]. "\x03cy;\x02ђ", // dlcorn;[⌞] dlcrop;[⌍]. "\x05corn;\x03⌞\x05crop;\x03⌍", // downharpoonright;[⇂] downharpoonleft;[⇃] doublebarwedge;[⌆] downdownarrows;[⇊] dotsquare;[⊡] downarrow;[↓] doteqdot;[≑] dotminus;[∸] dotplus;[∔] dollar;[$] doteq;[≐] dopf;[𝕕] dot;[˙]. "\x0fwnharpoonright;\x03⇂\x0ewnharpoonleft;\x03⇃\x0dublebarwedge;\x03⌆\x0dwndownarrows;\x03⇊\x08tsquare;\x03⊡\x08wnarrow;\x03↓\x07teqdot;\x03≑\x07tminus;\x03∸\x06tplus;\x03∔\x05llar;\x01$\x04teq;\x03≐\x03pf;\x04𝕕\x02t;\x02˙", // drbkarow;[⤐] drcorn;[⌟] drcrop;[⌌]. "\x07bkarow;\x03⤐\x05corn;\x03⌟\x05crop;\x03⌌", // dstrok;[đ] dscr;[𝒹] dscy;[ѕ] dsol;[⧶]. "\x05trok;\x02đ\x03cr;\x04𝒹\x03cy;\x02ѕ\x03ol;\x03⧶", // dtdot;[⋱] dtrif;[▾] dtri;[▿]. "\x04dot;\x03⋱\x04rif;\x03▾\x03ri;\x03▿", // duarr;[⇵] duhar;[⥯]. "\x04arr;\x03⇵\x04har;\x03⥯", // dwangle;[⦦]. "\x06angle;\x03⦦", // dzigrarr;[⟿] dzcy;[џ]. "\x07igrarr;\x03⟿\x03cy;\x02џ", // eDDot;[⩷] eDot;[≑]. "\x04Dot;\x03⩷\x03ot;\x03≑", // eacute;[é] easter;[⩮] eacute[é]. "\x05cute;\x02é\x05ster;\x03⩮\x04cute\x02é", // ecaron;[ě] ecolon;[≕] ecirc;[ê] ecir;[≖] ecirc[ê] ecy;[э]. "\x05aron;\x02ě\x05olon;\x03≕\x04irc;\x02ê\x03ir;\x03≖\x03irc\x02ê\x02y;\x02э", // edot;[ė]. "\x03ot;\x02ė", // ee;[ⅇ]. "\x01;\x03ⅇ", // efDot;[≒] efr;[𝔢]. "\x04Dot;\x03≒\x02r;\x04𝔢", // egrave;[è] egsdot;[⪘] egrave[è] egs;[⪖] eg;[⪚]. "\x05rave;\x02è\x05sdot;\x03⪘\x04rave\x02è\x02s;\x03⪖\x01;\x03⪚", // elinters;[⏧] elsdot;[⪗] ell;[ℓ] els;[⪕] el;[⪙]. "\x07inters;\x03⏧\x05sdot;\x03⪗\x02l;\x03ℓ\x02s;\x03⪕\x01;\x03⪙", // emptyset;[∅] emptyv;[∅] emsp13;[ ] emsp14;[ ] emacr;[ē] empty;[∅] emsp;[ ]. "\x07ptyset;\x03∅\x05ptyv;\x03∅\x05sp13;\x03 \x05sp14;\x03 \x04acr;\x02ē\x04pty;\x03∅\x03sp;\x03 ", // ensp;[ ] eng;[ŋ]. "\x03sp;\x03 \x02g;\x02ŋ", // eogon;[ę] eopf;[𝕖]. "\x04gon;\x02ę\x03pf;\x04𝕖", // epsilon;[ε] eparsl;[⧣] eplus;[⩱] epsiv;[ϵ] epar;[⋕] epsi;[ε]. "\x06silon;\x02ε\x05arsl;\x03⧣\x04lus;\x03⩱\x04siv;\x02ϵ\x03ar;\x03⋕\x03si;\x02ε", // eqslantless;[⪕] eqslantgtr;[⪖] eqvparsl;[⧥] eqcolon;[≕] equivDD;[⩸] eqcirc;[≖] equals;[=] equest;[≟] eqsim;[≂] equiv;[≡]. "\x0aslantless;\x03⪕\x09slantgtr;\x03⪖\x07vparsl;\x03⧥\x06colon;\x03≕\x06uivDD;\x03⩸\x05circ;\x03≖\x05uals;\x01=\x05uest;\x03≟\x04sim;\x03≂\x04uiv;\x03≡", // erDot;[≓] erarr;[⥱]. "\x04Dot;\x03≓\x04arr;\x03⥱", // esdot;[≐] escr;[ℯ] esim;[≂]. "\x04dot;\x03≐\x03cr;\x03ℯ\x03im;\x03≂", // eta;[η] eth;[ð] eth[ð]. "\x02a;\x02η\x02h;\x02ð\x01h\x02ð", // euml;[ë] euro;[€] euml[ë]. "\x03ml;\x02ë\x03ro;\x03€\x02ml\x02ë", // exponentiale;[ⅇ] expectation;[ℰ] exist;[∃] excl;[!]. "\x0bponentiale;\x03ⅇ\x0apectation;\x03ℰ\x04ist;\x03∃\x03cl;\x01!", // fallingdotseq;[≒]. "\x0cllingdotseq;\x03≒", // fcy;[ф]. "\x02y;\x02ф", // female;[♀]. "\x05male;\x03♀", // ffilig;[ffi] ffllig;[ffl] fflig;[ff] ffr;[𝔣]. "\x05ilig;\x03ffi\x05llig;\x03ffl\x04lig;\x03ff\x02r;\x04𝔣", // filig;[fi]. "\x04lig;\x03fi", // fjlig;[fj]. "\x04lig;\x02fj", // fllig;[fl] fltns;[▱] flat;[♭]. "\x04lig;\x03fl\x04tns;\x03▱\x03at;\x03♭", // fnof;[ƒ]. "\x03of;\x02ƒ", // forall;[∀] forkv;[⫙] fopf;[𝕗] fork;[⋔]. "\x05rall;\x03∀\x04rkv;\x03⫙\x03pf;\x04𝕗\x03rk;\x03⋔", // fpartint;[⨍]. "\x07artint;\x03⨍", // frac12;[½] frac13;[⅓] frac14;[¼] frac15;[⅕] frac16;[⅙] frac18;[⅛] frac23;[⅔] frac25;[⅖] frac34;[¾] frac35;[⅗] frac38;[⅜] frac45;[⅘] frac56;[⅚] frac58;[⅝] frac78;[⅞] frac12[½] frac14[¼] frac34[¾] frasl;[⁄] frown;[⌢]. "\x05ac12;\x02½\x05ac13;\x03⅓\x05ac14;\x02¼\x05ac15;\x03⅕\x05ac16;\x03⅙\x05ac18;\x03⅛\x05ac23;\x03⅔\x05ac25;\x03⅖\x05ac34;\x02¾\x05ac35;\x03⅗\x05ac38;\x03⅜\x05ac45;\x03⅘\x05ac56;\x03⅚\x05ac58;\x03⅝\x05ac78;\x03⅞\x04ac12\x02½\x04ac14\x02¼\x04ac34\x02¾\x04asl;\x03⁄\x04own;\x03⌢", // fscr;[𝒻]. "\x03cr;\x04𝒻", // gEl;[⪌] gE;[≧]. "\x02l;\x03⪌\x01;\x03≧", // gacute;[ǵ] gammad;[ϝ] gamma;[γ] gap;[⪆]. "\x05cute;\x02ǵ\x05mmad;\x02ϝ\x04mma;\x02γ\x02p;\x03⪆", // gbreve;[ğ]. "\x05reve;\x02ğ", // gcirc;[ĝ] gcy;[г]. "\x04irc;\x02ĝ\x02y;\x02г", // gdot;[ġ]. "\x03ot;\x02ġ", // geqslant;[⩾] gesdotol;[⪄] gesdoto;[⪂] gesdot;[⪀] gesles;[⪔] gescc;[⪩] geqq;[≧] gesl;[⋛︀] gel;[⋛] geq;[≥] ges;[⩾] ge;[≥]. "\x07qslant;\x03⩾\x07sdotol;\x03⪄\x06sdoto;\x03⪂\x05sdot;\x03⪀\x05sles;\x03⪔\x04scc;\x03⪩\x03qq;\x03≧\x03sl;\x06⋛︀\x02l;\x03⋛\x02q;\x03≥\x02s;\x03⩾\x01;\x03≥", // gfr;[𝔤]. "\x02r;\x04𝔤", // ggg;[⋙] gg;[≫]. "\x02g;\x03⋙\x01;\x03≫", // gimel;[ℷ]. "\x04mel;\x03ℷ", // gjcy;[ѓ]. "\x03cy;\x02ѓ", // glE;[⪒] gla;[⪥] glj;[⪤] gl;[≷]. "\x02E;\x03⪒\x02a;\x03⪥\x02j;\x03⪤\x01;\x03≷", // gnapprox;[⪊] gneqq;[≩] gnsim;[⋧] gnap;[⪊] gneq;[⪈] gnE;[≩] gne;[⪈]. "\x07approx;\x03⪊\x04eqq;\x03≩\x04sim;\x03⋧\x03ap;\x03⪊\x03eq;\x03⪈\x02E;\x03≩\x02e;\x03⪈", // gopf;[𝕘]. "\x03pf;\x04𝕘", // grave;[`]. "\x04ave;\x01`", // gsime;[⪎] gsiml;[⪐] gscr;[ℊ] gsim;[≳]. "\x04ime;\x03⪎\x04iml;\x03⪐\x03cr;\x03ℊ\x03im;\x03≳", // gtreqqless;[⪌] gtrapprox;[⪆] gtreqless;[⋛] gtquest;[⩼] gtrless;[≷] gtlPar;[⦕] gtrarr;[⥸] gtrdot;[⋗] gtrsim;[≳] gtcir;[⩺] gtdot;[⋗] gtcc;[⪧] gt;[>]. "\x09reqqless;\x03⪌\x08rapprox;\x03⪆\x08reqless;\x03⋛\x06quest;\x03⩼\x06rless;\x03≷\x05lPar;\x03⦕\x05rarr;\x03⥸\x05rdot;\x03⋗\x05rsim;\x03≳\x04cir;\x03⩺\x04dot;\x03⋗\x03cc;\x03⪧\x01;\x01>", // gvertneqq;[≩︀] gvnE;[≩︀]. "\x08ertneqq;\x06≩︀\x03nE;\x06≩︀", // hArr;[⇔]. "\x03rr;\x03⇔", // harrcir;[⥈] hairsp;[ ] hamilt;[ℋ] hardcy;[ъ] harrw;[↭] half;[½] harr;[↔]. "\x06rrcir;\x03⥈\x05irsp;\x03 \x05milt;\x03ℋ\x05rdcy;\x02ъ\x04rrw;\x03↭\x03lf;\x02½\x03rr;\x03↔", // hbar;[ℏ]. "\x03ar;\x03ℏ", // hcirc;[ĥ]. "\x04irc;\x02ĥ", // heartsuit;[♥] hearts;[♥] hellip;[…] hercon;[⊹]. "\x08artsuit;\x03♥\x05arts;\x03♥\x05llip;\x03…\x05rcon;\x03⊹", // hfr;[𝔥]. "\x02r;\x04𝔥", // hksearow;[⤥] hkswarow;[⤦]. "\x07searow;\x03⤥\x07swarow;\x03⤦", // hookrightarrow;[↪] hookleftarrow;[↩] homtht;[∻] horbar;[―] hoarr;[⇿] hopf;[𝕙]. "\x0dokrightarrow;\x03↪\x0cokleftarrow;\x03↩\x05mtht;\x03∻\x05rbar;\x03―\x04arr;\x03⇿\x03pf;\x04𝕙", // hslash;[ℏ] hstrok;[ħ] hscr;[𝒽]. "\x05lash;\x03ℏ\x05trok;\x02ħ\x03cr;\x04𝒽", // hybull;[⁃] hyphen;[‐]. "\x05bull;\x03⁃\x05phen;\x03‐", // iacute;[í] iacute[í]. "\x05cute;\x02í\x04cute\x02í", // icirc;[î] icirc[î] icy;[и] ic;[]. "\x04irc;\x02î\x03irc\x02î\x02y;\x02и\x01;\x03", // iexcl;[¡] iecy;[е] iexcl[¡]. "\x04xcl;\x02¡\x03cy;\x02е\x03xcl\x02¡", // iff;[⇔] ifr;[𝔦]. "\x02f;\x03⇔\x02r;\x04𝔦", // igrave;[ì] igrave[ì]. "\x05rave;\x02ì\x04rave\x02ì", // iiiint;[⨌] iinfin;[⧜] iiint;[∭] iiota;[℩] ii;[ⅈ]. "\x05iint;\x03⨌\x05nfin;\x03⧜\x04int;\x03∭\x04ota;\x03℩\x01;\x03ⅈ", // ijlig;[ij]. "\x04lig;\x02ij", // imagline;[ℐ] imagpart;[ℑ] imacr;[ī] image;[ℑ] imath;[ı] imped;[Ƶ] imof;[⊷]. "\x07agline;\x03ℐ\x07agpart;\x03ℑ\x04acr;\x02ī\x04age;\x03ℑ\x04ath;\x02ı\x04ped;\x02Ƶ\x03of;\x03⊷", // infintie;[⧝] integers;[ℤ] intercal;[⊺] intlarhk;[⨗] intprod;[⨼] incare;[℅] inodot;[ı] intcal;[⊺] infin;[∞] int;[∫] in;[∈]. "\x07fintie;\x03⧝\x07tegers;\x03ℤ\x07tercal;\x03⊺\x07tlarhk;\x03⨗\x06tprod;\x03⨼\x05care;\x03℅\x05odot;\x02ı\x05tcal;\x03⊺\x04fin;\x03∞\x02t;\x03∫\x01;\x03∈", // iogon;[į] iocy;[ё] iopf;[𝕚] iota;[ι]. "\x04gon;\x02į\x03cy;\x02ё\x03pf;\x04𝕚\x03ta;\x02ι", // iprod;[⨼]. "\x04rod;\x03⨼", // iquest;[¿] iquest[¿]. "\x05uest;\x02¿\x04uest\x02¿", // isindot;[⋵] isinsv;[⋳] isinE;[⋹] isins;[⋴] isinv;[∈] iscr;[𝒾] isin;[∈]. "\x06indot;\x03⋵\x05insv;\x03⋳\x04inE;\x03⋹\x04ins;\x03⋴\x04inv;\x03∈\x03cr;\x04𝒾\x03in;\x03∈", // itilde;[ĩ] it;[]. "\x05ilde;\x02ĩ\x01;\x03", // iukcy;[і] iuml;[ï] iuml[ï]. "\x04kcy;\x02і\x03ml;\x02ï\x02ml\x02ï", // jcirc;[ĵ] jcy;[й]. "\x04irc;\x02ĵ\x02y;\x02й", // jfr;[𝔧]. "\x02r;\x04𝔧", // jmath;[ȷ]. "\x04ath;\x02ȷ", // jopf;[𝕛]. "\x03pf;\x04𝕛", // jsercy;[ј] jscr;[𝒿]. "\x05ercy;\x02ј\x03cr;\x04𝒿", // jukcy;[є]. "\x04kcy;\x02є", // kappav;[ϰ] kappa;[κ]. "\x05ppav;\x02ϰ\x04ppa;\x02κ", // kcedil;[ķ] kcy;[к]. "\x05edil;\x02ķ\x02y;\x02к", // kfr;[𝔨]. "\x02r;\x04𝔨", // kgreen;[ĸ]. "\x05reen;\x02ĸ", // khcy;[х]. "\x03cy;\x02х", // kjcy;[ќ]. "\x03cy;\x02ќ", // kopf;[𝕜]. "\x03pf;\x04𝕜", // kscr;[𝓀]. "\x03cr;\x04𝓀", // lAtail;[⤛] lAarr;[⇚] lArr;[⇐]. "\x05tail;\x03⤛\x04arr;\x03⇚\x03rr;\x03⇐", // lBarr;[⤎]. "\x04arr;\x03⤎", // lEg;[⪋] lE;[≦]. "\x02g;\x03⪋\x01;\x03≦", // lHar;[⥢]. "\x03ar;\x03⥢", // laemptyv;[⦴] larrbfs;[⤟] larrsim;[⥳] lacute;[ĺ] lagran;[ℒ] lambda;[λ] langle;[⟨] larrfs;[⤝] larrhk;[↩] larrlp;[↫] larrpl;[⤹] larrtl;[↢] latail;[⤙] langd;[⦑] laquo;[«] larrb;[⇤] lates;[⪭︀] lang;[⟨] laquo[«] larr;[←] late;[⪭] lap;[⪅] lat;[⪫]. "\x07emptyv;\x03⦴\x06rrbfs;\x03⤟\x06rrsim;\x03⥳\x05cute;\x02ĺ\x05gran;\x03ℒ\x05mbda;\x02λ\x05ngle;\x03⟨\x05rrfs;\x03⤝\x05rrhk;\x03↩\x05rrlp;\x03↫\x05rrpl;\x03⤹\x05rrtl;\x03↢\x05tail;\x03⤙\x04ngd;\x03⦑\x04quo;\x02«\x04rrb;\x03⇤\x04tes;\x06⪭︀\x03ng;\x03⟨\x03quo\x02«\x03rr;\x03←\x03te;\x03⪭\x02p;\x03⪅\x02t;\x03⪫", // lbrksld;[⦏] lbrkslu;[⦍] lbrace;[{] lbrack;[[] lbarr;[⤌] lbbrk;[❲] lbrke;[⦋]. "\x06rksld;\x03⦏\x06rkslu;\x03⦍\x05race;\x01{\x05rack;\x01[\x04arr;\x03⤌\x04brk;\x03❲\x04rke;\x03⦋", // lcaron;[ľ] lcedil;[ļ] lceil;[⌈] lcub;[{] lcy;[л]. "\x05aron;\x02ľ\x05edil;\x02ļ\x04eil;\x03⌈\x03ub;\x01{\x02y;\x02л", // ldrushar;[⥋] ldrdhar;[⥧] ldquor;[„] ldquo;[“] ldca;[⤶] ldsh;[↲]. "\x07rushar;\x03⥋\x06rdhar;\x03⥧\x05quor;\x03„\x04quo;\x03“\x03ca;\x03⤶\x03sh;\x03↲", // leftrightsquigarrow;[↭] leftrightharpoons;[⇋] leftharpoondown;[↽] leftrightarrows;[⇆] leftleftarrows;[⇇] leftrightarrow;[↔] leftthreetimes;[⋋] leftarrowtail;[↢] leftharpoonup;[↼] lessapprox;[⪅] lesseqqgtr;[⪋] leftarrow;[←] lesseqgtr;[⋚] leqslant;[⩽] lesdotor;[⪃] lesdoto;[⪁] lessdot;[⋖] lessgtr;[≶] lesssim;[≲] lesdot;[⩿] lesges;[⪓] lescc;[⪨] leqq;[≦] lesg;[⋚︀] leg;[⋚] leq;[≤] les;[⩽] le;[≤]. "\x12ftrightsquigarrow;\x03↭\x10ftrightharpoons;\x03⇋\x0eftharpoondown;\x03↽\x0eftrightarrows;\x03⇆\x0dftleftarrows;\x03⇇\x0dftrightarrow;\x03↔\x0dftthreetimes;\x03⋋\x0cftarrowtail;\x03↢\x0cftharpoonup;\x03↼\x09ssapprox;\x03⪅\x09sseqqgtr;\x03⪋\x08ftarrow;\x03←\x08sseqgtr;\x03⋚\x07qslant;\x03⩽\x07sdotor;\x03⪃\x06sdoto;\x03⪁\x06ssdot;\x03⋖\x06ssgtr;\x03≶\x06sssim;\x03≲\x05sdot;\x03⩿\x05sges;\x03⪓\x04scc;\x03⪨\x03qq;\x03≦\x03sg;\x06⋚︀\x02g;\x03⋚\x02q;\x03≤\x02s;\x03⩽\x01;\x03≤", // lfisht;[⥼] lfloor;[⌊] lfr;[𝔩]. "\x05isht;\x03⥼\x05loor;\x03⌊\x02r;\x04𝔩", // lgE;[⪑] lg;[≶]. "\x02E;\x03⪑\x01;\x03≶", // lharul;[⥪] lhard;[↽] lharu;[↼] lhblk;[▄]. "\x05arul;\x03⥪\x04ard;\x03↽\x04aru;\x03↼\x04blk;\x03▄", // ljcy;[љ]. "\x03cy;\x02љ", // llcorner;[⌞] llhard;[⥫] llarr;[⇇] lltri;[◺] ll;[≪]. "\x07corner;\x03⌞\x05hard;\x03⥫\x04arr;\x03⇇\x04tri;\x03◺\x01;\x03≪", // lmoustache;[⎰] lmidot;[ŀ] lmoust;[⎰]. "\x09oustache;\x03⎰\x05idot;\x02ŀ\x05oust;\x03⎰", // lnapprox;[⪉] lneqq;[≨] lnsim;[⋦] lnap;[⪉] lneq;[⪇] lnE;[≨] lne;[⪇]. "\x07approx;\x03⪉\x04eqq;\x03≨\x04sim;\x03⋦\x03ap;\x03⪉\x03eq;\x03⪇\x02E;\x03≨\x02e;\x03⪇", // longleftrightarrow;[⟷] longrightarrow;[⟶] looparrowright;[↬] longleftarrow;[⟵] looparrowleft;[↫] longmapsto;[⟼] lotimes;[⨴] lozenge;[◊] loplus;[⨭] lowast;[∗] lowbar;[_] loang;[⟬] loarr;[⇽] lobrk;[⟦] lopar;[⦅] lopf;[𝕝] lozf;[⧫] loz;[◊]. "\x11ngleftrightarrow;\x03⟷\x0dngrightarrow;\x03⟶\x0doparrowright;\x03↬\x0cngleftarrow;\x03⟵\x0coparrowleft;\x03↫\x09ngmapsto;\x03⟼\x06times;\x03⨴\x06zenge;\x03◊\x05plus;\x03⨭\x05wast;\x03∗\x05wbar;\x01_\x04ang;\x03⟬\x04arr;\x03⇽\x04brk;\x03⟦\x04par;\x03⦅\x03pf;\x04𝕝\x03zf;\x03⧫\x02z;\x03◊", // lparlt;[⦓] lpar;[(]. "\x05arlt;\x03⦓\x03ar;\x01(", // lrcorner;[⌟] lrhard;[⥭] lrarr;[⇆] lrhar;[⇋] lrtri;[⊿] lrm;[]. "\x07corner;\x03⌟\x05hard;\x03⥭\x04arr;\x03⇆\x04har;\x03⇋\x04tri;\x03⊿\x02m;\x03", // lsaquo;[‹] lsquor;[‚] lstrok;[ł] lsime;[⪍] lsimg;[⪏] lsquo;[‘] lscr;[𝓁] lsim;[≲] lsqb;[[] lsh;[↰]. "\x05aquo;\x03‹\x05quor;\x03‚\x05trok;\x02ł\x04ime;\x03⪍\x04img;\x03⪏\x04quo;\x03‘\x03cr;\x04𝓁\x03im;\x03≲\x03qb;\x01[\x02h;\x03↰", // ltquest;[⩻] lthree;[⋋] ltimes;[⋉] ltlarr;[⥶] ltrPar;[⦖] ltcir;[⩹] ltdot;[⋖] ltrie;[⊴] ltrif;[◂] ltcc;[⪦] ltri;[◃] lt;[<]. "\x06quest;\x03⩻\x05hree;\x03⋋\x05imes;\x03⋉\x05larr;\x03⥶\x05rPar;\x03⦖\x04cir;\x03⩹\x04dot;\x03⋖\x04rie;\x03⊴\x04rif;\x03◂\x03cc;\x03⪦\x03ri;\x03◃\x01;\x01<", // lurdshar;[⥊] luruhar;[⥦]. "\x07rdshar;\x03⥊\x06ruhar;\x03⥦", // lvertneqq;[≨︀] lvnE;[≨︀]. "\x08ertneqq;\x06≨︀\x03nE;\x06≨︀", // mDDot;[∺]. "\x04Dot;\x03∺", // mapstodown;[↧] mapstoleft;[↤] mapstoup;[↥] maltese;[✠] mapsto;[↦] marker;[▮] macr;[¯] male;[♂] malt;[✠] macr[¯] map;[↦]. "\x09pstodown;\x03↧\x09pstoleft;\x03↤\x07pstoup;\x03↥\x06ltese;\x03✠\x05psto;\x03↦\x05rker;\x03▮\x03cr;\x02¯\x03le;\x03♂\x03lt;\x03✠\x02cr\x02¯\x02p;\x03↦", // mcomma;[⨩] mcy;[м]. "\x05omma;\x03⨩\x02y;\x02м", // mdash;[—]. "\x04ash;\x03—", // measuredangle;[∡]. "\x0casuredangle;\x03∡", // mfr;[𝔪]. "\x02r;\x04𝔪", // mho;[℧]. "\x02o;\x03℧", // minusdu;[⨪] midast;[*] midcir;[⫰] middot;[·] minusb;[⊟] minusd;[∸] micro;[µ] middot[·] minus;[−] micro[µ] mid;[∣]. "\x06nusdu;\x03⨪\x05dast;\x01*\x05dcir;\x03⫰\x05ddot;\x02·\x05nusb;\x03⊟\x05nusd;\x03∸\x04cro;\x02µ\x04ddot\x02·\x04nus;\x03−\x03cro\x02µ\x02d;\x03∣", // mlcp;[⫛] mldr;[…]. "\x03cp;\x03⫛\x03dr;\x03…", // mnplus;[∓]. "\x05plus;\x03∓", // models;[⊧] mopf;[𝕞]. "\x05dels;\x03⊧\x03pf;\x04𝕞", // mp;[∓]. "\x01;\x03∓", // mstpos;[∾] mscr;[𝓂]. "\x05tpos;\x03∾\x03cr;\x04𝓂", // multimap;[⊸] mumap;[⊸] mu;[μ]. "\x07ltimap;\x03⊸\x04map;\x03⊸\x01;\x02μ", // nGtv;[≫̸] nGg;[⋙̸] nGt;[≫⃒]. "\x03tv;\x05≫̸\x02g;\x05⋙̸\x02t;\x06≫⃒", // nLeftrightarrow;[⇎] nLeftarrow;[⇍] nLtv;[≪̸] nLl;[⋘̸] nLt;[≪⃒]. "\x0eeftrightarrow;\x03⇎\x09eftarrow;\x03⇍\x03tv;\x05≪̸\x02l;\x05⋘̸\x02t;\x06≪⃒", // nRightarrow;[⇏]. "\x0aightarrow;\x03⇏", // nVDash;[⊯] nVdash;[⊮]. "\x05Dash;\x03⊯\x05dash;\x03⊮", // naturals;[ℕ] napprox;[≉] natural;[♮] nacute;[ń] nabla;[∇] napid;[≋̸] napos;[ʼn] natur;[♮] nang;[∠⃒] napE;[⩰̸] nap;[≉]. "\x07turals;\x03ℕ\x06pprox;\x03≉\x06tural;\x03♮\x05cute;\x02ń\x04bla;\x03∇\x04pid;\x05≋̸\x04pos;\x02ʼn\x04tur;\x03♮\x03ng;\x06∠⃒\x03pE;\x05⩰̸\x02p;\x03≉", // nbumpe;[≏̸] nbump;[≎̸] nbsp;[ ] nbsp[ ]. "\x05umpe;\x05≏̸\x04ump;\x05≎̸\x03sp;\x02 \x02sp\x02 ", // ncongdot;[⩭̸] ncaron;[ň] ncedil;[ņ] ncong;[≇] ncap;[⩃] ncup;[⩂] ncy;[н]. "\x07ongdot;\x05⩭̸\x05aron;\x02ň\x05edil;\x02ņ\x04ong;\x03≇\x03ap;\x03⩃\x03up;\x03⩂\x02y;\x02н", // ndash;[–]. "\x04ash;\x03–", // nearrow;[↗] nexists;[∄] nearhk;[⤤] nequiv;[≢] nesear;[⤨] nexist;[∄] neArr;[⇗] nearr;[↗] nedot;[≐̸] nesim;[≂̸] ne;[≠]. "\x06arrow;\x03↗\x06xists;\x03∄\x05arhk;\x03⤤\x05quiv;\x03≢\x05sear;\x03⤨\x05xist;\x03∄\x04Arr;\x03⇗\x04arr;\x03↗\x04dot;\x05≐̸\x04sim;\x05≂̸\x01;\x03≠", // nfr;[𝔫]. "\x02r;\x04𝔫", // ngeqslant;[⩾̸] ngeqq;[≧̸] ngsim;[≵] ngeq;[≱] nges;[⩾̸] ngtr;[≯] ngE;[≧̸] nge;[≱] ngt;[≯]. "\x08eqslant;\x05⩾̸\x04eqq;\x05≧̸\x04sim;\x03≵\x03eq;\x03≱\x03es;\x05⩾̸\x03tr;\x03≯\x02E;\x05≧̸\x02e;\x03≱\x02t;\x03≯", // nhArr;[⇎] nharr;[↮] nhpar;[⫲]. "\x04Arr;\x03⇎\x04arr;\x03↮\x04par;\x03⫲", // nisd;[⋺] nis;[⋼] niv;[∋] ni;[∋]. "\x03sd;\x03⋺\x02s;\x03⋼\x02v;\x03∋\x01;\x03∋", // njcy;[њ]. "\x03cy;\x02њ", // nleftrightarrow;[↮] nleftarrow;[↚] nleqslant;[⩽̸] nltrie;[⋬] nlArr;[⇍] nlarr;[↚] nleqq;[≦̸] nless;[≮] nlsim;[≴] nltri;[⋪] nldr;[‥] nleq;[≰] nles;[⩽̸] nlE;[≦̸] nle;[≰] nlt;[≮]. "\x0eeftrightarrow;\x03↮\x09eftarrow;\x03↚\x08eqslant;\x05⩽̸\x05trie;\x03⋬\x04Arr;\x03⇍\x04arr;\x03↚\x04eqq;\x05≦̸\x04ess;\x03≮\x04sim;\x03≴\x04tri;\x03⋪\x03dr;\x03‥\x03eq;\x03≰\x03es;\x05⩽̸\x02E;\x05≦̸\x02e;\x03≰\x02t;\x03≮", // nmid;[∤]. "\x03id;\x03∤", // notindot;[⋵̸] notinva;[∉] notinvb;[⋷] notinvc;[⋶] notniva;[∌] notnivb;[⋾] notnivc;[⋽] notinE;[⋹̸] notin;[∉] notni;[∌] nopf;[𝕟] not;[¬] not[¬]. "\x07tindot;\x05⋵̸\x06tinva;\x03∉\x06tinvb;\x03⋷\x06tinvc;\x03⋶\x06tniva;\x03∌\x06tnivb;\x03⋾\x06tnivc;\x03⋽\x05tinE;\x05⋹̸\x04tin;\x03∉\x04tni;\x03∌\x03pf;\x04𝕟\x02t;\x02¬\x01t\x02¬", // nparallel;[∦] npolint;[⨔] npreceq;[⪯̸] nparsl;[⫽⃥] nprcue;[⋠] npart;[∂̸] nprec;[⊀] npar;[∦] npre;[⪯̸] npr;[⊀]. "\x08arallel;\x03∦\x06olint;\x03⨔\x06receq;\x05⪯̸\x05arsl;\x06⫽⃥\x05rcue;\x03⋠\x04art;\x05∂̸\x04rec;\x03⊀\x03ar;\x03∦\x03re;\x05⪯̸\x02r;\x03⊀", // nrightarrow;[↛] nrarrc;[⤳̸] nrarrw;[↝̸] nrtrie;[⋭] nrArr;[⇏] nrarr;[↛] nrtri;[⋫]. "\x0aightarrow;\x03↛\x05arrc;\x05⤳̸\x05arrw;\x05↝̸\x05trie;\x03⋭\x04Arr;\x03⇏\x04arr;\x03↛\x04tri;\x03⋫", // nshortparallel;[∦] nsubseteqq;[⫅̸] nsupseteqq;[⫆̸] nshortmid;[∤] nsubseteq;[⊈] nsupseteq;[⊉] nsqsube;[⋢] nsqsupe;[⋣] nsubset;[⊂⃒] nsucceq;[⪰̸] nsupset;[⊃⃒] nsccue;[⋡] nsimeq;[≄] nsime;[≄] nsmid;[∤] nspar;[∦] nsubE;[⫅̸] nsube;[⊈] nsucc;[⊁] nsupE;[⫆̸] nsupe;[⊉] nsce;[⪰̸] nscr;[𝓃] nsim;[≁] nsub;[⊄] nsup;[⊅] nsc;[⊁]. "\x0dhortparallel;\x03∦\x09ubseteqq;\x05⫅̸\x09upseteqq;\x05⫆̸\x08hortmid;\x03∤\x08ubseteq;\x03⊈\x08upseteq;\x03⊉\x06qsube;\x03⋢\x06qsupe;\x03⋣\x06ubset;\x06⊂⃒\x06ucceq;\x05⪰̸\x06upset;\x06⊃⃒\x05ccue;\x03⋡\x05imeq;\x03≄\x04ime;\x03≄\x04mid;\x03∤\x04par;\x03∦\x04ubE;\x05⫅̸\x04ube;\x03⊈\x04ucc;\x03⊁\x04upE;\x05⫆̸\x04upe;\x03⊉\x03ce;\x05⪰̸\x03cr;\x04𝓃\x03im;\x03≁\x03ub;\x03⊄\x03up;\x03⊅\x02c;\x03⊁", // ntrianglerighteq;[⋭] ntrianglelefteq;[⋬] ntriangleright;[⋫] ntriangleleft;[⋪] ntilde;[ñ] ntilde[ñ] ntgl;[≹] ntlg;[≸]. "\x0frianglerighteq;\x03⋭\x0erianglelefteq;\x03⋬\x0driangleright;\x03⋫\x0criangleleft;\x03⋪\x05ilde;\x02ñ\x04ilde\x02ñ\x03gl;\x03≹\x03lg;\x03≸", // numero;[№] numsp;[ ] num;[#] nu;[ν]. "\x05mero;\x03№\x04msp;\x03 \x02m;\x01#\x01;\x02ν", // nvinfin;[⧞] nvltrie;[⊴⃒] nvrtrie;[⊵⃒] nvDash;[⊭] nvHarr;[⤄] nvdash;[⊬] nvlArr;[⤂] nvrArr;[⤃] nvsim;[∼⃒] nvap;[≍⃒] nvge;[≥⃒] nvgt;[>⃒] nvle;[≤⃒] nvlt;[<⃒]. "\x06infin;\x03⧞\x06ltrie;\x06⊴⃒\x06rtrie;\x06⊵⃒\x05Dash;\x03⊭\x05Harr;\x03⤄\x05dash;\x03⊬\x05lArr;\x03⤂\x05rArr;\x03⤃\x04sim;\x06∼⃒\x03ap;\x06≍⃒\x03ge;\x06≥⃒\x03gt;\x04>⃒\x03le;\x06≤⃒\x03lt;\x04<⃒", // nwarrow;[↖] nwarhk;[⤣] nwnear;[⤧] nwArr;[⇖] nwarr;[↖]. "\x06arrow;\x03↖\x05arhk;\x03⤣\x05near;\x03⤧\x04Arr;\x03⇖\x04arr;\x03↖", // oS;[Ⓢ]. "\x01;\x03Ⓢ", // oacute;[ó] oacute[ó] oast;[⊛]. "\x05cute;\x02ó\x04cute\x02ó\x03st;\x03⊛", // ocirc;[ô] ocir;[⊚] ocirc[ô] ocy;[о]. "\x04irc;\x02ô\x03ir;\x03⊚\x03irc\x02ô\x02y;\x02о", // odblac;[ő] odsold;[⦼] odash;[⊝] odiv;[⨸] odot;[⊙]. "\x05blac;\x02ő\x05sold;\x03⦼\x04ash;\x03⊝\x03iv;\x03⨸\x03ot;\x03⊙", // oelig;[œ]. "\x04lig;\x02œ", // ofcir;[⦿] ofr;[𝔬]. "\x04cir;\x03⦿\x02r;\x04𝔬", // ograve;[ò] ograve[ò] ogon;[˛] ogt;[⧁]. "\x05rave;\x02ò\x04rave\x02ò\x03on;\x02˛\x02t;\x03⧁", // ohbar;[⦵] ohm;[Ω]. "\x04bar;\x03⦵\x02m;\x02Ω", // oint;[∮]. "\x03nt;\x03∮", // olcross;[⦻] olarr;[↺] olcir;[⦾] oline;[‾] olt;[⧀]. "\x06cross;\x03⦻\x04arr;\x03↺\x04cir;\x03⦾\x04ine;\x03‾\x02t;\x03⧀", // omicron;[ο] ominus;[⊖] omacr;[ō] omega;[ω] omid;[⦶]. "\x06icron;\x02ο\x05inus;\x03⊖\x04acr;\x02ō\x04ega;\x02ω\x03id;\x03⦶", // oopf;[𝕠]. "\x03pf;\x04𝕠", // operp;[⦹] oplus;[⊕] opar;[⦷]. "\x04erp;\x03⦹\x04lus;\x03⊕\x03ar;\x03⦷", // orderof;[ℴ] orslope;[⩗] origof;[⊶] orarr;[↻] order;[ℴ] ordf;[ª] ordm;[º] oror;[⩖] ord;[⩝] ordf[ª] ordm[º] orv;[⩛] or;[∨]. "\x06derof;\x03ℴ\x06slope;\x03⩗\x05igof;\x03⊶\x04arr;\x03↻\x04der;\x03ℴ\x03df;\x02ª\x03dm;\x02º\x03or;\x03⩖\x02d;\x03⩝\x02df\x02ª\x02dm\x02º\x02v;\x03⩛\x01;\x03∨", // oslash;[ø] oslash[ø] oscr;[ℴ] osol;[⊘]. "\x05lash;\x02ø\x04lash\x02ø\x03cr;\x03ℴ\x03ol;\x03⊘", // otimesas;[⨶] otilde;[õ] otimes;[⊗] otilde[õ]. "\x07imesas;\x03⨶\x05ilde;\x02õ\x05imes;\x03⊗\x04ilde\x02õ", // ouml;[ö] ouml[ö]. "\x03ml;\x02ö\x02ml\x02ö", // ovbar;[⌽]. "\x04bar;\x03⌽", // parallel;[∥] parsim;[⫳] parsl;[⫽] para;[¶] part;[∂] par;[∥] para[¶]. "\x07rallel;\x03∥\x05rsim;\x03⫳\x04rsl;\x03⫽\x03ra;\x02¶\x03rt;\x03∂\x02r;\x03∥\x02ra\x02¶", // pcy;[п]. "\x02y;\x02п", // pertenk;[‱] percnt;[%] period;[.] permil;[‰] perp;[⊥]. "\x06rtenk;\x03‱\x05rcnt;\x01%\x05riod;\x01.\x05rmil;\x03‰\x03rp;\x03⊥", // pfr;[𝔭]. "\x02r;\x04𝔭", // phmmat;[ℳ] phone;[☎] phiv;[ϕ] phi;[φ]. "\x05mmat;\x03ℳ\x04one;\x03☎\x03iv;\x02ϕ\x02i;\x02φ", // pitchfork;[⋔] piv;[ϖ] pi;[π]. "\x08tchfork;\x03⋔\x02v;\x02ϖ\x01;\x02π", // plusacir;[⨣] planckh;[ℎ] pluscir;[⨢] plussim;[⨦] plustwo;[⨧] planck;[ℏ] plankv;[ℏ] plusdo;[∔] plusdu;[⨥] plusmn;[±] plusb;[⊞] pluse;[⩲] plusmn[±] plus;[+]. "\x07usacir;\x03⨣\x06anckh;\x03ℎ\x06uscir;\x03⨢\x06ussim;\x03⨦\x06ustwo;\x03⨧\x05anck;\x03ℏ\x05ankv;\x03ℏ\x05usdo;\x03∔\x05usdu;\x03⨥\x05usmn;\x02±\x04usb;\x03⊞\x04use;\x03⩲\x04usmn\x02±\x03us;\x01+", // pm;[±]. "\x01;\x02±", // pointint;[⨕] pound;[£] popf;[𝕡] pound[£]. "\x07intint;\x03⨕\x04und;\x02£\x03pf;\x04𝕡\x03und\x02£", // preccurlyeq;[≼] precnapprox;[⪹] precapprox;[⪷] precneqq;[⪵] precnsim;[⋨] profalar;[⌮] profline;[⌒] profsurf;[⌓] precsim;[≾] preceq;[⪯] primes;[ℙ] prnsim;[⋨] propto;[∝] prurel;[⊰] prcue;[≼] prime;[′] prnap;[⪹] prsim;[≾] prap;[⪷] prec;[≺] prnE;[⪵] prod;[∏] prop;[∝] prE;[⪳] pre;[⪯] pr;[≺]. "\x0aeccurlyeq;\x03≼\x0aecnapprox;\x03⪹\x09ecapprox;\x03⪷\x07ecneqq;\x03⪵\x07ecnsim;\x03⋨\x07ofalar;\x03⌮\x07ofline;\x03⌒\x07ofsurf;\x03⌓\x06ecsim;\x03≾\x05eceq;\x03⪯\x05imes;\x03ℙ\x05nsim;\x03⋨\x05opto;\x03∝\x05urel;\x03⊰\x04cue;\x03≼\x04ime;\x03′\x04nap;\x03⪹\x04sim;\x03≾\x03ap;\x03⪷\x03ec;\x03≺\x03nE;\x03⪵\x03od;\x03∏\x03op;\x03∝\x02E;\x03⪳\x02e;\x03⪯\x01;\x03≺", // pscr;[𝓅] psi;[ψ]. "\x03cr;\x04𝓅\x02i;\x02ψ", // puncsp;[ ]. "\x05ncsp;\x03 ", // qfr;[𝔮]. "\x02r;\x04𝔮", // qint;[⨌]. "\x03nt;\x03⨌", // qopf;[𝕢]. "\x03pf;\x04𝕢", // qprime;[⁗]. "\x05rime;\x03⁗", // qscr;[𝓆]. "\x03cr;\x04𝓆", // quaternions;[ℍ] quatint;[⨖] questeq;[≟] quest;[?] quot;[\"] quot[\"]. "\x0aaternions;\x03ℍ\x06atint;\x03⨖\x06esteq;\x03≟\x04est;\x01?\x03ot;\x01\"\x02ot\x01\"", // rAtail;[⤜] rAarr;[⇛] rArr;[⇒]. "\x05tail;\x03⤜\x04arr;\x03⇛\x03rr;\x03⇒", // rBarr;[⤏]. "\x04arr;\x03⤏", // rHar;[⥤]. "\x03ar;\x03⥤", // rationals;[ℚ] raemptyv;[⦳] rarrbfs;[⤠] rarrsim;[⥴] racute;[ŕ] rangle;[⟩] rarrap;[⥵] rarrfs;[⤞] rarrhk;[↪] rarrlp;[↬] rarrpl;[⥅] rarrtl;[↣] ratail;[⤚] radic;[√] rangd;[⦒] range;[⦥] raquo;[»] rarrb;[⇥] rarrc;[⤳] rarrw;[↝] ratio;[∶] race;[∽̱] rang;[⟩] raquo[»] rarr;[→]. "\x08tionals;\x03ℚ\x07emptyv;\x03⦳\x06rrbfs;\x03⤠\x06rrsim;\x03⥴\x05cute;\x02ŕ\x05ngle;\x03⟩\x05rrap;\x03⥵\x05rrfs;\x03⤞\x05rrhk;\x03↪\x05rrlp;\x03↬\x05rrpl;\x03⥅\x05rrtl;\x03↣\x05tail;\x03⤚\x04dic;\x03√\x04ngd;\x03⦒\x04nge;\x03⦥\x04quo;\x02»\x04rrb;\x03⇥\x04rrc;\x03⤳\x04rrw;\x03↝\x04tio;\x03∶\x03ce;\x05∽̱\x03ng;\x03⟩\x03quo\x02»\x03rr;\x03→", // rbrksld;[⦎] rbrkslu;[⦐] rbrace;[}] rbrack;[]] rbarr;[⤍] rbbrk;[❳] rbrke;[⦌]. "\x06rksld;\x03⦎\x06rkslu;\x03⦐\x05race;\x01}\x05rack;\x01]\x04arr;\x03⤍\x04brk;\x03❳\x04rke;\x03⦌", // rcaron;[ř] rcedil;[ŗ] rceil;[⌉] rcub;[}] rcy;[р]. "\x05aron;\x02ř\x05edil;\x02ŗ\x04eil;\x03⌉\x03ub;\x01}\x02y;\x02р", // rdldhar;[⥩] rdquor;[”] rdquo;[”] rdca;[⤷] rdsh;[↳]. "\x06ldhar;\x03⥩\x05quor;\x03”\x04quo;\x03”\x03ca;\x03⤷\x03sh;\x03↳", // realpart;[ℜ] realine;[ℛ] reals;[ℝ] real;[ℜ] rect;[▭] reg;[®] reg[®]. "\x07alpart;\x03ℜ\x06aline;\x03ℛ\x04als;\x03ℝ\x03al;\x03ℜ\x03ct;\x03▭\x02g;\x02®\x01g\x02®", // rfisht;[⥽] rfloor;[⌋] rfr;[𝔯]. "\x05isht;\x03⥽\x05loor;\x03⌋\x02r;\x04𝔯", // rharul;[⥬] rhard;[⇁] rharu;[⇀] rhov;[ϱ] rho;[ρ]. "\x05arul;\x03⥬\x04ard;\x03⇁\x04aru;\x03⇀\x03ov;\x02ϱ\x02o;\x02ρ", // rightleftharpoons;[⇌] rightharpoondown;[⇁] rightrightarrows;[⇉] rightleftarrows;[⇄] rightsquigarrow;[↝] rightthreetimes;[⋌] rightarrowtail;[↣] rightharpoonup;[⇀] risingdotseq;[≓] rightarrow;[→] ring;[˚]. "\x10ghtleftharpoons;\x03⇌\x0fghtharpoondown;\x03⇁\x0fghtrightarrows;\x03⇉\x0eghtleftarrows;\x03⇄\x0eghtsquigarrow;\x03↝\x0eghtthreetimes;\x03⋌\x0dghtarrowtail;\x03↣\x0dghtharpoonup;\x03⇀\x0bsingdotseq;\x03≓\x09ghtarrow;\x03→\x03ng;\x02˚", // rlarr;[⇄] rlhar;[⇌] rlm;[]. "\x04arr;\x03⇄\x04har;\x03⇌\x02m;\x03", // rmoustache;[⎱] rmoust;[⎱]. "\x09oustache;\x03⎱\x05oust;\x03⎱", // rnmid;[⫮]. "\x04mid;\x03⫮", // rotimes;[⨵] roplus;[⨮] roang;[⟭] roarr;[⇾] robrk;[⟧] ropar;[⦆] ropf;[𝕣]. "\x06times;\x03⨵\x05plus;\x03⨮\x04ang;\x03⟭\x04arr;\x03⇾\x04brk;\x03⟧\x04par;\x03⦆\x03pf;\x04𝕣", // rppolint;[⨒] rpargt;[⦔] rpar;[)]. "\x07polint;\x03⨒\x05argt;\x03⦔\x03ar;\x01)", // rrarr;[⇉]. "\x04arr;\x03⇉", // rsaquo;[›] rsquor;[’] rsquo;[’] rscr;[𝓇] rsqb;[]] rsh;[↱]. "\x05aquo;\x03›\x05quor;\x03’\x04quo;\x03’\x03cr;\x04𝓇\x03qb;\x01]\x02h;\x03↱", // rtriltri;[⧎] rthree;[⋌] rtimes;[⋊] rtrie;[⊵] rtrif;[▸] rtri;[▹]. "\x07riltri;\x03⧎\x05hree;\x03⋌\x05imes;\x03⋊\x04rie;\x03⊵\x04rif;\x03▸\x03ri;\x03▹", // ruluhar;[⥨]. "\x06luhar;\x03⥨", // rx;[℞]. "\x01;\x03℞", // sacute;[ś]. "\x05cute;\x02ś", // sbquo;[‚]. "\x04quo;\x03‚", // scpolint;[⨓] scaron;[š] scedil;[ş] scnsim;[⋩] sccue;[≽] scirc;[ŝ] scnap;[⪺] scsim;[≿] scap;[⪸] scnE;[⪶] scE;[⪴] sce;[⪰] scy;[с] sc;[≻]. "\x07polint;\x03⨓\x05aron;\x02š\x05edil;\x02ş\x05nsim;\x03⋩\x04cue;\x03≽\x04irc;\x02ŝ\x04nap;\x03⪺\x04sim;\x03≿\x03ap;\x03⪸\x03nE;\x03⪶\x02E;\x03⪴\x02e;\x03⪰\x02y;\x02с\x01;\x03≻", // sdotb;[⊡] sdote;[⩦] sdot;[⋅]. "\x04otb;\x03⊡\x04ote;\x03⩦\x03ot;\x03⋅", // setminus;[∖] searrow;[↘] searhk;[⤥] seswar;[⤩] seArr;[⇘] searr;[↘] setmn;[∖] sect;[§] semi;[;] sext;[✶] sect[§]. "\x07tminus;\x03∖\x06arrow;\x03↘\x05arhk;\x03⤥\x05swar;\x03⤩\x04Arr;\x03⇘\x04arr;\x03↘\x04tmn;\x03∖\x03ct;\x02§\x03mi;\x01;\x03xt;\x03✶\x02ct\x02§", // sfrown;[⌢] sfr;[𝔰]. "\x05rown;\x03⌢\x02r;\x04𝔰", // shortparallel;[∥] shortmid;[∣] shchcy;[щ] sharp;[♯] shcy;[ш] shy;[] shy[]. "\x0cortparallel;\x03∥\x07ortmid;\x03∣\x05chcy;\x02щ\x04arp;\x03♯\x03cy;\x02ш\x02y;\x02\x01y\x02", // simplus;[⨤] simrarr;[⥲] sigmaf;[ς] sigmav;[ς] simdot;[⩪] sigma;[σ] simeq;[≃] simgE;[⪠] simlE;[⪟] simne;[≆] sime;[≃] simg;[⪞] siml;[⪝] sim;[∼]. "\x06mplus;\x03⨤\x06mrarr;\x03⥲\x05gmaf;\x02ς\x05gmav;\x02ς\x05mdot;\x03⩪\x04gma;\x02σ\x04meq;\x03≃\x04mgE;\x03⪠\x04mlE;\x03⪟\x04mne;\x03≆\x03me;\x03≃\x03mg;\x03⪞\x03ml;\x03⪝\x02m;\x03∼", // slarr;[←]. "\x04arr;\x03←", // smallsetminus;[∖] smeparsl;[⧤] smashp;[⨳] smile;[⌣] smtes;[⪬︀] smid;[∣] smte;[⪬] smt;[⪪]. "\x0callsetminus;\x03∖\x07eparsl;\x03⧤\x05ashp;\x03⨳\x04ile;\x03⌣\x04tes;\x06⪬︀\x03id;\x03∣\x03te;\x03⪬\x02t;\x03⪪", // softcy;[ь] solbar;[⌿] solb;[⧄] sopf;[𝕤] sol;[/]. "\x05ftcy;\x02ь\x05lbar;\x03⌿\x03lb;\x03⧄\x03pf;\x04𝕤\x02l;\x01/", // spadesuit;[♠] spades;[♠] spar;[∥]. "\x08adesuit;\x03♠\x05ades;\x03♠\x03ar;\x03∥", // sqsubseteq;[⊑] sqsupseteq;[⊒] sqsubset;[⊏] sqsupset;[⊐] sqcaps;[⊓︀] sqcups;[⊔︀] sqsube;[⊑] sqsupe;[⊒] square;[□] squarf;[▪] sqcap;[⊓] sqcup;[⊔] sqsub;[⊏] sqsup;[⊐] squf;[▪] squ;[□]. "\x09subseteq;\x03⊑\x09supseteq;\x03⊒\x07subset;\x03⊏\x07supset;\x03⊐\x05caps;\x06⊓︀\x05cups;\x06⊔︀\x05sube;\x03⊑\x05supe;\x03⊒\x05uare;\x03□\x05uarf;\x03▪\x04cap;\x03⊓\x04cup;\x03⊔\x04sub;\x03⊏\x04sup;\x03⊐\x03uf;\x03▪\x02u;\x03□", // srarr;[→]. "\x04arr;\x03→", // ssetmn;[∖] ssmile;[⌣] sstarf;[⋆] sscr;[𝓈]. "\x05etmn;\x03∖\x05mile;\x03⌣\x05tarf;\x03⋆\x03cr;\x04𝓈", // straightepsilon;[ϵ] straightphi;[ϕ] starf;[★] strns;[¯] star;[☆]. "\x0eraightepsilon;\x02ϵ\x0araightphi;\x02ϕ\x04arf;\x03★\x04rns;\x02¯\x03ar;\x03☆", // succcurlyeq;[≽] succnapprox;[⪺] subsetneqq;[⫋] succapprox;[⪸] supsetneqq;[⫌] subseteqq;[⫅] subsetneq;[⊊] supseteqq;[⫆] supsetneq;[⊋] subseteq;[⊆] succneqq;[⪶] succnsim;[⋩] supseteq;[⊇] subedot;[⫃] submult;[⫁] subplus;[⪿] subrarr;[⥹] succsim;[≿] supdsub;[⫘] supedot;[⫄] suphsol;[⟉] suphsub;[⫗] suplarr;[⥻] supmult;[⫂] supplus;[⫀] subdot;[⪽] subset;[⊂] subsim;[⫇] subsub;[⫕] subsup;[⫓] succeq;[⪰] supdot;[⪾] supset;[⊃] supsim;[⫈] supsub;[⫔] supsup;[⫖] subnE;[⫋] subne;[⊊] supnE;[⫌] supne;[⊋] subE;[⫅] sube;[⊆] succ;[≻] sung;[♪] sup1;[¹] sup2;[²] sup3;[³] supE;[⫆] supe;[⊇] sub;[⊂] sum;[∑] sup1[¹] sup2[²] sup3[³] sup;[⊃]. "\x0acccurlyeq;\x03≽\x0accnapprox;\x03⪺\x09bsetneqq;\x03⫋\x09ccapprox;\x03⪸\x09psetneqq;\x03⫌\x08bseteqq;\x03⫅\x08bsetneq;\x03⊊\x08pseteqq;\x03⫆\x08psetneq;\x03⊋\x07bseteq;\x03⊆\x07ccneqq;\x03⪶\x07ccnsim;\x03⋩\x07pseteq;\x03⊇\x06bedot;\x03⫃\x06bmult;\x03⫁\x06bplus;\x03⪿\x06brarr;\x03⥹\x06ccsim;\x03≿\x06pdsub;\x03⫘\x06pedot;\x03⫄\x06phsol;\x03⟉\x06phsub;\x03⫗\x06plarr;\x03⥻\x06pmult;\x03⫂\x06pplus;\x03⫀\x05bdot;\x03⪽\x05bset;\x03⊂\x05bsim;\x03⫇\x05bsub;\x03⫕\x05bsup;\x03⫓\x05cceq;\x03⪰\x05pdot;\x03⪾\x05pset;\x03⊃\x05psim;\x03⫈\x05psub;\x03⫔\x05psup;\x03⫖\x04bnE;\x03⫋\x04bne;\x03⊊\x04pnE;\x03⫌\x04pne;\x03⊋\x03bE;\x03⫅\x03be;\x03⊆\x03cc;\x03≻\x03ng;\x03♪\x03p1;\x02¹\x03p2;\x02²\x03p3;\x02³\x03pE;\x03⫆\x03pe;\x03⊇\x02b;\x03⊂\x02m;\x03∑\x02p1\x02¹\x02p2\x02²\x02p3\x02³\x02p;\x03⊃", // swarrow;[↙] swarhk;[⤦] swnwar;[⤪] swArr;[⇙] swarr;[↙]. "\x06arrow;\x03↙\x05arhk;\x03⤦\x05nwar;\x03⤪\x04Arr;\x03⇙\x04arr;\x03↙", // szlig;[ß] szlig[ß]. "\x04lig;\x02ß\x03lig\x02ß", // target;[⌖] tau;[τ]. "\x05rget;\x03⌖\x02u;\x02τ", // tbrk;[⎴]. "\x03rk;\x03⎴", // tcaron;[ť] tcedil;[ţ] tcy;[т]. "\x05aron;\x02ť\x05edil;\x02ţ\x02y;\x02т", // tdot;[⃛]. "\x03ot;\x03⃛", // telrec;[⌕]. "\x05lrec;\x03⌕", // tfr;[𝔱]. "\x02r;\x04𝔱", // thickapprox;[≈] therefore;[∴] thetasym;[ϑ] thicksim;[∼] there4;[∴] thetav;[ϑ] thinsp;[ ] thksim;[∼] theta;[θ] thkap;[≈] thorn;[þ] thorn[þ]. "\x0aickapprox;\x03≈\x08erefore;\x03∴\x07etasym;\x02ϑ\x07icksim;\x03∼\x05ere4;\x03∴\x05etav;\x02ϑ\x05insp;\x03 \x05ksim;\x03∼\x04eta;\x02θ\x04kap;\x03≈\x04orn;\x02þ\x03orn\x02þ", // timesbar;[⨱] timesb;[⊠] timesd;[⨰] tilde;[˜] times;[×] times[×] tint;[∭]. "\x07mesbar;\x03⨱\x05mesb;\x03⊠\x05mesd;\x03⨰\x04lde;\x02˜\x04mes;\x02×\x03mes\x02×\x03nt;\x03∭", // topfork;[⫚] topbot;[⌶] topcir;[⫱] toea;[⤨] topf;[𝕥] tosa;[⤩] top;[⊤]. "\x06pfork;\x03⫚\x05pbot;\x03⌶\x05pcir;\x03⫱\x03ea;\x03⤨\x03pf;\x04𝕥\x03sa;\x03⤩\x02p;\x03⊤", // tprime;[‴]. "\x05rime;\x03‴", // trianglerighteq;[⊵] trianglelefteq;[⊴] triangleright;[▹] triangledown;[▿] triangleleft;[◃] triangleq;[≜] triangle;[▵] triminus;[⨺] trpezium;[⏢] triplus;[⨹] tritime;[⨻] tridot;[◬] trade;[™] trisb;[⧍] trie;[≜]. "\x0eianglerighteq;\x03⊵\x0dianglelefteq;\x03⊴\x0ciangleright;\x03▹\x0biangledown;\x03▿\x0biangleleft;\x03◃\x08iangleq;\x03≜\x07iangle;\x03▵\x07iminus;\x03⨺\x07pezium;\x03⏢\x06iplus;\x03⨹\x06itime;\x03⨻\x05idot;\x03◬\x04ade;\x03™\x04isb;\x03⧍\x03ie;\x03≜", // tstrok;[ŧ] tshcy;[ћ] tscr;[𝓉] tscy;[ц]. "\x05trok;\x02ŧ\x04hcy;\x02ћ\x03cr;\x04𝓉\x03cy;\x02ц", // twoheadrightarrow;[↠] twoheadleftarrow;[↞] twixt;[≬]. "\x10oheadrightarrow;\x03↠\x0foheadleftarrow;\x03↞\x04ixt;\x03≬", // uArr;[⇑]. "\x03rr;\x03⇑", // uHar;[⥣]. "\x03ar;\x03⥣", // uacute;[ú] uacute[ú] uarr;[↑]. "\x05cute;\x02ú\x04cute\x02ú\x03rr;\x03↑", // ubreve;[ŭ] ubrcy;[ў]. "\x05reve;\x02ŭ\x04rcy;\x02ў", // ucirc;[û] ucirc[û] ucy;[у]. "\x04irc;\x02û\x03irc\x02û\x02y;\x02у", // udblac;[ű] udarr;[⇅] udhar;[⥮]. "\x05blac;\x02ű\x04arr;\x03⇅\x04har;\x03⥮", // ufisht;[⥾] ufr;[𝔲]. "\x05isht;\x03⥾\x02r;\x04𝔲", // ugrave;[ù] ugrave[ù]. "\x05rave;\x02ù\x04rave\x02ù", // uharl;[↿] uharr;[↾] uhblk;[▀]. "\x04arl;\x03↿\x04arr;\x03↾\x04blk;\x03▀", // ulcorner;[⌜] ulcorn;[⌜] ulcrop;[⌏] ultri;[◸]. "\x07corner;\x03⌜\x05corn;\x03⌜\x05crop;\x03⌏\x04tri;\x03◸", // umacr;[ū] uml;[¨] uml[¨]. "\x04acr;\x02ū\x02l;\x02¨\x01l\x02¨", // uogon;[ų] uopf;[𝕦]. "\x04gon;\x02ų\x03pf;\x04𝕦", // upharpoonright;[↾] upharpoonleft;[↿] updownarrow;[↕] upuparrows;[⇈] uparrow;[↑] upsilon;[υ] uplus;[⊎] upsih;[ϒ] upsi;[υ]. "\x0dharpoonright;\x03↾\x0charpoonleft;\x03↿\x0adownarrow;\x03↕\x09uparrows;\x03⇈\x06arrow;\x03↑\x06silon;\x02υ\x04lus;\x03⊎\x04sih;\x02ϒ\x03si;\x02υ", // urcorner;[⌝] urcorn;[⌝] urcrop;[⌎] uring;[ů] urtri;[◹]. "\x07corner;\x03⌝\x05corn;\x03⌝\x05crop;\x03⌎\x04ing;\x02ů\x04tri;\x03◹", // uscr;[𝓊]. "\x03cr;\x04𝓊", // utilde;[ũ] utdot;[⋰] utrif;[▴] utri;[▵]. "\x05ilde;\x02ũ\x04dot;\x03⋰\x04rif;\x03▴\x03ri;\x03▵", // uuarr;[⇈] uuml;[ü] uuml[ü]. "\x04arr;\x03⇈\x03ml;\x02ü\x02ml\x02ü", // uwangle;[⦧]. "\x06angle;\x03⦧", // vArr;[⇕]. "\x03rr;\x03⇕", // vBarv;[⫩] vBar;[⫨]. "\x04arv;\x03⫩\x03ar;\x03⫨", // vDash;[⊨]. "\x04ash;\x03⊨", // vartriangleright;[⊳] vartriangleleft;[⊲] varsubsetneqq;[⫋︀] varsupsetneqq;[⫌︀] varsubsetneq;[⊊︀] varsupsetneq;[⊋︀] varepsilon;[ϵ] varnothing;[∅] varpropto;[∝] varkappa;[ϰ] varsigma;[ς] vartheta;[ϑ] vangrt;[⦜] varphi;[ϕ] varrho;[ϱ] varpi;[ϖ] varr;[↕]. "\x0frtriangleright;\x03⊳\x0ertriangleleft;\x03⊲\x0crsubsetneqq;\x06⫋︀\x0crsupsetneqq;\x06⫌︀\x0brsubsetneq;\x06⊊︀\x0brsupsetneq;\x06⊋︀\x09repsilon;\x02ϵ\x09rnothing;\x03∅\x08rpropto;\x03∝\x07rkappa;\x02ϰ\x07rsigma;\x02ς\x07rtheta;\x02ϑ\x05ngrt;\x03⦜\x05rphi;\x02ϕ\x05rrho;\x02ϱ\x04rpi;\x02ϖ\x03rr;\x03↕", // vcy;[в]. "\x02y;\x02в", // vdash;[⊢]. "\x04ash;\x03⊢", // veebar;[⊻] vellip;[⋮] verbar;[|] veeeq;[≚] vert;[|] vee;[∨]. "\x05ebar;\x03⊻\x05llip;\x03⋮\x05rbar;\x01|\x04eeq;\x03≚\x03rt;\x01|\x02e;\x03∨", // vfr;[𝔳]. "\x02r;\x04𝔳", // vltri;[⊲]. "\x04tri;\x03⊲", // vnsub;[⊂⃒] vnsup;[⊃⃒]. "\x04sub;\x06⊂⃒\x04sup;\x06⊃⃒", // vopf;[𝕧]. "\x03pf;\x04𝕧", // vprop;[∝]. "\x04rop;\x03∝", // vrtri;[⊳]. "\x04tri;\x03⊳", // vsubnE;[⫋︀] vsubne;[⊊︀] vsupnE;[⫌︀] vsupne;[⊋︀] vscr;[𝓋]. "\x05ubnE;\x06⫋︀\x05ubne;\x06⊊︀\x05upnE;\x06⫌︀\x05upne;\x06⊋︀\x03cr;\x04𝓋", // vzigzag;[⦚]. "\x06igzag;\x03⦚", // wcirc;[ŵ]. "\x04irc;\x02ŵ", // wedbar;[⩟] wedgeq;[≙] weierp;[℘] wedge;[∧]. "\x05dbar;\x03⩟\x05dgeq;\x03≙\x05ierp;\x03℘\x04dge;\x03∧", // wfr;[𝔴]. "\x02r;\x04𝔴", // wopf;[𝕨]. "\x03pf;\x04𝕨", // wp;[℘]. "\x01;\x03℘", // wreath;[≀] wr;[≀]. "\x05eath;\x03≀\x01;\x03≀", // wscr;[𝓌]. "\x03cr;\x04𝓌", // xcirc;[◯] xcap;[⋂] xcup;[⋃]. "\x04irc;\x03◯\x03ap;\x03⋂\x03up;\x03⋃", // xdtri;[▽]. "\x04tri;\x03▽", // xfr;[𝔵]. "\x02r;\x04𝔵", // xhArr;[⟺] xharr;[⟷]. "\x04Arr;\x03⟺\x04arr;\x03⟷", // xi;[ξ]. "\x01;\x02ξ", // xlArr;[⟸] xlarr;[⟵]. "\x04Arr;\x03⟸\x04arr;\x03⟵", // xmap;[⟼]. "\x03ap;\x03⟼", // xnis;[⋻]. "\x03is;\x03⋻", // xoplus;[⨁] xotime;[⨂] xodot;[⨀] xopf;[𝕩]. "\x05plus;\x03⨁\x05time;\x03⨂\x04dot;\x03⨀\x03pf;\x04𝕩", // xrArr;[⟹] xrarr;[⟶]. "\x04Arr;\x03⟹\x04arr;\x03⟶", // xsqcup;[⨆] xscr;[𝓍]. "\x05qcup;\x03⨆\x03cr;\x04𝓍", // xuplus;[⨄] xutri;[△]. "\x05plus;\x03⨄\x04tri;\x03△", // xvee;[⋁]. "\x03ee;\x03⋁", // xwedge;[⋀]. "\x05edge;\x03⋀", // yacute;[ý] yacute[ý] yacy;[я]. "\x05cute;\x02ý\x04cute\x02ý\x03cy;\x02я", // ycirc;[ŷ] ycy;[ы]. "\x04irc;\x02ŷ\x02y;\x02ы", // yen;[¥] yen[¥]. "\x02n;\x02¥\x01n\x02¥", // yfr;[𝔶]. "\x02r;\x04𝔶", // yicy;[ї]. "\x03cy;\x02ї", // yopf;[𝕪]. "\x03pf;\x04𝕪", // yscr;[𝓎]. "\x03cr;\x04𝓎", // yucy;[ю] yuml;[ÿ] yuml[ÿ]. "\x03cy;\x02ю\x03ml;\x02ÿ\x02ml\x02ÿ", // zacute;[ź]. "\x05cute;\x02ź", // zcaron;[ž] zcy;[з]. "\x05aron;\x02ž\x02y;\x02з", // zdot;[ż]. "\x03ot;\x02ż", // zeetrf;[ℨ] zeta;[ζ]. "\x05etrf;\x03ℨ\x03ta;\x02ζ", // zfr;[𝔷]. "\x02r;\x04𝔷", // zhcy;[ж]. "\x03cy;\x02ж", // zigrarr;[⇝]. "\x06grarr;\x03⇝", // zopf;[𝕫]. "\x03pf;\x04𝕫", // zscr;[𝓏]. "\x03cr;\x04𝓏", // zwnj;[] zwj;[]. "\x03nj;\x03\x02j;\x03", ), "small_words" => "GT\x00LT\x00gt\x00lt\x00", "small_mappings" => array( ">", "<", ">", "<", ) ) ); <?php /** * HTML API: WP_HTML_Processor_State class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used by the HTML processor during HTML parsing * for managing the internal parsing state. * * This class is designed for internal use by the HTML processor. * * @since 6.4.0 * * @access private * * @see WP_HTML_Processor */ class WP_HTML_Processor_State { /* * Insertion mode constants. * * These constants exist and are named to make it easier to * discover and recognize the supported insertion modes in * the parser. * * Out of all the possible insertion modes, only those * supported by the parser are listed here. As support * is added to the parser for more modes, add them here * following the same naming and value pattern. * * @see https://html.spec.whatwg.org/#the-insertion-mode */ /** * Initial insertion mode for full HTML parser. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#the-initial-insertion-mode * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_INITIAL = 'insertion-mode-initial'; /** * Before HTML insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#the-before-html-insertion-mode * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_BEFORE_HTML = 'insertion-mode-before-html'; /** * Before head insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-beforehead * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_BEFORE_HEAD = 'insertion-mode-before-head'; /** * In head insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inhead * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_HEAD = 'insertion-mode-in-head'; /** * In head noscript insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inheadnoscript * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_HEAD_NOSCRIPT = 'insertion-mode-in-head-noscript'; /** * After head insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-afterhead * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_AFTER_HEAD = 'insertion-mode-after-head'; /** * In body insertion mode for full HTML parser. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#parsing-main-inbody * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_BODY = 'insertion-mode-in-body'; /** * In table insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-intable * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_TABLE = 'insertion-mode-in-table'; /** * In table text insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-intabletext * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_TABLE_TEXT = 'insertion-mode-in-table-text'; /** * In caption insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-incaption * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_CAPTION = 'insertion-mode-in-caption'; /** * In column group insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-incolumngroup * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_COLUMN_GROUP = 'insertion-mode-in-column-group'; /** * In table body insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-intablebody * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_TABLE_BODY = 'insertion-mode-in-table-body'; /** * In row insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inrow * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_ROW = 'insertion-mode-in-row'; /** * In cell insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-incell * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_CELL = 'insertion-mode-in-cell'; /** * In select insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inselect * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_SELECT = 'insertion-mode-in-select'; /** * In select in table insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inselectintable * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_SELECT_IN_TABLE = 'insertion-mode-in-select-in-table'; /** * In template insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-intemplate * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_TEMPLATE = 'insertion-mode-in-template'; /** * After body insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-afterbody * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_AFTER_BODY = 'insertion-mode-after-body'; /** * In frameset insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-inframeset * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_IN_FRAMESET = 'insertion-mode-in-frameset'; /** * After frameset insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#parsing-main-afterframeset * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_AFTER_FRAMESET = 'insertion-mode-after-frameset'; /** * After after body insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#the-after-after-body-insertion-mode * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_AFTER_AFTER_BODY = 'insertion-mode-after-after-body'; /** * After after frameset insertion mode for full HTML parser. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#the-after-after-frameset-insertion-mode * @see WP_HTML_Processor_State::$insertion_mode * * @var string */ const INSERTION_MODE_AFTER_AFTER_FRAMESET = 'insertion-mode-after-after-frameset'; /** * The stack of template insertion modes. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#the-insertion-mode:stack-of-template-insertion-modes * * @var array<string> */ public $stack_of_template_insertion_modes = array(); /** * Tracks open elements while scanning HTML. * * This property is initialized in the constructor and never null. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#stack-of-open-elements * * @var WP_HTML_Open_Elements */ public $stack_of_open_elements; /** * Tracks open formatting elements, used to handle mis-nested formatting element tags. * * This property is initialized in the constructor and never null. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#list-of-active-formatting-elements * * @var WP_HTML_Active_Formatting_Elements */ public $active_formatting_elements; /** * Refers to the currently-matched tag, if any. * * @since 6.4.0 * * @var WP_HTML_Token|null */ public $current_token = null; /** * Tree construction insertion mode. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#insertion-mode * * @var string */ public $insertion_mode = self::INSERTION_MODE_INITIAL; /** * Context node initializing fragment parser, if created as a fragment parser. * * @since 6.4.0 * @deprecated 6.8.0 WP_HTML_Processor tracks the context_node internally. * * @var null */ public $context_node = null; /** * The recognized encoding of the input byte stream. * * > The stream of code points that comprises the input to the tokenization * > stage will be initially seen by the user agent as a stream of bytes * > (typically coming over the network or from the local file system). * > The bytes encode the actual characters according to a particular character * > encoding, which the user agent uses to decode the bytes into characters. * * @since 6.7.0 * * @var string|null */ public $encoding = null; /** * The parser's confidence in the input encoding. * * > When the HTML parser is decoding an input byte stream, it uses a character * > encoding and a confidence. The confidence is either tentative, certain, or * > irrelevant. The encoding used, and whether the confidence in that encoding * > is tentative or certain, is used during the parsing to determine whether to * > change the encoding. If no encoding is necessary, e.g. because the parser is * > operating on a Unicode stream and doesn't have to use a character encoding * > at all, then the confidence is irrelevant. * * @since 6.7.0 * * @var string */ public $encoding_confidence = 'tentative'; /** * HEAD element pointer. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/multipage/parsing.html#head-element-pointer * * @var WP_HTML_Token|null */ public $head_element = null; /** * FORM element pointer. * * > points to the last form element that was opened and whose end tag has * > not yet been seen. It is used to make form controls associate with * > forms in the face of dramatically bad markup, for historical reasons. * > It is ignored inside template elements. * * @todo This may be invalidated by a seek operation. * * @see https://html.spec.whatwg.org/#form-element-pointer * * @since 6.7.0 * * @var WP_HTML_Token|null */ public $form_element = null; /** * The frameset-ok flag indicates if a `FRAMESET` element is allowed in the current state. * * > The frameset-ok flag is set to "ok" when the parser is created. It is set to "not ok" after certain tokens are seen. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#frameset-ok-flag * * @var bool */ public $frameset_ok = true; /** * Constructor - creates a new and empty state value. * * @since 6.4.0 * * @see WP_HTML_Processor */ public function __construct() { $this->stack_of_open_elements = new WP_HTML_Open_Elements(); $this->active_formatting_elements = new WP_HTML_Active_Formatting_Elements(); } } <?php /** * HTML API: WP_HTML_Processor class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used to safely parse and modify an HTML document. * * The HTML Processor class properly parses and modifies HTML5 documents. * * It supports a subset of the HTML5 specification, and when it encounters * unsupported markup, it aborts early to avoid unintentionally breaking * the document. The HTML Processor should never break an HTML document. * * While the `WP_HTML_Tag_Processor` is a valuable tool for modifying * attributes on individual HTML tags, the HTML Processor is more capable * and useful for the following operations: * * - Querying based on nested HTML structure. * * Eventually the HTML Processor will also support: * - Wrapping a tag in surrounding HTML. * - Unwrapping a tag by removing its parent. * - Inserting and removing nodes. * - Reading and changing inner content. * - Navigating up or around HTML structure. * * ## Usage * * Use of this class requires three steps: * * 1. Call a static creator method with your input HTML document. * 2. Find the location in the document you are looking for. * 3. Request changes to the document at that location. * * Example: * * $processor = WP_HTML_Processor::create_fragment( $html ); * if ( $processor->next_tag( array( 'breadcrumbs' => array( 'DIV', 'FIGURE', 'IMG' ) ) ) ) { * $processor->add_class( 'responsive-image' ); * } * * #### Breadcrumbs * * Breadcrumbs represent the stack of open elements from the root * of the document or fragment down to the currently-matched node, * if one is currently selected. Call WP_HTML_Processor::get_breadcrumbs() * to inspect the breadcrumbs for a matched tag. * * Breadcrumbs can specify nested HTML structure and are equivalent * to a CSS selector comprising tag names separated by the child * combinator, such as "DIV > FIGURE > IMG". * * Since all elements find themselves inside a full HTML document * when parsed, the return value from `get_breadcrumbs()` will always * contain any implicit outermost elements. For example, when parsing * with `create_fragment()` in the `BODY` context (the default), any * tag in the given HTML document will contain `array( 'HTML', 'BODY', … )` * in its breadcrumbs. * * Despite containing the implied outermost elements in their breadcrumbs, * tags may be found with the shortest-matching breadcrumb query. That is, * `array( 'IMG' )` matches all IMG elements and `array( 'P', 'IMG' )` * matches all IMG elements directly inside a P element. To ensure that no * partial matches erroneously match it's possible to specify in a query * the full breadcrumb match all the way down from the root HTML element. * * Example: * * $html = '<figure><img><figcaption>A <em>lovely</em> day outside</figcaption></figure>'; * // ----- Matches here. * $processor->next_tag( array( 'breadcrumbs' => array( 'FIGURE', 'IMG' ) ) ); * * $html = '<figure><img><figcaption>A <em>lovely</em> day outside</figcaption></figure>'; * // ---- Matches here. * $processor->next_tag( array( 'breadcrumbs' => array( 'FIGURE', 'FIGCAPTION', 'EM' ) ) ); * * $html = '<div><img></div><img>'; * // ----- Matches here, because IMG must be a direct child of the implicit BODY. * $processor->next_tag( array( 'breadcrumbs' => array( 'BODY', 'IMG' ) ) ); * * ## HTML Support * * This class implements a small part of the HTML5 specification. * It's designed to operate within its support and abort early whenever * encountering circumstances it can't properly handle. This is * the principle way in which this class remains as simple as possible * without cutting corners and breaking compliance. * * ### Supported elements * * If any unsupported element appears in the HTML input the HTML Processor * will abort early and stop all processing. This draconian measure ensures * that the HTML Processor won't break any HTML it doesn't fully understand. * * The HTML Processor supports all elements other than a specific set: * * - Any element inside a TABLE. * - Any element inside foreign content, including SVG and MATH. * - Any element outside the IN BODY insertion mode, e.g. doctype declarations, meta, links. * * ### Supported markup * * Some kinds of non-normative HTML involve reconstruction of formatting elements and * re-parenting of mis-nested elements. For example, a DIV tag found inside a TABLE * may in fact belong _before_ the table in the DOM. If the HTML Processor encounters * such a case it will stop processing. * * The following list illustrates some common examples of unexpected HTML inputs that * the HTML Processor properly parses and represents: * * - HTML with optional tags omitted, e.g. `<p>one<p>two`. * - HTML with unexpected tag closers, e.g. `<p>one </span> more</p>`. * - Non-void tags with self-closing flag, e.g. `<div/>the DIV is still open.</div>`. * - Heading elements which close open heading elements of another level, e.g. `<h1>Closed by </h2>`. * - Elements containing text that looks like other tags but isn't, e.g. `<title>The <img> is plaintext</title>`. * - SCRIPT and STYLE tags containing text that looks like HTML but isn't, e.g. `<script>document.write('<p>Hi</p>');</script>`. * - SCRIPT content which has been escaped, e.g. `<script><!-- document.write('<script>console.log("hi")</script>') --></script>`. * * ### Unsupported Features * * This parser does not report parse errors. * * Normally, when additional HTML or BODY tags are encountered in a document, if there * are any additional attributes on them that aren't found on the previous elements, * the existing HTML and BODY elements adopt those missing attribute values. This * parser does not add those additional attributes. * * In certain situations, elements are moved to a different part of the document in * a process called "adoption" and "fostering." Because the nodes move to a location * in the document that the parser had already processed, this parser does not support * these situations and will bail. * * @since 6.4.0 * * @see WP_HTML_Tag_Processor * @see https://html.spec.whatwg.org/ */ class WP_HTML_Processor extends WP_HTML_Tag_Processor { /** * The maximum number of bookmarks allowed to exist at any given time. * * HTML processing requires more bookmarks than basic tag processing, * so this class constant from the Tag Processor is overwritten. * * @since 6.4.0 * * @var int */ const MAX_BOOKMARKS = 100; /** * Holds the working state of the parser, including the stack of * open elements and the stack of active formatting elements. * * Initialized in the constructor. * * @since 6.4.0 * * @var WP_HTML_Processor_State */ private $state; /** * Used to create unique bookmark names. * * This class sets a bookmark for every tag in the HTML document that it encounters. * The bookmark name is auto-generated and increments, starting with `1`. These are * internal bookmarks and are automatically released when the referring WP_HTML_Token * goes out of scope and is garbage-collected. * * @since 6.4.0 * * @see WP_HTML_Processor::$release_internal_bookmark_on_destruct * * @var int */ private $bookmark_counter = 0; /** * Stores an explanation for why something failed, if it did. * * @see self::get_last_error * * @since 6.4.0 * * @var string|null */ private $last_error = null; /** * Stores context for why the parser bailed on unsupported HTML, if it did. * * @see self::get_unsupported_exception * * @since 6.7.0 * * @var WP_HTML_Unsupported_Exception|null */ private $unsupported_exception = null; /** * Releases a bookmark when PHP garbage-collects its wrapping WP_HTML_Token instance. * * This function is created inside the class constructor so that it can be passed to * the stack of open elements and the stack of active formatting elements without * exposing it as a public method on the class. * * @since 6.4.0 * * @var Closure|null */ private $release_internal_bookmark_on_destruct = null; /** * Stores stack events which arise during parsing of the * HTML document, which will then supply the "match" events. * * @since 6.6.0 * * @var WP_HTML_Stack_Event[] */ private $element_queue = array(); /** * Stores the current breadcrumbs. * * @since 6.7.0 * * @var string[] */ private $breadcrumbs = array(); /** * Current stack event, if set, representing a matched token. * * Because the parser may internally point to a place further along in a document * than the nodes which have already been processed (some "virtual" nodes may have * appeared while scanning the HTML document), this will point at the "current" node * being processed. It comes from the front of the element queue. * * @since 6.6.0 * * @var WP_HTML_Stack_Event|null */ private $current_element = null; /** * Context node if created as a fragment parser. * * @var WP_HTML_Token|null */ private $context_node = null; /* * Public Interface Functions */ /** * Creates an HTML processor in the fragment parsing mode. * * Use this for cases where you are processing chunks of HTML that * will be found within a bigger HTML document, such as rendered * block output that exists within a post, `the_content` inside a * rendered site layout. * * Fragment parsing occurs within a context, which is an HTML element * that the document will eventually be placed in. It becomes important * when special elements have different rules than others, such as inside * a TEXTAREA or a TITLE tag where things that look like tags are text, * or inside a SCRIPT tag where things that look like HTML syntax are JS. * * The context value should be a representation of the tag into which the * HTML is found. For most cases this will be the body element. The HTML * form is provided because a context element may have attributes that * impact the parse, such as with a SCRIPT tag and its `type` attribute. * * ## Current HTML Support * * - The only supported context is `<body>`, which is the default value. * - The only supported document encoding is `UTF-8`, which is the default value. * * @since 6.4.0 * @since 6.6.0 Returns `static` instead of `self` so it can create subclass instances. * * @param string $html Input HTML fragment to process. * @param string $context Context element for the fragment, must be default of `<body>`. * @param string $encoding Text encoding of the document; must be default of 'UTF-8'. * @return static|null The created processor if successful, otherwise null. */ public static function create_fragment( $html, $context = '<body>', $encoding = 'UTF-8' ) { if ( '<body>' !== $context || 'UTF-8' !== $encoding ) { return null; } $context_processor = static::create_full_parser( "<!DOCTYPE html>{$context}", $encoding ); if ( null === $context_processor ) { return null; } while ( $context_processor->next_tag() ) { if ( ! $context_processor->is_virtual() ) { $context_processor->set_bookmark( 'final_node' ); } } if ( ! $context_processor->has_bookmark( 'final_node' ) || ! $context_processor->seek( 'final_node' ) ) { _doing_it_wrong( __METHOD__, __( 'No valid context element was detected.' ), '6.8.0' ); return null; } return $context_processor->create_fragment_at_current_node( $html ); } /** * Creates an HTML processor in the full parsing mode. * * It's likely that a fragment parser is more appropriate, unless sending an * entire HTML document from start to finish. Consider a fragment parser with * a context node of `<body>`. * * UTF-8 is the only allowed encoding. If working with a document that * isn't UTF-8, first convert the document to UTF-8, then pass in the * converted HTML. * * @param string $html Input HTML document to process. * @param string|null $known_definite_encoding Optional. If provided, specifies the charset used * in the input byte stream. Currently must be UTF-8. * @return static|null The created processor if successful, otherwise null. */ public static function create_full_parser( $html, $known_definite_encoding = 'UTF-8' ) { if ( 'UTF-8' !== $known_definite_encoding ) { return null; } $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); $processor->state->encoding = $known_definite_encoding; $processor->state->encoding_confidence = 'certain'; return $processor; } /** * Constructor. * * Do not use this method. Use the static creator methods instead. * * @access private * * @since 6.4.0 * * @see WP_HTML_Processor::create_fragment() * * @param string $html HTML to process. * @param string|null $use_the_static_create_methods_instead This constructor should not be called manually. */ public function __construct( $html, $use_the_static_create_methods_instead = null ) { parent::__construct( $html ); if ( self::CONSTRUCTOR_UNLOCK_CODE !== $use_the_static_create_methods_instead ) { _doing_it_wrong( __METHOD__, sprintf( /* translators: %s: WP_HTML_Processor::create_fragment(). */ __( 'Call %s to create an HTML Processor instead of calling the constructor directly.' ), '<code>WP_HTML_Processor::create_fragment()</code>' ), '6.4.0' ); } $this->state = new WP_HTML_Processor_State(); $this->state->stack_of_open_elements->set_push_handler( function ( WP_HTML_Token $token ): void { $is_virtual = ! isset( $this->state->current_token ) || $this->is_tag_closer(); $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::PUSH, $provenance ); $this->change_parsing_namespace( $token->integration_node_type ? 'html' : $token->namespace ); } ); $this->state->stack_of_open_elements->set_pop_handler( function ( WP_HTML_Token $token ): void { $is_virtual = ! isset( $this->state->current_token ) || ! $this->is_tag_closer(); $same_node = isset( $this->state->current_token ) && $token->node_name === $this->state->current_token->node_name; $provenance = ( ! $same_node || $is_virtual ) ? 'virtual' : 'real'; $this->element_queue[] = new WP_HTML_Stack_Event( $token, WP_HTML_Stack_Event::POP, $provenance ); $adjusted_current_node = $this->get_adjusted_current_node(); if ( $adjusted_current_node ) { $this->change_parsing_namespace( $adjusted_current_node->integration_node_type ? 'html' : $adjusted_current_node->namespace ); } else { $this->change_parsing_namespace( 'html' ); } } ); /* * Create this wrapper so that it's possible to pass * a private method into WP_HTML_Token classes without * exposing it to any public API. */ $this->release_internal_bookmark_on_destruct = function ( string $name ): void { parent::release_bookmark( $name ); }; } /** * Creates a fragment processor at the current node. * * HTML Fragment parsing always happens with a context node. HTML Fragment Processors can be * instantiated with a `BODY` context node via `WP_HTML_Processor::create_fragment( $html )`. * * The context node may impact how a fragment of HTML is parsed. For example, consider the HTML * fragment `<td />Inside TD?</td>`. * * A BODY context node will produce the following tree: * * └─#text Inside TD? * * Notice that the `<td>` tags are completely ignored. * * Compare that with an SVG context node that produces the following tree: * * ├─svg:td * └─#text Inside TD? * * Here, a `td` node in the `svg` namespace is created, and its self-closing flag is respected. * This is a peculiarity of parsing HTML in foreign content like SVG. * * Finally, consider the tree produced with a TABLE context node: * * └─TBODY * └─TR * └─TD * └─#text Inside TD? * * These examples demonstrate how important the context node may be when processing an HTML * fragment. Special care must be taken when processing fragments that are expected to appear * in specific contexts. SVG and TABLE are good examples, but there are others. * * @see https://html.spec.whatwg.org/multipage/parsing.html#html-fragment-parsing-algorithm * * @since 6.8.0 * * @param string $html Input HTML fragment to process. * @return static|null The created processor if successful, otherwise null. */ private function create_fragment_at_current_node( string $html ) { if ( $this->get_token_type() !== '#tag' || $this->is_tag_closer() ) { _doing_it_wrong( __METHOD__, __( 'The context element must be a start tag.' ), '6.8.0' ); return null; } $tag_name = $this->current_element->token->node_name; $namespace = $this->current_element->token->namespace; if ( 'html' === $namespace && self::is_void( $tag_name ) ) { _doing_it_wrong( __METHOD__, sprintf( // translators: %s: A tag name like INPUT or BR. __( 'The context element cannot be a void element, found "%s".' ), $tag_name ), '6.8.0' ); return null; } /* * Prevent creating fragments at nodes that require a special tokenizer state. * This is unsupported by the HTML Processor. */ if ( 'html' === $namespace && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP', 'PLAINTEXT' ), true ) ) { _doing_it_wrong( __METHOD__, sprintf( // translators: %s: A tag name like IFRAME or TEXTAREA. __( 'The context element "%s" is not supported.' ), $tag_name ), '6.8.0' ); return null; } $fragment_processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE ); $fragment_processor->compat_mode = $this->compat_mode; // @todo Create "fake" bookmarks for non-existent but implied nodes. $fragment_processor->bookmarks['root-node'] = new WP_HTML_Span( 0, 0 ); $root_node = new WP_HTML_Token( 'root-node', 'HTML', false ); $fragment_processor->state->stack_of_open_elements->push( $root_node ); $fragment_processor->bookmarks['context-node'] = new WP_HTML_Span( 0, 0 ); $fragment_processor->context_node = clone $this->current_element->token; $fragment_processor->context_node->bookmark_name = 'context-node'; $fragment_processor->context_node->on_destroy = null; $fragment_processor->breadcrumbs = array( 'HTML', $fragment_processor->context_node->node_name ); if ( 'TEMPLATE' === $fragment_processor->context_node->node_name ) { $fragment_processor->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; } $fragment_processor->reset_insertion_mode_appropriately(); /* * > Set the parser's form element pointer to the nearest node to the context element that * > is a form element (going straight up the ancestor chain, and including the element * > itself, if it is a form element), if any. (If there is no such form element, the * > form element pointer keeps its initial value, null.) */ foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) { if ( 'FORM' === $element->node_name && 'html' === $element->namespace ) { $fragment_processor->state->form_element = clone $element; $fragment_processor->state->form_element->bookmark_name = null; $fragment_processor->state->form_element->on_destroy = null; break; } } $fragment_processor->state->encoding_confidence = 'irrelevant'; /* * Update the parsing namespace near the end of the process. * This is important so that any push/pop from the stack of open * elements does not change the parsing namespace. */ $fragment_processor->change_parsing_namespace( $this->current_element->token->integration_node_type ? 'html' : $namespace ); return $fragment_processor; } /** * Stops the parser and terminates its execution when encountering unsupported markup. * * @throws WP_HTML_Unsupported_Exception Halts execution of the parser. * * @since 6.7.0 * * @param string $message Explains support is missing in order to parse the current node. */ private function bail( string $message ) { $here = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $token = substr( $this->html, $here->start, $here->length ); $open_elements = array(); foreach ( $this->state->stack_of_open_elements->stack as $item ) { $open_elements[] = $item->node_name; } $active_formats = array(); foreach ( $this->state->active_formatting_elements->walk_down() as $item ) { $active_formats[] = $item->node_name; } $this->last_error = self::ERROR_UNSUPPORTED; $this->unsupported_exception = new WP_HTML_Unsupported_Exception( $message, $this->state->current_token->node_name, $here->start, $token, $open_elements, $active_formats ); throw $this->unsupported_exception; } /** * Returns the last error, if any. * * Various situations lead to parsing failure but this class will * return `false` in all those cases. To determine why something * failed it's possible to request the last error. This can be * helpful to know to distinguish whether a given tag couldn't * be found or if content in the document caused the processor * to give up and abort processing. * * Example * * $processor = WP_HTML_Processor::create_fragment( '<template><strong><button><em><p><em>' ); * false === $processor->next_tag(); * WP_HTML_Processor::ERROR_UNSUPPORTED === $processor->get_last_error(); * * @since 6.4.0 * * @see self::ERROR_UNSUPPORTED * @see self::ERROR_EXCEEDED_MAX_BOOKMARKS * * @return string|null The last error, if one exists, otherwise null. */ public function get_last_error(): ?string { return $this->last_error; } /** * Returns context for why the parser aborted due to unsupported HTML, if it did. * * This is meant for debugging purposes, not for production use. * * @since 6.7.0 * * @see self::$unsupported_exception * * @return WP_HTML_Unsupported_Exception|null */ public function get_unsupported_exception() { return $this->unsupported_exception; } /** * Finds the next tag matching the $query. * * @todo Support matching the class name and tag name. * * @since 6.4.0 * @since 6.6.0 Visits all tokens, including virtual ones. * * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document. * * @param array|string|null $query { * Optional. Which tag name to find, having which class, etc. Default is to find any tag. * * @type string|null $tag_name Which tag to find, or `null` for "any tag." * @type string $tag_closers 'visit' to pause at tag closers, 'skip' or unset to only visit openers. * @type int|null $match_offset Find the Nth tag matching all search criteria. * 1 for "first" tag, 3 for "third," etc. * Defaults to first tag. * @type string|null $class_name Tag must contain this whole class name to match. * @type string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`. * May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`. * } * @return bool Whether a tag was matched. */ public function next_tag( $query = null ): bool { $visit_closers = isset( $query['tag_closers'] ) && 'visit' === $query['tag_closers']; if ( null === $query ) { while ( $this->next_token() ) { if ( '#tag' !== $this->get_token_type() ) { continue; } if ( ! $this->is_tag_closer() || $visit_closers ) { return true; } } return false; } if ( is_string( $query ) ) { $query = array( 'breadcrumbs' => array( $query ) ); } if ( ! is_array( $query ) ) { _doing_it_wrong( __METHOD__, __( 'Please pass a query array to this function.' ), '6.4.0' ); return false; } if ( isset( $query['tag_name'] ) ) { $query['tag_name'] = strtoupper( $query['tag_name'] ); } $needs_class = ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) ) ? $query['class_name'] : null; if ( ! ( array_key_exists( 'breadcrumbs', $query ) && is_array( $query['breadcrumbs'] ) ) ) { while ( $this->next_token() ) { if ( '#tag' !== $this->get_token_type() ) { continue; } if ( isset( $query['tag_name'] ) && $query['tag_name'] !== $this->get_token_name() ) { continue; } if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) { continue; } if ( ! $this->is_tag_closer() || $visit_closers ) { return true; } } return false; } $breadcrumbs = $query['breadcrumbs']; $match_offset = isset( $query['match_offset'] ) ? (int) $query['match_offset'] : 1; while ( $match_offset > 0 && $this->next_token() ) { if ( '#tag' !== $this->get_token_type() || $this->is_tag_closer() ) { continue; } if ( isset( $needs_class ) && ! $this->has_class( $needs_class ) ) { continue; } if ( $this->matches_breadcrumbs( $breadcrumbs ) && 0 === --$match_offset ) { return true; } } return false; } /** * Finds the next token in the HTML document. * * This doesn't currently have a way to represent non-tags and doesn't process * semantic rules for text nodes. For access to the raw tokens consider using * WP_HTML_Tag_Processor instead. * * @since 6.5.0 Added for internal support; do not use. * @since 6.7.2 Refactored so subclasses may extend. * * @return bool Whether a token was parsed. */ public function next_token(): bool { return $this->next_visitable_token(); } /** * Ensures internal accounting is maintained for HTML semantic rules while * the underlying Tag Processor class is seeking to a bookmark. * * This doesn't currently have a way to represent non-tags and doesn't process * semantic rules for text nodes. For access to the raw tokens consider using * WP_HTML_Tag_Processor instead. * * Note that this method may call itself recursively. This is why it is not * implemented as {@see WP_HTML_Processor::next_token()}, which instead calls * this method similarly to how {@see WP_HTML_Tag_Processor::next_token()} * calls the {@see WP_HTML_Tag_Processor::base_class_next_token()} method. * * @since 6.7.2 Added for internal support. * * @access private * * @return bool */ private function next_visitable_token(): bool { $this->current_element = null; if ( isset( $this->last_error ) ) { return false; } /* * Prime the events if there are none. * * @todo In some cases, probably related to the adoption agency * algorithm, this call to step() doesn't create any new * events. Calling it again creates them. Figure out why * this is and if it's inherent or if it's a bug. Looping * until there are events or until there are no more * tokens works in the meantime and isn't obviously wrong. */ if ( empty( $this->element_queue ) && $this->step() ) { return $this->next_visitable_token(); } // Process the next event on the queue. $this->current_element = array_shift( $this->element_queue ); if ( ! isset( $this->current_element ) ) { // There are no tokens left, so close all remaining open elements. while ( $this->state->stack_of_open_elements->pop() ) { continue; } return empty( $this->element_queue ) ? false : $this->next_visitable_token(); } $is_pop = WP_HTML_Stack_Event::POP === $this->current_element->operation; /* * The root node only exists in the fragment parser, and closing it * indicates that the parse is complete. Stop before popping it from * the breadcrumbs. */ if ( 'root-node' === $this->current_element->token->bookmark_name ) { return $this->next_visitable_token(); } // Adjust the breadcrumbs for this event. if ( $is_pop ) { array_pop( $this->breadcrumbs ); } else { $this->breadcrumbs[] = $this->current_element->token->node_name; } // Avoid sending close events for elements which don't expect a closing. if ( $is_pop && ! $this->expects_closer( $this->current_element->token ) ) { return $this->next_visitable_token(); } return true; } /** * Indicates if the current tag token is a tag closer. * * Example: * * $p = WP_HTML_Processor::create_fragment( '<div></div>' ); * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); * $p->is_tag_closer() === false; * * $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) ); * $p->is_tag_closer() === true; * * @since 6.6.0 Subclassed for HTML Processor. * * @return bool Whether the current tag is a tag closer. */ public function is_tag_closer(): bool { return $this->is_virtual() ? ( WP_HTML_Stack_Event::POP === $this->current_element->operation && '#tag' === $this->get_token_type() ) : parent::is_tag_closer(); } /** * Indicates if the currently-matched token is virtual, created by a stack operation * while processing HTML, rather than a token found in the HTML text itself. * * @since 6.6.0 * * @return bool Whether the current token is virtual. */ private function is_virtual(): bool { return ( isset( $this->current_element->provenance ) && 'virtual' === $this->current_element->provenance ); } /** * Indicates if the currently-matched tag matches the given breadcrumbs. * * A "*" represents a single tag wildcard, where any tag matches, but not no tags. * * At some point this function _may_ support a `**` syntax for matching any number * of unspecified tags in the breadcrumb stack. This has been intentionally left * out, however, to keep this function simple and to avoid introducing backtracking, * which could open up surprising performance breakdowns. * * Example: * * $processor = WP_HTML_Processor::create_fragment( '<div><span><figure><img></figure></span></div>' ); * $processor->next_tag( 'img' ); * true === $processor->matches_breadcrumbs( array( 'figure', 'img' ) ); * true === $processor->matches_breadcrumbs( array( 'span', 'figure', 'img' ) ); * false === $processor->matches_breadcrumbs( array( 'span', 'img' ) ); * true === $processor->matches_breadcrumbs( array( 'span', '*', 'img' ) ); * * @since 6.4.0 * * @param string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`. * May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`. * @return bool Whether the currently-matched tag is found at the given nested structure. */ public function matches_breadcrumbs( $breadcrumbs ): bool { // Everything matches when there are zero constraints. if ( 0 === count( $breadcrumbs ) ) { return true; } // Start at the last crumb. $crumb = end( $breadcrumbs ); if ( '*' !== $crumb && $this->get_tag() !== strtoupper( $crumb ) ) { return false; } for ( $i = count( $this->breadcrumbs ) - 1; $i >= 0; $i-- ) { $node = $this->breadcrumbs[ $i ]; $crumb = strtoupper( current( $breadcrumbs ) ); if ( '*' !== $crumb && $node !== $crumb ) { return false; } if ( false === prev( $breadcrumbs ) ) { return true; } } return false; } /** * Indicates if the currently-matched node expects a closing * token, or if it will self-close on the next step. * * Most HTML elements expect a closer, such as a P element or * a DIV element. Others, like an IMG element are void and don't * have a closing tag. Special elements, such as SCRIPT and STYLE, * are treated just like void tags. Text nodes and self-closing * foreign content will also act just like a void tag, immediately * closing as soon as the processor advances to the next token. * * @since 6.6.0 * * @param WP_HTML_Token|null $node Optional. Node to examine, if provided. * Default is to examine current node. * @return bool|null Whether to expect a closer for the currently-matched node, * or `null` if not matched on any token. */ public function expects_closer( ?WP_HTML_Token $node = null ): ?bool { $token_name = $node->node_name ?? $this->get_token_name(); if ( ! isset( $token_name ) ) { return null; } $token_namespace = $node->namespace ?? $this->get_namespace(); $token_has_self_closing = $node->has_self_closing_flag ?? $this->has_self_closing_flag(); return ! ( // Comments, text nodes, and other atomic tokens. '#' === $token_name[0] || // Doctype declarations. 'html' === $token_name || // Void elements. ( 'html' === $token_namespace && self::is_void( $token_name ) ) || // Special atomic elements. ( 'html' === $token_namespace && in_array( $token_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) || // Self-closing elements in foreign content. ( 'html' !== $token_namespace && $token_has_self_closing ) ); } /** * Steps through the HTML document and stop at the next tag, if any. * * @since 6.4.0 * * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document. * * @see self::PROCESS_NEXT_NODE * @see self::REPROCESS_CURRENT_NODE * * @param string $node_to_process Whether to parse the next node or reprocess the current node. * @return bool Whether a tag was matched. */ public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool { // Refuse to proceed if there was a previous error. if ( null !== $this->last_error ) { return false; } if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) { /* * Void elements still hop onto the stack of open elements even though * there's no corresponding closing tag. This is important for managing * stack-based operations such as "navigate to parent node" or checking * on an element's breadcrumbs. * * When moving on to the next node, therefore, if the bottom-most element * on the stack is a void element, it must be closed. */ $top_node = $this->state->stack_of_open_elements->current_node(); if ( isset( $top_node ) && ! $this->expects_closer( $top_node ) ) { $this->state->stack_of_open_elements->pop(); } } if ( self::PROCESS_NEXT_NODE === $node_to_process ) { parent::next_token(); if ( WP_HTML_Tag_Processor::STATE_TEXT_NODE === $this->parser_state ) { parent::subdivide_text_appropriately(); } } // Finish stepping when there are no more tokens in the document. if ( WP_HTML_Tag_Processor::STATE_INCOMPLETE_INPUT === $this->parser_state || WP_HTML_Tag_Processor::STATE_COMPLETE === $this->parser_state ) { return false; } $adjusted_current_node = $this->get_adjusted_current_node(); $is_closer = $this->is_tag_closer(); $is_start_tag = WP_HTML_Tag_Processor::STATE_MATCHED_TAG === $this->parser_state && ! $is_closer; $token_name = $this->get_token_name(); if ( self::REPROCESS_CURRENT_NODE !== $node_to_process ) { $this->state->current_token = new WP_HTML_Token( $this->bookmark_token(), $token_name, $this->has_self_closing_flag(), $this->release_internal_bookmark_on_destruct ); } $parse_in_current_insertion_mode = ( 0 === $this->state->stack_of_open_elements->count() || 'html' === $adjusted_current_node->namespace || ( 'math' === $adjusted_current_node->integration_node_type && ( ( $is_start_tag && ! in_array( $token_name, array( 'MGLYPH', 'MALIGNMARK' ), true ) ) || '#text' === $token_name ) ) || ( 'math' === $adjusted_current_node->namespace && 'ANNOTATION-XML' === $adjusted_current_node->node_name && $is_start_tag && 'SVG' === $token_name ) || ( 'html' === $adjusted_current_node->integration_node_type && ( $is_start_tag || '#text' === $token_name ) ) ); try { if ( ! $parse_in_current_insertion_mode ) { return $this->step_in_foreign_content(); } switch ( $this->state->insertion_mode ) { case WP_HTML_Processor_State::INSERTION_MODE_INITIAL: return $this->step_initial(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML: return $this->step_before_html(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD: return $this->step_before_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD: return $this->step_in_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT: return $this->step_in_head_noscript(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD: return $this->step_after_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY: return $this->step_in_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: return $this->step_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT: return $this->step_in_table_text(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: return $this->step_in_caption(); case WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP: return $this->step_in_column_group(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: return $this->step_in_table_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: return $this->step_in_row(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: return $this->step_in_cell(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: return $this->step_in_select(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE: return $this->step_in_select_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE: return $this->step_in_template(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY: return $this->step_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET: return $this->step_in_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET: return $this->step_after_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY: return $this->step_after_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET: return $this->step_after_after_frameset(); // This should be unreachable but PHP doesn't have total type checking on switch. default: $this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." ); } } catch ( WP_HTML_Unsupported_Exception $e ) { /* * Exceptions are used in this class to escape deep call stacks that * otherwise might involve messier calling and return conventions. */ return false; } } /** * Computes the HTML breadcrumbs for the currently-matched node, if matched. * * Breadcrumbs start at the outermost parent and descend toward the matched element. * They always include the entire path from the root HTML node to the matched element. * * Example: * * $processor = WP_HTML_Processor::create_fragment( '<p><strong><em><img></em></strong></p>' ); * $processor->next_tag( 'IMG' ); * $processor->get_breadcrumbs() === array( 'HTML', 'BODY', 'P', 'STRONG', 'EM', 'IMG' ); * * @since 6.4.0 * * @return string[] Array of tag names representing path to matched node. */ public function get_breadcrumbs(): array { return $this->breadcrumbs; } /** * Returns the nesting depth of the current location in the document. * * Example: * * $processor = WP_HTML_Processor::create_fragment( '<div><p></p></div>' ); * // The processor starts in the BODY context, meaning it has depth from the start: HTML > BODY. * 2 === $processor->get_current_depth(); * * // Opening the DIV element increases the depth. * $processor->next_token(); * 3 === $processor->get_current_depth(); * * // Opening the P element increases the depth. * $processor->next_token(); * 4 === $processor->get_current_depth(); * * // The P element is closed during `next_token()` so the depth is decreased to reflect that. * $processor->next_token(); * 3 === $processor->get_current_depth(); * * @since 6.6.0 * * @return int Nesting-depth of current location in the document. */ public function get_current_depth(): int { return count( $this->breadcrumbs ); } /** * Normalizes an HTML fragment by serializing it. * * This method assumes that the given HTML snippet is found in BODY context. * For normalizing full documents or fragments found in other contexts, create * a new processor using {@see WP_HTML_Processor::create_fragment} or * {@see WP_HTML_Processor::create_full_parser} and call {@see WP_HTML_Processor::serialize} * on the created instances. * * Many aspects of an input HTML fragment may be changed during normalization. * * - Attribute values will be double-quoted. * - Duplicate attributes will be removed. * - Omitted tags will be added. * - Tag and attribute name casing will be lower-cased, * except for specific SVG and MathML tags or attributes. * - Text will be re-encoded, null bytes handled, * and invalid UTF-8 replaced with U+FFFD. * - Any incomplete syntax trailing at the end will be omitted, * for example, an unclosed comment opener will be removed. * * Example: * * echo WP_HTML_Processor::normalize( '<a href=#anchor v=5 href="/" enabled>One</a another v=5><!--' ); * // <a href="#anchor" v="5" enabled>One</a> * * echo WP_HTML_Processor::normalize( '<div></p>fun<table><td>cell</div>' ); * // <div><p></p>fun<table><tbody><tr><td>cell</td></tr></tbody></table></div> * * echo WP_HTML_Processor::normalize( '<![CDATA[invalid comment]]> syntax < <> "oddities"' ); * // <!--[CDATA[invalid comment]]--> syntax < <> "oddities" * * @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 { return static::create_fragment( $html )->serialize(); } /** * Returns normalized HTML for a fragment by serializing it. * * This differs from {@see WP_HTML_Processor::normalize} in that it starts with * a specific HTML Processor, which _must_ not have already started scanning; * it must be in the initial ready state and will be in the completed state once * serialization is complete. * * Many aspects of an input HTML fragment may be changed during normalization. * * - Attribute values will be double-quoted. * - Duplicate attributes will be removed. * - Omitted tags will be added. * - Tag and attribute name casing will be lower-cased, * except for specific SVG and MathML tags or attributes. * - Text will be re-encoded, null bytes handled, * and invalid UTF-8 replaced with U+FFFD. * - Any incomplete syntax trailing at the end will be omitted, * for example, an unclosed comment opener will be removed. * * Example: * * $processor = WP_HTML_Processor::create_fragment( '<a href=#anchor v=5 href="/" enabled>One</a another v=5><!--' ); * echo $processor->serialize(); * // <a href="#anchor" v="5" enabled>One</a> * * $processor = WP_HTML_Processor::create_fragment( '<div></p>fun<table><td>cell</div>' ); * echo $processor->serialize(); * // <div><p></p>fun<table><tbody><tr><td>cell</td></tr></tbody></table></div> * * $processor = WP_HTML_Processor::create_fragment( '<![CDATA[invalid comment]]> syntax < <> "oddities"' ); * echo $processor->serialize(); * // <!--[CDATA[invalid comment]]--> syntax < <> "oddities" * * @since 6.7.0 * * @return string|null Normalized HTML markup represented by processor, * or `null` if unable to generate serialization. */ public function serialize(): ?string { if ( WP_HTML_Tag_Processor::STATE_READY !== $this->parser_state ) { wp_trigger_error( __METHOD__, 'An HTML Processor which has already started processing cannot serialize its contents. Serialize immediately after creating the instance.', E_USER_WARNING ); return null; } $html = ''; while ( $this->next_token() ) { $html .= $this->serialize_token(); } if ( null !== $this->get_last_error() ) { wp_trigger_error( __METHOD__, "Cannot serialize HTML Processor with parsing error: {$this->get_last_error()}.", E_USER_WARNING ); return null; } return $html; } /** * Serializes the currently-matched token. * * This method produces a fully-normative HTML string for the currently-matched token, * if able. If not matched at any token or if the token doesn't correspond to any HTML * it will return an empty string (for example, presumptuous end tags are ignored). * * @see static::serialize() * * @since 6.7.0 * * @return string Serialization of token, or empty string if no serialization exists. */ protected function serialize_token(): string { $html = ''; $token_type = $this->get_token_type(); switch ( $token_type ) { case '#doctype': $doctype = $this->get_doctype_info(); if ( null === $doctype ) { break; } $html .= '<!DOCTYPE'; if ( $doctype->name ) { $html .= " {$doctype->name}"; } if ( null !== $doctype->public_identifier ) { $quote = str_contains( $doctype->public_identifier, '"' ) ? "'" : '"'; $html .= " PUBLIC {$quote}{$doctype->public_identifier}{$quote}"; } if ( null !== $doctype->system_identifier ) { if ( null === $doctype->public_identifier ) { $html .= ' SYSTEM'; } $quote = str_contains( $doctype->system_identifier, '"' ) ? "'" : '"'; $html .= " {$quote}{$doctype->system_identifier}{$quote}"; } $html .= '>'; break; case '#text': $html .= htmlspecialchars( $this->get_modifiable_text(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8' ); break; // Unlike the `<>` which is interpreted as plaintext, this is ignored entirely. case '#presumptuous-tag': break; case '#funky-comment': case '#comment': $html .= "<!--{$this->get_full_comment_text()}-->"; break; case '#cdata-section': $html .= "<![CDATA[{$this->get_modifiable_text()}]]>"; break; } if ( '#tag' !== $token_type ) { return $html; } $tag_name = str_replace( "\x00", "\u{FFFD}", $this->get_tag() ); $in_html = 'html' === $this->get_namespace(); $qualified_name = $in_html ? strtolower( $tag_name ) : $this->get_qualified_tag_name(); if ( $this->is_tag_closer() ) { $html .= "</{$qualified_name}>"; return $html; } $attribute_names = $this->get_attribute_names_with_prefix( '' ); if ( ! isset( $attribute_names ) ) { $html .= "<{$qualified_name}>"; return $html; } $html .= "<{$qualified_name}"; foreach ( $attribute_names as $attribute_name ) { $html .= " {$this->get_qualified_attribute_name( $attribute_name )}"; $value = $this->get_attribute( $attribute_name ); if ( is_string( $value ) ) { $html .= '="' . htmlspecialchars( $value, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5 ) . '"'; } $html = str_replace( "\x00", "\u{FFFD}", $html ); } if ( ! $in_html && $this->has_self_closing_flag() ) { $html .= ' /'; } $html .= '>'; // Flush out self-contained elements. if ( $in_html && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) { $text = $this->get_modifiable_text(); switch ( $tag_name ) { case 'IFRAME': case 'NOEMBED': case 'NOFRAMES': $text = ''; break; case 'SCRIPT': case 'STYLE': break; default: $text = htmlspecialchars( $text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8' ); } $html .= "{$text}</{$qualified_name}>"; } return $html; } /** * Parses next element in the 'initial' insertion mode. * * This internal function performs the 'initial' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-initial-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_initial(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * * Parse error: ignore the token. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto initial_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': $doctype = $this->get_doctype_info(); if ( null !== $doctype && 'quirks' === $doctype->indicated_compatability_mode ) { $this->compat_mode = WP_HTML_Tag_Processor::QUIRKS_MODE; } /* * > Then, switch the insertion mode to "before html". */ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML; $this->insert_html_element( $this->state->current_token ); return true; } /* * > Anything else */ initial_anything_else: $this->compat_mode = WP_HTML_Tag_Processor::QUIRKS_MODE; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'before html' insertion mode. * * This internal function performs the 'before html' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-before-html-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_before_html(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * * Parse error: ignore the token. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto before_html_anything_else; break; /* * > A start tag whose tag name is "html" */ case '+HTML': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return true; /* * > An end tag whose tag name is one of: "head", "body", "html", "br" * * Closing BR tags are always reported by the Tag Processor as opening tags. */ case '-HEAD': case '-BODY': case '-HTML': /* * > Act as described in the "anything else" entry below. */ goto before_html_anything_else; break; } /* * > Any other end tag */ if ( $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > Anything else. * * > Create an html element whose node document is the Document object. * > Append it to the Document object. Put this element in the stack of open elements. * > Switch the insertion mode to "before head", then reprocess the token. */ before_html_anything_else: $this->insert_virtual_node( 'HTML' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'before head' insertion mode. * * This internal function performs the 'before head' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-before-head-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_before_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * * Parse error: ignore the token. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step(); } goto before_head_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is "head" */ case '+HEAD': $this->insert_html_element( $this->state->current_token ); $this->state->head_element = $this->state->current_token; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return true; /* * > An end tag whose tag name is one of: "head", "body", "html", "br" * > Act as described in the "anything else" entry below. * * Closing BR tags are always reported by the Tag Processor as opening tags. */ case '-HEAD': case '-BODY': case '-HTML': goto before_head_anything_else; break; } if ( $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > Anything else * * > Insert an HTML element for a "head" start tag token with no attributes. */ before_head_anything_else: $this->state->head_element = $this->insert_virtual_node( 'HEAD' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'in head' insertion mode. * * This internal function performs the 'in head' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { // Insert the character. $this->insert_html_element( $this->state->current_token ); return true; } goto in_head_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is one of: "base", "basefont", "bgsound", "link" */ case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "meta" */ case '+META': $this->insert_html_element( $this->state->current_token ); /* * > If the active speculative HTML parser is null, then: * > - If the element has a charset attribute, and getting an encoding from * > its value results in an encoding, and the confidence is currently * > tentative, then change the encoding to the resulting encoding. */ $charset = $this->get_attribute( 'charset' ); if ( is_string( $charset ) && 'tentative' === $this->state->encoding_confidence ) { $this->bail( 'Cannot yet process META tags with charset to determine encoding.' ); } /* * > - Otherwise, if the element has an http-equiv attribute whose value is * > an ASCII case-insensitive match for the string "Content-Type", and * > the element has a content attribute, and applying the algorithm for * > extracting a character encoding from a meta element to that attribute's * > value returns an encoding, and the confidence is currently tentative, * > then change the encoding to the extracted encoding. */ $http_equiv = $this->get_attribute( 'http-equiv' ); $content = $this->get_attribute( 'content' ); if ( is_string( $http_equiv ) && is_string( $content ) && 0 === strcasecmp( $http_equiv, 'Content-Type' ) && 'tentative' === $this->state->encoding_confidence ) { $this->bail( 'Cannot yet process META tags with http-equiv Content-Type to determine encoding.' ); } return true; /* * > A start tag whose tag name is "title" */ case '+TITLE': $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "noscript", if the scripting flag is enabled * > A start tag whose tag name is one of: "noframes", "style" * * The scripting flag is never enabled in this parser. */ case '+NOFRAMES': case '+STYLE': $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "noscript", if the scripting flag is disabled */ case '+NOSCRIPT': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT; return true; /* * > A start tag whose tag name is "script" * * @todo Could the adjusted insertion location be anything other than the current location? */ case '+SCRIPT': $this->insert_html_element( $this->state->current_token ); return true; /* * > An end tag whose tag name is "head" */ case '-HEAD': $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; return true; /* * > An end tag whose tag name is one of: "body", "html", "br" * * BR tags are always reported by the Tag Processor as opening tags. */ case '-BODY': case '-HTML': /* * > Act as described in the "anything else" entry below. */ goto in_head_anything_else; break; /* * > A start tag whose tag name is "template" * * @todo Could the adjusted insertion location be anything other than the current location? */ case '+TEMPLATE': $this->state->active_formatting_elements->insert_marker(); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; $this->insert_html_element( $this->state->current_token ); return true; /* * > An end tag whose tag name is "template" */ case '-TEMPLATE': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { // @todo Indicate a parse error once it's possible. return $this->step(); } $this->generate_implied_end_tags_thoroughly(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'TEMPLATE' ) ) { // @todo Indicate a parse error once it's possible. } $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); array_pop( $this->state->stack_of_template_insertion_modes ); $this->reset_insertion_mode_appropriately(); return true; } /* * > A start tag whose tag name is "head" * > Any other end tag */ if ( '+HEAD' === $op || $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > Anything else */ in_head_anything_else: $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'in head noscript' insertion mode. * * This internal function performs the 'in head noscript' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-inheadnoscript * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_head_noscript(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * * Parse error: ignore the token. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_head(); } goto in_head_noscript_anything_else; break; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > An end tag whose tag name is "noscript" */ case '-NOSCRIPT': $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return true; /* * > A comment token * > * > A start tag whose tag name is one of: "basefont", "bgsound", * > "link", "meta", "noframes", "style" */ case '#comment': case '#funky-comment': case '#presumptuous-tag': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+STYLE': return $this->step_in_head(); /* * > An end tag whose tag name is "br" * * This should never happen, as the Tag Processor prevents showing a BR closing tag. */ } /* * > A start tag whose tag name is one of: "head", "noscript" * > Any other end tag */ if ( '+HEAD' === $op || '+NOSCRIPT' === $op || $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > Anything else * * Anything here is a parse error. */ in_head_noscript_anything_else: $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'after head' insertion mode. * * This internal function performs the 'after head' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-after-head-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_after_head(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = parent::is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, * > U+000A LINE FEED (LF), U+000C FORM FEED (FF), * > U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { // Insert the character. $this->insert_html_element( $this->state->current_token ); return true; } goto after_head_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is "body" */ case '+BODY': $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return true; /* * > A start tag whose tag name is "frameset" */ case '+FRAMESET': $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET; return true; /* * > A start tag whose tag name is one of: "base", "basefont", "bgsound", * > "link", "meta", "noframes", "script", "style", "template", "title" * * Anything here is a parse error. */ case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': /* * > Push the node pointed to by the head element pointer onto the stack of open elements. * > Process the token using the rules for the "in head" insertion mode. * > Remove the node pointed to by the head element pointer from the stack of open elements. (It might not be the current node at this point.) */ $this->bail( 'Cannot process elements after HEAD which reopen the HEAD element.' ); /* * Do not leave this break in when adding support; it's here to prevent * WPCS from getting confused at the switch structure without a return, * because it doesn't know that `bail()` always throws. */ break; /* * > An end tag whose tag name is "template" */ case '-TEMPLATE': return $this->step_in_head(); /* * > An end tag whose tag name is one of: "body", "html", "br" * * Closing BR tags are always reported by the Tag Processor as opening tags. */ case '-BODY': case '-HTML': /* * > Act as described in the "anything else" entry below. */ goto after_head_anything_else; break; } /* * > A start tag whose tag name is "head" * > Any other end tag */ if ( '+HEAD' === $op || $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > Anything else * > Insert an HTML element for a "body" start tag token with no attributes. */ after_head_anything_else: $this->insert_virtual_node( 'BODY' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'in body' insertion mode. * * This internal function performs the 'in body' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.4.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-inbody * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_body(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { case '#text': /* * > A character token that is U+0000 NULL * * Any successive sequence of NULL bytes is ignored and won't * trigger active format reconstruction. Therefore, if the text * only comprises NULL bytes then the token should be ignored * here, but if there are any other characters in the stream * the active formats should be reconstructed. */ if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { // Parse error: ignore the token. return $this->step(); } $this->reconstruct_active_formatting_elements(); /* * Whitespace-only text does not affect the frameset-ok flag. * It is probably inter-element whitespace, but it may also * contain character references which decode only to whitespace. */ if ( parent::TEXT_IS_GENERIC === $this->text_node_classification ) { $this->state->frameset_ok = false; } $this->insert_html_element( $this->state->current_token ); return true; case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token * > Parse error. Ignore the token. */ case 'html': return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { /* * > Otherwise, for each attribute on the token, check to see if the attribute * > is already present on the top element of the stack of open elements. If * > it is not, add the attribute and its corresponding value to that element. * * This parser does not currently support this behavior: ignore the token. */ } // Ignore the token. return $this->step(); /* * > A start tag whose tag name is one of: "base", "basefont", "bgsound", "link", * > "meta", "noframes", "script", "style", "template", "title" * > * > An end tag whose tag name is "template" */ case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': case '-TEMPLATE': return $this->step_in_head(); /* * > A start tag whose tag name is "body" * * This tag in the IN BODY insertion mode is a parse error. */ case '+BODY': if ( 1 === $this->state->stack_of_open_elements->count() || 'BODY' !== ( $this->state->stack_of_open_elements->at( 2 )->node_name ?? null ) || $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { // Ignore the token. return $this->step(); } /* * > Otherwise, set the frameset-ok flag to "not ok"; then, for each attribute * > on the token, check to see if the attribute is already present on the body * > element (the second element) on the stack of open elements, and if it is * > not, add the attribute and its corresponding value to that element. * * This parser does not currently support this behavior: ignore the token. */ $this->state->frameset_ok = false; return $this->step(); /* * > A start tag whose tag name is "frameset" * * This tag in the IN BODY insertion mode is a parse error. */ case '+FRAMESET': if ( 1 === $this->state->stack_of_open_elements->count() || 'BODY' !== ( $this->state->stack_of_open_elements->at( 2 )->node_name ?? null ) || false === $this->state->frameset_ok ) { // Ignore the token. return $this->step(); } /* * > Otherwise, run the following steps: */ $this->bail( 'Cannot process non-ignored FRAMESET tags.' ); break; /* * > An end tag whose tag name is "body" */ case '-BODY': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'BODY' ) ) { // Parse error: ignore the token. return $this->step(); } /* * > Otherwise, if there is a node in the stack of open elements that is not either a * > dd element, a dt element, an li element, an optgroup element, an option element, * > a p element, an rb element, an rp element, an rt element, an rtc element, a tbody * > element, a td element, a tfoot element, a th element, a thread element, a tr * > element, the body element, or the html element, then this is a parse error. * * There is nothing to do for this parse error, so don't check for it. */ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY; /* * The BODY element is not removed from the stack of open elements. * Only internal state has changed, this does not qualify as a "step" * in terms of advancing through the document to another token. * Nothing has been pushed or popped. * Proceed to parse the next item. */ return $this->step(); /* * > An end tag whose tag name is "html" */ case '-HTML': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'BODY' ) ) { // Parse error: ignore the token. return $this->step(); } /* * > Otherwise, if there is a node in the stack of open elements that is not either a * > dd element, a dt element, an li element, an optgroup element, an option element, * > a p element, an rb element, an rp element, an rt element, an rtc element, a tbody * > element, a td element, a tfoot element, a th element, a thread element, a tr * > element, the body element, or the html element, then this is a parse error. * * There is nothing to do for this parse error, so don't check for it. */ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is one of: "address", "article", "aside", * > "blockquote", "center", "details", "dialog", "dir", "div", "dl", * > "fieldset", "figcaption", "figure", "footer", "header", "hgroup", * > "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul" */ case '+ADDRESS': case '+ARTICLE': case '+ASIDE': case '+BLOCKQUOTE': case '+CENTER': case '+DETAILS': case '+DIALOG': case '+DIR': case '+DIV': case '+DL': case '+FIELDSET': case '+FIGCAPTION': case '+FIGURE': case '+FOOTER': case '+HEADER': case '+HGROUP': case '+MAIN': case '+MENU': case '+NAV': case '+OL': case '+P': case '+SEARCH': case '+SECTION': case '+SUMMARY': case '+UL': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is one of: "h1", "h2", "h3", "h4", "h5", "h6" */ case '+H1': case '+H2': case '+H3': case '+H4': case '+H5': case '+H6': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } if ( in_array( $this->state->stack_of_open_elements->current_node()->node_name, array( 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ), true ) ) { // @todo Indicate a parse error once it's possible. $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is one of: "pre", "listing" */ case '+PRE': case '+LISTING': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } /* * > If the next token is a U+000A LINE FEED (LF) character token, * > then ignore that token and move on to the next one. (Newlines * > at the start of pre blocks are ignored as an authoring convenience.) * * This is handled in `get_modifiable_text()`. */ $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; /* * > A start tag whose tag name is "form" */ case '+FORM': $stack_contains_template = $this->state->stack_of_open_elements->contains( 'TEMPLATE' ); if ( isset( $this->state->form_element ) && ! $stack_contains_template ) { // Parse error: ignore the token. return $this->step(); } if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); if ( ! $stack_contains_template ) { $this->state->form_element = $this->state->current_token; } return true; /* * > A start tag whose tag name is "li" * > A start tag whose tag name is one of: "dd", "dt" */ case '+DD': case '+DT': case '+LI': $this->state->frameset_ok = false; $node = $this->state->stack_of_open_elements->current_node(); $is_li = 'LI' === $token_name; in_body_list_loop: /* * The logic for LI and DT/DD is the same except for one point: LI elements _only_ * close other LI elements, but a DT or DD element closes _any_ open DT or DD element. */ if ( $is_li ? 'LI' === $node->node_name : ( 'DD' === $node->node_name || 'DT' === $node->node_name ) ) { $node_name = $is_li ? 'LI' : $node->node_name; $this->generate_implied_end_tags( $node_name ); if ( ! $this->state->stack_of_open_elements->current_node_is( $node_name ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. } $this->state->stack_of_open_elements->pop_until( $node_name ); goto in_body_list_done; } if ( 'ADDRESS' !== $node->node_name && 'DIV' !== $node->node_name && 'P' !== $node->node_name && self::is_special( $node ) ) { /* * > If node is in the special category, but is not an address, div, * > or p element, then jump to the step labeled done below. */ goto in_body_list_done; } else { /* * > Otherwise, set node to the previous entry in the stack of open elements * > and return to the step labeled loop. */ foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $item ) { $node = $item; break; } goto in_body_list_loop; } in_body_list_done: if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); return true; case '+PLAINTEXT': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } /* * @todo This may need to be handled in the Tag Processor and turn into * a single self-contained tag like TEXTAREA, whose modifiable text * is the rest of the input document as plaintext. */ $this->bail( 'Cannot process PLAINTEXT elements.' ); break; /* * > A start tag whose tag name is "button" */ case '+BUTTON': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'BUTTON' ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. $this->generate_implied_end_tags(); $this->state->stack_of_open_elements->pop_until( 'BUTTON' ); } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; /* * > An end tag whose tag name is one of: "address", "article", "aside", "blockquote", * > "button", "center", "details", "dialog", "dir", "div", "dl", "fieldset", * > "figcaption", "figure", "footer", "header", "hgroup", "listing", "main", * > "menu", "nav", "ol", "pre", "search", "section", "summary", "ul" */ case '-ADDRESS': case '-ARTICLE': case '-ASIDE': case '-BLOCKQUOTE': case '-BUTTON': case '-CENTER': case '-DETAILS': case '-DIALOG': case '-DIR': case '-DIV': case '-DL': case '-FIELDSET': case '-FIGCAPTION': case '-FIGURE': case '-FOOTER': case '-HEADER': case '-HGROUP': case '-LISTING': case '-MAIN': case '-MENU': case '-NAV': case '-OL': case '-PRE': case '-SEARCH': case '-SECTION': case '-SUMMARY': case '-UL': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) { // @todo Report parse error. // Ignore the token. return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Record parse error: this error doesn't impact parsing. } $this->state->stack_of_open_elements->pop_until( $token_name ); return true; /* * > An end tag whose tag name is "form" */ case '-FORM': if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { $node = $this->state->form_element; $this->state->form_element = null; /* * > If node is null or if the stack of open elements does not have node * > in scope, then this is a parse error; return and ignore the token. * * @todo It's necessary to check if the form token itself is in scope, not * simply whether any FORM is in scope. */ if ( null === $node || ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) { // Parse error: ignore the token. return $this->step(); } $this->generate_implied_end_tags(); if ( $node !== $this->state->stack_of_open_elements->current_node() ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. $this->bail( 'Cannot close a FORM when other elements remain open as this would throw off the breadcrumbs for the following tokens.' ); } $this->state->stack_of_open_elements->remove_node( $node ); return true; } else { /* * > If the stack of open elements does not have a form element in scope, * > then this is a parse error; return and ignore the token. * * Note that unlike in the clause above, this is checking for any FORM in scope. */ if ( ! $this->state->stack_of_open_elements->has_element_in_scope( 'FORM' ) ) { // Parse error: ignore the token. return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'FORM' ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. } $this->state->stack_of_open_elements->pop_until( 'FORM' ); return true; } break; /* * > An end tag whose tag name is "p" */ case '-P': if ( ! $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->insert_html_element( $this->state->current_token ); } $this->close_a_p_element(); return true; /* * > An end tag whose tag name is "li" * > An end tag whose tag name is one of: "dd", "dt" */ case '-DD': case '-DT': case '-LI': if ( /* * An end tag whose tag name is "li": * If the stack of open elements does not have an li element in list item scope, * then this is a parse error; ignore the token. */ ( 'LI' === $token_name && ! $this->state->stack_of_open_elements->has_element_in_list_item_scope( 'LI' ) ) || /* * An end tag whose tag name is one of: "dd", "dt": * If the stack of open elements does not have an element in scope that is an * HTML element with the same tag name as that of the token, then this is a * parse error; ignore the token. */ ( 'LI' !== $token_name && ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) ) { /* * This is a parse error, ignore the token. * * @todo Indicate a parse error once it's possible. */ return $this->step(); } $this->generate_implied_end_tags( $token_name ); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Indicate a parse error once it's possible. This error does not impact the logic here. } $this->state->stack_of_open_elements->pop_until( $token_name ); return true; /* * > An end tag whose tag name is one of: "h1", "h2", "h3", "h4", "h5", "h6" */ case '-H1': case '-H2': case '-H3': case '-H4': case '-H5': case '-H6': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( '(internal: H1 through H6 - do not use)' ) ) { /* * This is a parse error; ignore the token. * * @todo Indicate a parse error once it's possible. */ return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // @todo Record parse error: this error doesn't impact parsing. } $this->state->stack_of_open_elements->pop_until( '(internal: H1 through H6 - do not use)' ); return true; /* * > A start tag whose tag name is "a" */ case '+A': foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { switch ( $item->node_name ) { case 'marker': break 2; case 'A': $this->run_adoption_agency_algorithm(); $this->state->active_formatting_elements->remove_node( $item ); $this->state->stack_of_open_elements->remove_node( $item ); break 2; } } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; /* * > A start tag whose tag name is one of: "b", "big", "code", "em", "font", "i", * > "s", "small", "strike", "strong", "tt", "u" */ case '+B': case '+BIG': case '+CODE': case '+EM': case '+FONT': case '+I': case '+S': case '+SMALL': case '+STRIKE': case '+STRONG': case '+TT': case '+U': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; /* * > A start tag whose tag name is "nobr" */ case '+NOBR': $this->reconstruct_active_formatting_elements(); if ( $this->state->stack_of_open_elements->has_element_in_scope( 'NOBR' ) ) { // Parse error. $this->run_adoption_agency_algorithm(); $this->reconstruct_active_formatting_elements(); } $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->push( $this->state->current_token ); return true; /* * > An end tag whose tag name is one of: "a", "b", "big", "code", "em", "font", "i", * > "nobr", "s", "small", "strike", "strong", "tt", "u" */ case '-A': case '-B': case '-BIG': case '-CODE': case '-EM': case '-FONT': case '-I': case '-NOBR': case '-S': case '-SMALL': case '-STRIKE': case '-STRONG': case '-TT': case '-U': $this->run_adoption_agency_algorithm(); return true; /* * > A start tag whose tag name is one of: "applet", "marquee", "object" */ case '+APPLET': case '+MARQUEE': case '+OBJECT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->active_formatting_elements->insert_marker(); $this->state->frameset_ok = false; return true; /* * > A end tag token whose tag name is one of: "applet", "marquee", "object" */ case '-APPLET': case '-MARQUEE': case '-OBJECT': if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $token_name ) ) { // Parse error: ignore the token. return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( $token_name ) ) { // This is a parse error. } $this->state->stack_of_open_elements->pop_until( $token_name ); $this->state->active_formatting_elements->clear_up_to_last_marker(); return true; /* * > A start tag whose tag name is "table" */ case '+TABLE': /* * > If the Document is not set to quirks mode, and the stack of open elements * > has a p element in button scope, then close a p element. */ if ( WP_HTML_Tag_Processor::QUIRKS_MODE !== $this->compat_mode && $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; /* * > An end tag whose tag name is "br" * * This is prevented from happening because the Tag Processor * reports all closing BR tags as if they were opening tags. */ /* * > A start tag whose tag name is one of: "area", "br", "embed", "img", "keygen", "wbr" */ case '+AREA': case '+BR': case '+EMBED': case '+IMG': case '+KEYGEN': case '+WBR': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; /* * > A start tag whose tag name is "input" */ case '+INPUT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); /* * > If the token does not have an attribute with the name "type", or if it does, * > but that attribute's value is not an ASCII case-insensitive match for the * > string "hidden", then: set the frameset-ok flag to "not ok". */ $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { $this->state->frameset_ok = false; } return true; /* * > A start tag whose tag name is one of: "param", "source", "track" */ case '+PARAM': case '+SOURCE': case '+TRACK': $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "hr" */ case '+HR': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; return true; /* * > A start tag whose tag name is "image" */ case '+IMAGE': /* * > Parse error. Change the token's tag name to "img" and reprocess it. (Don't ask.) * * Note that this is handled elsewhere, so it should not be possible to reach this code. */ $this->bail( "Cannot process an IMAGE tag. (Don't ask.)" ); break; /* * > A start tag whose tag name is "textarea" */ case '+TEXTAREA': $this->insert_html_element( $this->state->current_token ); /* * > If the next token is a U+000A LINE FEED (LF) character token, then ignore * > that token and move on to the next one. (Newlines at the start of * > textarea elements are ignored as an authoring convenience.) * * This is handled in `get_modifiable_text()`. */ $this->state->frameset_ok = false; /* * > Switch the insertion mode to "text". * * As a self-contained node, this behavior is handled in the Tag Processor. */ return true; /* * > A start tag whose tag name is "xmp" */ case '+XMP': if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { $this->close_a_p_element(); } $this->reconstruct_active_formatting_elements(); $this->state->frameset_ok = false; /* * > Follow the generic raw text element parsing algorithm. * * As a self-contained node, this behavior is handled in the Tag Processor. */ $this->insert_html_element( $this->state->current_token ); return true; /* * A start tag whose tag name is "iframe" */ case '+IFRAME': $this->state->frameset_ok = false; /* * > Follow the generic raw text element parsing algorithm. * * As a self-contained node, this behavior is handled in the Tag Processor. */ $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "noembed" * > A start tag whose tag name is "noscript", if the scripting flag is enabled * * The scripting flag is never enabled in this parser. */ case '+NOEMBED': $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "select" */ case '+SELECT': $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; switch ( $this->state->insertion_mode ) { /* * > If the insertion mode is one of "in table", "in caption", "in table body", "in row", * > or "in cell", then switch the insertion mode to "in select in table". */ case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; break; /* * > Otherwise, switch the insertion mode to "in select". */ default: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; break; } return true; /* * > A start tag whose tag name is one of: "optgroup", "option" */ case '+OPTGROUP': case '+OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is one of: "rb", "rtc" */ case '+RB': case '+RTC': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'RUBY' ) ) { $this->generate_implied_end_tags(); if ( $this->state->stack_of_open_elements->current_node_is( 'RUBY' ) ) { // @todo Indicate a parse error once it's possible. } } $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is one of: "rp", "rt" */ case '+RP': case '+RT': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'RUBY' ) ) { $this->generate_implied_end_tags( 'RTC' ); $current_node_name = $this->state->stack_of_open_elements->current_node()->node_name; if ( 'RTC' === $current_node_name || 'RUBY' === $current_node_name ) { // @todo Indicate a parse error once it's possible. } } $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "math" */ case '+MATH': $this->reconstruct_active_formatting_elements(); /* * @todo Adjust MathML attributes for the token. (This fixes the case of MathML attributes that are not all lowercase.) * @todo Adjust foreign attributes for the token. (This fixes the use of namespaced attributes, in particular XLink.) * * These ought to be handled in the attribute methods. */ $this->state->current_token->namespace = 'math'; $this->insert_html_element( $this->state->current_token ); if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; /* * > A start tag whose tag name is "svg" */ case '+SVG': $this->reconstruct_active_formatting_elements(); /* * @todo Adjust SVG attributes for the token. (This fixes the case of SVG attributes that are not all lowercase.) * @todo Adjust foreign attributes for the token. (This fixes the use of namespaced attributes, in particular XLink in SVG.) * * These ought to be handled in the attribute methods. */ $this->state->current_token->namespace = 'svg'; $this->insert_html_element( $this->state->current_token ); if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; /* * > A start tag whose tag name is one of: "caption", "col", "colgroup", * > "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr" */ case '+CAPTION': case '+COL': case '+COLGROUP': case '+FRAME': case '+HEAD': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': // Parse error. Ignore the token. return $this->step(); } if ( ! parent::is_tag_closer() ) { /* * > Any other start tag */ $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; } else { /* * > Any other end tag */ /* * Find the corresponding tag opener in the stack of open elements, if * it exists before reaching a special element, which provides a kind * of boundary in the stack. For example, a `</custom-tag>` should not * close anything beyond its containing `P` or `DIV` element. */ foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { if ( 'html' === $node->namespace && $token_name === $node->node_name ) { break; } if ( self::is_special( $node ) ) { // This is a parse error, ignore the token. return $this->step(); } } $this->generate_implied_end_tags( $token_name ); if ( $node !== $this->state->stack_of_open_elements->current_node() ) { // @todo Record parse error: this error doesn't impact parsing. } foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $node === $item ) { return true; } } } $this->bail( 'Should not have been able to reach end of IN BODY processing. Check HTML API code.' ); // This unnecessary return prevents tools from inaccurately reporting type errors. return false; } /** * Parses next element in the 'in table' insertion mode. * * This internal function performs the 'in table' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intable * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_table(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token, if the current node is table, * > tbody, template, tfoot, thead, or tr element */ case '#text': $current_node = $this->state->stack_of_open_elements->current_node(); $current_node_name = $current_node ? $current_node->node_name : null; if ( $current_node_name && ( 'TABLE' === $current_node_name || 'TBODY' === $current_node_name || 'TEMPLATE' === $current_node_name || 'TFOOT' === $current_node_name || 'THEAD' === $current_node_name || 'TR' === $current_node_name ) ) { /* * If the text is empty after processing HTML entities and stripping * U+0000 NULL bytes then ignore the token. */ if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { return $this->step(); } /* * This follows the rules for "in table text" insertion mode. * * Whitespace-only text nodes are inserted in-place. Otherwise * foster parenting is enabled and the nodes would be * inserted out-of-place. * * > If any of the tokens in the pending table character tokens * > list are character tokens that are not ASCII whitespace, * > then this is a parse error: reprocess the character tokens * > in the pending table character tokens list using the rules * > given in the "anything else" entry in the "in table" * > insertion mode. * > * > Otherwise, insert the characters given by the pending table * > character tokens list. * * @see https://html.spec.whatwg.org/#parsing-main-intabletext */ if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { $this->insert_html_element( $this->state->current_token ); return true; } // Non-whitespace would trigger fostering, unsupported at this time. $this->bail( 'Foster parenting is not supported.' ); break; } break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "caption" */ case '+CAPTION': $this->state->stack_of_open_elements->clear_to_table_context(); $this->state->active_formatting_elements->insert_marker(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; return true; /* * > A start tag whose tag name is "colgroup" */ case '+COLGROUP': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return true; /* * > A start tag whose tag name is "col" */ case '+COL': $this->state->stack_of_open_elements->clear_to_table_context(); /* * > Insert an HTML element for a "colgroup" start tag token with no attributes, * > then switch the insertion mode to "in column group". */ $this->insert_virtual_node( 'COLGROUP' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ case '+TBODY': case '+TFOOT': case '+THEAD': $this->state->stack_of_open_elements->clear_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return true; /* * > A start tag whose tag name is one of: "td", "th", "tr" */ case '+TD': case '+TH': case '+TR': $this->state->stack_of_open_elements->clear_to_table_context(); /* * > Insert an HTML element for a "tbody" start tag token with no attributes, * > then switch the insertion mode to "in table body". */ $this->insert_virtual_node( 'TBODY' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is "table" * * This tag in the IN TABLE insertion mode is a parse error. */ case '+TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'TABLE' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is "table" */ case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { // @todo Indicate a parse error once it's possible. return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'TABLE' ); $this->reset_insertion_mode_appropriately(); return true; /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TBODY': case '-TD': case '-TFOOT': case '-TH': case '-THEAD': case '-TR': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is one of: "style", "script", "template" * > An end tag whose tag name is "template" */ case '+STYLE': case '+SCRIPT': case '+TEMPLATE': case '-TEMPLATE': /* * > Process the token using the rules for the "in head" insertion mode. */ return $this->step_in_head(); /* * > A start tag whose tag name is "input" * * > If the token does not have an attribute with the name "type", or if it does, but * > that attribute's value is not an ASCII case-insensitive match for the string * > "hidden", then: act as described in the "anything else" entry below. */ case '+INPUT': $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { goto anything_else; } // @todo Indicate a parse error once it's possible. $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "form" * * This tag in the IN TABLE insertion mode is a parse error. */ case '+FORM': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) || isset( $this->state->form_element ) ) { return $this->step(); } // This FORM is special because it immediately closes and cannot have other children. $this->insert_html_element( $this->state->current_token ); $this->state->form_element = $this->state->current_token; $this->state->stack_of_open_elements->pop(); return true; } /* * > Anything else * > Parse error. Enable foster parenting, process the token using the rules for the * > "in body" insertion mode, and then disable foster parenting. * * @todo Indicate a parse error once it's possible. */ anything_else: $this->bail( 'Foster parenting is not supported.' ); } /** * Parses next element in the 'in table text' insertion mode. * * This internal function performs the 'in table text' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intabletext * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_table_text(): bool { $this->bail( 'No support for parsing in the ' . WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT . ' state.' ); } /** * Parses next element in the 'in caption' insertion mode. * * This internal function performs the 'in caption' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-incaption * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_caption(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > An end tag whose tag name is "caption" * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr" * > An end tag whose tag name is "table" * * These tag handling rules are identical except for the final instruction. * Handle them in a single block. */ case '-CAPTION': case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'CAPTION' ) ) { // Parse error: ignore the token. return $this->step(); } $this->generate_implied_end_tags(); if ( ! $this->state->stack_of_open_elements->current_node_is( 'CAPTION' ) ) { // @todo Indicate a parse error once it's possible. } $this->state->stack_of_open_elements->pop_until( 'CAPTION' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; // If this is not a CAPTION end tag, the token should be reprocessed. if ( '-CAPTION' === $op ) { return true; } return $this->step( self::REPROCESS_CURRENT_NODE ); /** * > An end tag whose tag name is one of: "body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ case '-BODY': case '-COL': case '-COLGROUP': case '-HTML': case '-TBODY': case '-TD': case '-TFOOT': case '-TH': case '-THEAD': case '-TR': // Parse error: ignore the token. return $this->step(); } /** * > Anything else * > Process the token using the rules for the "in body" insertion mode. */ return $this->step_in_body(); } /** * Parses next element in the 'in column group' insertion mode. * * This internal function performs the 'in column group' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-incolgroup * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_column_group(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { // Insert the character. $this->insert_html_element( $this->state->current_token ); return true; } goto in_column_group_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // @todo Indicate a parse error once it's possible. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is "col" */ case '+COL': $this->insert_html_element( $this->state->current_token ); $this->state->stack_of_open_elements->pop(); return true; /* * > An end tag whose tag name is "colgroup" */ case '-COLGROUP': if ( ! $this->state->stack_of_open_elements->current_node_is( 'COLGROUP' ) ) { // @todo Indicate a parse error once it's possible. return $this->step(); } $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; /* * > An end tag whose tag name is "col" */ case '-COL': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "template" * > An end tag whose tag name is "template" */ case '+TEMPLATE': case '-TEMPLATE': return $this->step_in_head(); } in_column_group_anything_else: /* * > Anything else */ if ( ! $this->state->stack_of_open_elements->current_node_is( 'COLGROUP' ) ) { // @todo Indicate a parse error once it's possible. return $this->step(); } $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'in table body' insertion mode. * * This internal function performs the 'in table body' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intbody * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_table_body(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A start tag whose tag name is "tr" */ case '+TR': $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return true; /* * > A start tag whose tag name is one of: "th", "td" */ case '+TH': case '+TD': // @todo Indicate a parse error once it's possible. $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->insert_virtual_node( 'TR' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ case '-TBODY': case '-TFOOT': case '-THEAD': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { // Parse error: ignore the token. return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; /* * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "tfoot", "thead" * > An end tag whose tag name is "table" */ case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TBODY' ) && ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'THEAD' ) && ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TFOOT' ) ) { // Parse error: ignore the token. return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_body_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "td", "th", "tr" */ case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TD': case '-TH': case '-TR': // Parse error: ignore the token. return $this->step(); } /* * > Anything else * > Process the token using the rules for the "in table" insertion mode. */ return $this->step_in_table(); } /** * Parses next element in the 'in row' insertion mode. * * This internal function performs the 'in row' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intr * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_row(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A start tag whose tag name is one of: "th", "td" */ case '+TH': case '+TD': $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL; $this->state->active_formatting_elements->insert_marker(); return true; /* * > An end tag whose tag name is "tr" */ case '-TR': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { // Parse error: ignore the token. return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return true; /* * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr" * > An end tag whose tag name is "table" */ case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': case '+TR': case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { // Parse error: ignore the token. return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ case '-TBODY': case '-TFOOT': case '-THEAD': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { // Parse error: ignore the token. return $this->step(); } if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { // Ignore the token. return $this->step(); } $this->state->stack_of_open_elements->clear_to_table_row_context(); $this->state->stack_of_open_elements->pop(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "td", "th" */ case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': case '-TD': case '-TH': // Parse error: ignore the token. return $this->step(); } /* * > Anything else * > Process the token using the rules for the "in table" insertion mode. */ return $this->step_in_table(); } /** * Parses next element in the 'in cell' insertion mode. * * This internal function performs the 'in cell' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intd * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_cell(): bool { $tag_name = $this->get_tag(); $op_sigil = $this->is_tag_closer() ? '-' : '+'; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > An end tag whose tag name is one of: "td", "th" */ case '-TD': case '-TH': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { // Parse error: ignore the token. return $this->step(); } $this->generate_implied_end_tags(); /* * @todo This needs to check if the current node is an HTML element, meaning that * when SVG and MathML support is added, this needs to differentiate between an * HTML element of the given name, such as `<center>`, and a foreign element of * the same given name. */ if ( ! $this->state->stack_of_open_elements->current_node_is( $tag_name ) ) { // @todo Indicate a parse error once it's possible. } $this->state->stack_of_open_elements->pop_until( $tag_name ); $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return true; /* * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "td", * > "tfoot", "th", "thead", "tr" */ case '+CAPTION': case '+COL': case '+COLGROUP': case '+TBODY': case '+TD': case '+TFOOT': case '+TH': case '+THEAD': case '+TR': /* * > Assert: The stack of open elements has a td or th element in table scope. * * Nothing to do here, except to verify in tests that this never appears. */ $this->close_cell(); return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html" */ case '-BODY': case '-CAPTION': case '-COL': case '-COLGROUP': case '-HTML': // Parse error: ignore the token. return $this->step(); /* * > An end tag whose tag name is one of: "table", "tbody", "tfoot", "thead", "tr" */ case '-TABLE': case '-TBODY': case '-TFOOT': case '-THEAD': case '-TR': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { // Parse error: ignore the token. return $this->step(); } $this->close_cell(); return $this->step( self::REPROCESS_CURRENT_NODE ); } /* * > Anything else * > Process the token using the rules for the "in body" insertion mode. */ return $this->step_in_body(); } /** * Parses next element in the 'in select' insertion mode. * * This internal function performs the 'in select' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselect * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_select(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > Any other character token */ case '#text': /* * > A character token that is U+0000 NULL * * If a text node only comprises null bytes then it should be * entirely ignored and should not return to calling code. */ if ( parent::TEXT_IS_NULL_SEQUENCE === $this->text_node_classification ) { // Parse error: ignore the token. return $this->step(); } $this->insert_html_element( $this->state->current_token ); return true; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is "option" */ case '+OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; /* * > A start tag whose tag name is "optgroup" * > A start tag whose tag name is "hr" * * These rules are identical except for the treatment of the self-closing flag and * the subsequent pop of the HR void element, all of which is handled elsewhere in the processor. */ case '+OPTGROUP': case '+HR': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); } if ( $this->state->stack_of_open_elements->current_node_is( 'OPTGROUP' ) ) { $this->state->stack_of_open_elements->pop(); } $this->insert_html_element( $this->state->current_token ); return true; /* * > An end tag whose tag name is "optgroup" */ case '-OPTGROUP': $current_node = $this->state->stack_of_open_elements->current_node(); if ( $current_node && 'OPTION' === $current_node->node_name ) { foreach ( $this->state->stack_of_open_elements->walk_up( $current_node ) as $parent ) { break; } if ( $parent && 'OPTGROUP' === $parent->node_name ) { $this->state->stack_of_open_elements->pop(); } } if ( $this->state->stack_of_open_elements->current_node_is( 'OPTGROUP' ) ) { $this->state->stack_of_open_elements->pop(); return true; } // Parse error: ignore the token. return $this->step(); /* * > An end tag whose tag name is "option" */ case '-OPTION': if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) { $this->state->stack_of_open_elements->pop(); return true; } // Parse error: ignore the token. return $this->step(); /* * > An end tag whose tag name is "select" * > A start tag whose tag name is "select" * * > It just gets treated like an end tag. */ case '-SELECT': case '+SELECT': if ( ! $this->state->stack_of_open_elements->has_element_in_select_scope( 'SELECT' ) ) { // Parse error: ignore the token. return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return true; /* * > A start tag whose tag name is one of: "input", "keygen", "textarea" * * All three of these tags are considered a parse error when found in this insertion mode. */ case '+INPUT': case '+KEYGEN': case '+TEXTAREA': if ( ! $this->state->stack_of_open_elements->has_element_in_select_scope( 'SELECT' ) ) { // Ignore the token. return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is one of: "script", "template" * > An end tag whose tag name is "template" */ case '+SCRIPT': case '+TEMPLATE': case '-TEMPLATE': return $this->step_in_head(); } /* * > Anything else * > Parse error: ignore the token. */ return $this->step(); } /** * Parses next element in the 'in select in table' insertion mode. * * This internal function performs the 'in select in table' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-inselectintable * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_select_in_table(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A start tag whose tag name is one of: "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" */ case '+CAPTION': case '+TABLE': case '+TBODY': case '+TFOOT': case '+THEAD': case '+TR': case '+TD': case '+TH': // @todo Indicate a parse error once it's possible. $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th" */ case '-CAPTION': case '-TABLE': case '-TBODY': case '-TFOOT': case '-THEAD': case '-TR': case '-TD': case '-TH': // @todo Indicate a parse error once it's possible. if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $token_name ) ) { return $this->step(); } $this->state->stack_of_open_elements->pop_until( 'SELECT' ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); } /* * > Anything else */ return $this->step_in_select(); } /** * Parses next element in the 'in template' insertion mode. * * This internal function performs the 'in template' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-intemplate * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_template(): bool { $token_name = $this->get_token_name(); $token_type = $this->get_token_type(); $is_closer = $this->is_tag_closer(); $op_sigil = '#tag' === $token_type ? ( $is_closer ? '-' : '+' ) : ''; $op = "{$op_sigil}{$token_name}"; switch ( $op ) { /* * > A character token * > A comment token * > A DOCTYPE token */ case '#text': case '#comment': case '#funky-comment': case '#presumptuous-tag': case 'html': return $this->step_in_body(); /* * > A start tag whose tag name is one of: "base", "basefont", "bgsound", "link", * > "meta", "noframes", "script", "style", "template", "title" * > An end tag whose tag name is "template" */ case '+BASE': case '+BASEFONT': case '+BGSOUND': case '+LINK': case '+META': case '+NOFRAMES': case '+SCRIPT': case '+STYLE': case '+TEMPLATE': case '+TITLE': case '-TEMPLATE': return $this->step_in_head(); /* * > A start tag whose tag name is one of: "caption", "colgroup", "tbody", "tfoot", "thead" */ case '+CAPTION': case '+COLGROUP': case '+TBODY': case '+TFOOT': case '+THEAD': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is "col" */ case '+COL': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is "tr" */ case '+TR': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > A start tag whose tag name is one of: "td", "th" */ case '+TD': case '+TH': array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return $this->step( self::REPROCESS_CURRENT_NODE ); } /* * > Any other start tag */ if ( ! $is_closer ) { array_pop( $this->state->stack_of_template_insertion_modes ); $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } /* * > Any other end tag */ if ( $is_closer ) { // Parse error: ignore the token. return $this->step(); } /* * > An end-of-file token */ if ( ! $this->state->stack_of_open_elements->contains( 'TEMPLATE' ) ) { // Stop parsing. return false; } // @todo Indicate a parse error once it's possible. $this->state->stack_of_open_elements->pop_until( 'TEMPLATE' ); $this->state->active_formatting_elements->clear_up_to_last_marker(); array_pop( $this->state->stack_of_template_insertion_modes ); $this->reset_insertion_mode_appropriately(); return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'after body' insertion mode. * * This internal function performs the 'after body' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-afterbody * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_after_body(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * * > Process the token using the rules for the "in body" insertion mode. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } goto after_body_anything_else; break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of BODY is unsupported.' ); break; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > An end tag whose tag name is "html" * * > If the parser was created as part of the HTML fragment parsing algorithm, * > this is a parse error; ignore the token. (fragment case) * > * > Otherwise, switch the insertion mode to "after after body". */ case '-HTML': if ( isset( $this->context_node ) ) { return $this->step(); } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY; /* * The HTML element is not removed from the stack of open elements. * Only internal state has changed, this does not qualify as a "step" * in terms of advancing through the document to another token. * Nothing has been pushed or popped. * Proceed to parse the next item. */ return $this->step(); } /* * > Parse error. Switch the insertion mode to "in body" and reprocess the token. */ after_body_anything_else: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'in frameset' insertion mode. * * This internal function performs the 'in frameset' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-inframeset * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * > * > Insert the character. * * This algorithm effectively strips non-whitespace characters from text and inserts * them under HTML. This is not supported at this time. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in frameset.' ); break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > A start tag whose tag name is "frameset" */ case '+FRAMESET': $this->insert_html_element( $this->state->current_token ); return true; /* * > An end tag whose tag name is "frameset" */ case '-FRAMESET': /* * > If the current node is the root html element, then this is a parse error; * > ignore the token. (fragment case) */ if ( $this->state->stack_of_open_elements->current_node_is( 'HTML' ) ) { return $this->step(); } /* * > Otherwise, pop the current node from the stack of open elements. */ $this->state->stack_of_open_elements->pop(); /* * > If the parser was not created as part of the HTML fragment parsing algorithm * > (fragment case), and the current node is no longer a frameset element, then * > switch the insertion mode to "after frameset". */ if ( ! isset( $this->context_node ) && ! $this->state->stack_of_open_elements->current_node_is( 'FRAMESET' ) ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET; } return true; /* * > A start tag whose tag name is "frame" * * > Insert an HTML element for the token. Immediately pop the * > current node off the stack of open elements. * > * > Acknowledge the token's self-closing flag, if it is set. */ case '+FRAME': $this->insert_html_element( $this->state->current_token ); $this->state->stack_of_open_elements->pop(); return true; /* * > A start tag whose tag name is "noframes" */ case '+NOFRAMES': return $this->step_in_head(); } // Parse error: ignore the token. return $this->step(); } /** * Parses next element in the 'after frameset' insertion mode. * * This internal function performs the 'after frameset' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-afterframeset * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_after_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * > * > Insert the character. * * This algorithm effectively strips non-whitespace characters from text and inserts * them under HTML. This is not supported at this time. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in after frameset' ); break; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_html_element( $this->state->current_token ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "html" */ case '+HTML': return $this->step_in_body(); /* * > An end tag whose tag name is "html" */ case '-HTML': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET; /* * The HTML element is not removed from the stack of open elements. * Only internal state has changed, this does not qualify as a "step" * in terms of advancing through the document to another token. * Nothing has been pushed or popped. * Proceed to parse the next item. */ return $this->step(); /* * > A start tag whose tag name is "noframes" */ case '+NOFRAMES': return $this->step_in_head(); } // Parse error: ignore the token. return $this->step(); } /** * Parses next element in the 'after after body' insertion mode. * * This internal function performs the 'after after body' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-after-after-body-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_after_after_body(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of HTML is unsupported.' ); break; /* * > A DOCTYPE token * > A start tag whose tag name is "html" * * > Process the token using the rules for the "in body" insertion mode. */ case 'html': case '+HTML': return $this->step_in_body(); /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * > * > Process the token using the rules for the "in body" insertion mode. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } goto after_after_body_anything_else; break; } /* * > Parse error. Switch the insertion mode to "in body" and reprocess the token. */ after_after_body_anything_else: $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); } /** * Parses next element in the 'after after frameset' insertion mode. * * This internal function performs the 'after after frameset' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#the-after-after-frameset-insertion-mode * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_after_after_frameset(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; switch ( $op ) { /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->bail( 'Content outside of HTML is unsupported.' ); break; /* * > A DOCTYPE token * > A start tag whose tag name is "html" * * > Process the token using the rules for the "in body" insertion mode. */ case 'html': case '+HTML': return $this->step_in_body(); /* * > A character token that is one of U+0009 CHARACTER TABULATION, U+000A LINE FEED (LF), * > U+000C FORM FEED (FF), U+000D CARRIAGE RETURN (CR), or U+0020 SPACE * > * > Process the token using the rules for the "in body" insertion mode. * * This algorithm effectively strips non-whitespace characters from text and inserts * them under HTML. This is not supported at this time. */ case '#text': if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) { return $this->step_in_body(); } $this->bail( 'Non-whitespace characters cannot be handled in after after frameset.' ); break; /* * > A start tag whose tag name is "noframes" */ case '+NOFRAMES': return $this->step_in_head(); } // Parse error: ignore the token. return $this->step(); } /** * Parses next element in the 'in foreign content' insertion mode. * * This internal function performs the 'in foreign content' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * * @since 6.7.0 Stub implementation. * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#parsing-main-inforeign * @see WP_HTML_Processor::step * * @return bool Whether an element was found. */ private function step_in_foreign_content(): bool { $tag_name = $this->get_token_name(); $token_type = $this->get_token_type(); $op_sigil = '#tag' === $token_type ? ( $this->is_tag_closer() ? '-' : '+' ) : ''; $op = "{$op_sigil}{$tag_name}"; /* * > A start tag whose name is "font", if the token has any attributes named "color", "face", or "size" * * This section drawn out above the switch to more easily incorporate * the additional rules based on the presence of the attributes. */ if ( '+FONT' === $op && ( null !== $this->get_attribute( 'color' ) || null !== $this->get_attribute( 'face' ) || null !== $this->get_attribute( 'size' ) ) ) { $op = '+FONT with attributes'; } switch ( $op ) { case '#text': /* * > A character token that is U+0000 NULL * * This is handled by `get_modifiable_text()`. */ /* * Whitespace-only text does not affect the frameset-ok flag. * It is probably inter-element whitespace, but it may also * contain character references which decode only to whitespace. */ if ( parent::TEXT_IS_GENERIC === $this->text_node_classification ) { $this->state->frameset_ok = false; } $this->insert_foreign_element( $this->state->current_token, false ); return true; /* * CDATA sections are alternate wrappers for text content and therefore * ought to follow the same rules as text nodes. */ case '#cdata-section': /* * NULL bytes and whitespace do not change the frameset-ok flag. */ $current_token = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $cdata_content_start = $current_token->start + 9; $cdata_content_length = $current_token->length - 12; if ( strspn( $this->html, "\0 \t\n\f\r", $cdata_content_start, $cdata_content_length ) !== $cdata_content_length ) { $this->state->frameset_ok = false; } $this->insert_foreign_element( $this->state->current_token, false ); return true; /* * > A comment token */ case '#comment': case '#funky-comment': case '#presumptuous-tag': $this->insert_foreign_element( $this->state->current_token, false ); return true; /* * > A DOCTYPE token */ case 'html': // Parse error: ignore the token. return $this->step(); /* * > A start tag whose tag name is "b", "big", "blockquote", "body", "br", "center", * > "code", "dd", "div", "dl", "dt", "em", "embed", "h1", "h2", "h3", "h4", "h5", * > "h6", "head", "hr", "i", "img", "li", "listing", "menu", "meta", "nobr", "ol", * > "p", "pre", "ruby", "s", "small", "span", "strong", "strike", "sub", "sup", * > "table", "tt", "u", "ul", "var" * * > A start tag whose name is "font", if the token has any attributes named "color", "face", or "size" * * > An end tag whose tag name is "br", "p" * * Closing BR tags are always reported by the Tag Processor as opening tags. */ case '+B': case '+BIG': case '+BLOCKQUOTE': case '+BODY': case '+BR': case '+CENTER': case '+CODE': case '+DD': case '+DIV': case '+DL': case '+DT': case '+EM': case '+EMBED': case '+H1': case '+H2': case '+H3': case '+H4': case '+H5': case '+H6': case '+HEAD': case '+HR': case '+I': case '+IMG': case '+LI': case '+LISTING': case '+MENU': case '+META': case '+NOBR': case '+OL': case '+P': case '+PRE': case '+RUBY': case '+S': case '+SMALL': case '+SPAN': case '+STRONG': case '+STRIKE': case '+SUB': case '+SUP': case '+TABLE': case '+TT': case '+U': case '+UL': case '+VAR': case '+FONT with attributes': case '-BR': case '-P': // @todo Indicate a parse error once it's possible. foreach ( $this->state->stack_of_open_elements->walk_up() as $current_node ) { if ( 'math' === $current_node->integration_node_type || 'html' === $current_node->integration_node_type || 'html' === $current_node->namespace ) { break; } $this->state->stack_of_open_elements->pop(); } goto in_foreign_content_process_in_current_insertion_mode; } /* * > Any other start tag */ if ( ! $this->is_tag_closer() ) { $this->insert_foreign_element( $this->state->current_token, false ); /* * > If the token has its self-closing flag set, then run * > the appropriate steps from the following list: * > * > ↪ the token's tag name is "script", and the new current node is in the SVG namespace * > Acknowledge the token's self-closing flag, and then act as * > described in the steps for a "script" end tag below. * > * > ↪ Otherwise * > Pop the current node off the stack of open elements and * > acknowledge the token's self-closing flag. * * Since the rules for SCRIPT below indicate to pop the element off of the stack of * open elements, which is the same for the Otherwise condition, there's no need to * separate these checks. The difference comes when a parser operates with the scripting * flag enabled, and executes the script, which this parser does not support. */ if ( $this->state->current_token->has_self_closing_flag ) { $this->state->stack_of_open_elements->pop(); } return true; } /* * > An end tag whose name is "script", if the current node is an SVG script element. */ if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) { $this->state->stack_of_open_elements->pop(); return true; } /* * > Any other end tag */ if ( $this->is_tag_closer() ) { $node = $this->state->stack_of_open_elements->current_node(); if ( $tag_name !== $node->node_name ) { // @todo Indicate a parse error once it's possible. } in_foreign_content_end_tag_loop: if ( $node === $this->state->stack_of_open_elements->at( 1 ) ) { return true; } /* * > If node's tag name, converted to ASCII lowercase, is the same as the tag name * > of the token, pop elements from the stack of open elements until node has * > been popped from the stack, and then return. */ if ( 0 === strcasecmp( $node->node_name, $tag_name ) ) { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $node === $item ) { return true; } } } foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $item ) { $node = $item; break; } if ( 'html' !== $node->namespace ) { goto in_foreign_content_end_tag_loop; } in_foreign_content_process_in_current_insertion_mode: switch ( $this->state->insertion_mode ) { case WP_HTML_Processor_State::INSERTION_MODE_INITIAL: return $this->step_initial(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML: return $this->step_before_html(); case WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD: return $this->step_before_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD: return $this->step_in_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT: return $this->step_in_head_noscript(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD: return $this->step_after_head(); case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY: return $this->step_in_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: return $this->step_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT: return $this->step_in_table_text(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: return $this->step_in_caption(); case WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP: return $this->step_in_column_group(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: return $this->step_in_table_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: return $this->step_in_row(); case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: return $this->step_in_cell(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: return $this->step_in_select(); case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE: return $this->step_in_select_in_table(); case WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE: return $this->step_in_template(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY: return $this->step_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET: return $this->step_in_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_FRAMESET: return $this->step_after_frameset(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY: return $this->step_after_after_body(); case WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET: return $this->step_after_after_frameset(); // This should be unreachable but PHP doesn't have total type checking on switch. default: $this->bail( "Unaware of the requested parsing mode: '{$this->state->insertion_mode}'." ); } } $this->bail( 'Should not have been able to reach end of IN FOREIGN CONTENT processing. Check HTML API code.' ); // This unnecessary return prevents tools from inaccurately reporting type errors. return false; } /* * Internal helpers */ /** * Creates a new bookmark for the currently-matched token and returns the generated name. * * @since 6.4.0 * @since 6.5.0 Renamed from bookmark_tag() to bookmark_token(). * * @throws Exception When unable to allocate requested bookmark. * * @return string|false Name of created bookmark, or false if unable to create. */ private function bookmark_token() { if ( ! parent::set_bookmark( ++$this->bookmark_counter ) ) { $this->last_error = self::ERROR_EXCEEDED_MAX_BOOKMARKS; throw new Exception( 'could not allocate bookmark' ); } return "{$this->bookmark_counter}"; } /* * HTML semantic overrides for Tag Processor */ /** * Indicates the namespace of the current token, or "html" if there is none. * * @return string One of "html", "math", or "svg". */ public function get_namespace(): string { if ( ! isset( $this->current_element ) ) { return parent::get_namespace(); } return $this->current_element->token->namespace; } /** * Returns the uppercase name of the matched tag. * * The semantic rules for HTML specify that certain tags be reprocessed * with a different tag name. Because of this, the tag name presented * by the HTML Processor may differ from the one reported by the HTML * Tag Processor, which doesn't apply these semantic rules. * * Example: * * $processor = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' ); * $processor->next_tag() === true; * $processor->get_tag() === 'DIV'; * * $processor->next_tag() === false; * $processor->get_tag() === null; * * @since 6.4.0 * * @return string|null Name of currently matched tag in input HTML, or `null` if none found. */ public function get_tag(): ?string { if ( null !== $this->last_error ) { return null; } if ( $this->is_virtual() ) { return $this->current_element->token->node_name; } $tag_name = parent::get_tag(); /* * > A start tag whose tag name is "image" * > Change the token's tag name to "img" and reprocess it. (Don't ask.) */ return ( 'IMAGE' === $tag_name && 'html' === $this->get_namespace() ) ? 'IMG' : $tag_name; } /** * Indicates if the currently matched tag contains the self-closing flag. * * No HTML elements ought to have the self-closing flag and for those, the self-closing * flag will be ignored. For void elements this is benign because they "self close" * automatically. For non-void HTML elements though problems will appear if someone * intends to use a self-closing element in place of that element with an empty body. * For HTML foreign elements and custom elements the self-closing flag determines if * they self-close or not. * * This function does not determine if a tag is self-closing, * but only if the self-closing flag is present in the syntax. * * @since 6.6.0 Subclassed for the HTML Processor. * * @return bool Whether the currently matched tag contains the self-closing flag. */ public function has_self_closing_flag(): bool { return $this->is_virtual() ? false : parent::has_self_closing_flag(); } /** * Returns the node name represented by the token. * * This matches the DOM API value `nodeName`. Some values * are static, such as `#text` for a text node, while others * are dynamically generated from the token itself. * * Dynamic names: * - Uppercase tag name for tag matches. * - `html` for DOCTYPE declarations. * * Note that if the Tag Processor is not matched on a token * then this function will return `null`, either because it * hasn't yet found a token or because it reached the end * of the document without matching a token. * * @since 6.6.0 Subclassed for the HTML Processor. * * @return string|null Name of the matched token. */ public function get_token_name(): ?string { return $this->is_virtual() ? $this->current_element->token->node_name : parent::get_token_name(); } /** * Indicates the kind of matched token, if any. * * This differs from `get_token_name()` in that it always * returns a static string indicating the type, whereas * `get_token_name()` may return values derived from the * token itself, such as a tag name or processing * instruction tag. * * Possible values: * - `#tag` when matched on a tag. * - `#text` when matched on a text node. * - `#cdata-section` when matched on a CDATA node. * - `#comment` when matched on a comment. * - `#doctype` when matched on a DOCTYPE declaration. * - `#presumptuous-tag` when matched on an empty tag closer. * - `#funky-comment` when matched on a funky comment. * * @since 6.6.0 Subclassed for the HTML Processor. * * @return string|null What kind of token is matched, or null. */ public function get_token_type(): ?string { if ( $this->is_virtual() ) { /* * This logic comes from the Tag Processor. * * @todo It would be ideal not to repeat this here, but it's not clearly * better to allow passing a token name to `get_token_type()`. */ $node_name = $this->current_element->token->node_name; $starting_char = $node_name[0]; if ( 'A' <= $starting_char && 'Z' >= $starting_char ) { return '#tag'; } if ( 'html' === $node_name ) { return '#doctype'; } return $node_name; } return parent::get_token_type(); } /** * Returns the value of a requested attribute from a matched tag opener if that attribute exists. * * Example: * * $p = WP_HTML_Processor::create_fragment( '<div enabled class="test" data-test-id="14">Test</div>' ); * $p->next_token() === true; * $p->get_attribute( 'data-test-id' ) === '14'; * $p->get_attribute( 'enabled' ) === true; * $p->get_attribute( 'aria-label' ) === null; * * $p->next_tag() === false; * $p->get_attribute( 'class' ) === null; * * @since 6.6.0 Subclassed for HTML Processor. * * @param string $name Name of attribute whose value is requested. * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`. */ public function get_attribute( $name ) { return $this->is_virtual() ? null : parent::get_attribute( $name ); } /** * Updates or creates a new attribute on the currently matched tag with the passed value. * * For boolean attributes special handling is provided: * - When `true` is passed as the value, then only the attribute name is added to the tag. * - When `false` is passed, the attribute gets removed if it existed before. * * For string attributes, the value is escaped using the `esc_attr` function. * * @since 6.6.0 Subclassed for the HTML Processor. * * @param string $name The attribute name to target. * @param string|bool $value The new attribute value. * @return bool Whether an attribute value was set. */ public function set_attribute( $name, $value ): bool { return $this->is_virtual() ? false : parent::set_attribute( $name, $value ); } /** * Remove an attribute from the currently-matched tag. * * @since 6.6.0 Subclassed for HTML Processor. * * @param string $name The attribute name to remove. * @return bool Whether an attribute was removed. */ public function remove_attribute( $name ): bool { return $this->is_virtual() ? false : parent::remove_attribute( $name ); } /** * Gets lowercase names of all attributes matching a given prefix in the current tag. * * Note that matching is case-insensitive. This is in accordance with the spec: * * > There must never be two or more attributes on * > the same start tag whose names are an ASCII * > case-insensitive match for each other. * - HTML 5 spec * * Example: * * $p = new WP_HTML_Tag_Processor( '<div data-ENABLED class="test" DATA-test-id="14">Test</div>' ); * $p->next_tag( array( 'class_name' => 'test' ) ) === true; * $p->get_attribute_names_with_prefix( 'data-' ) === array( 'data-enabled', 'data-test-id' ); * * $p->next_tag() === false; * $p->get_attribute_names_with_prefix( 'data-' ) === null; * * @since 6.6.0 Subclassed for the HTML Processor. * * @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive * * @param string $prefix Prefix of requested attribute names. * @return array|null List of attribute names, or `null` when no tag opener is matched. */ public function get_attribute_names_with_prefix( $prefix ): ?array { return $this->is_virtual() ? null : parent::get_attribute_names_with_prefix( $prefix ); } /** * Adds a new class name to the currently matched tag. * * @since 6.6.0 Subclassed for the HTML Processor. * * @param string $class_name The class name to add. * @return bool Whether the class was set to be added. */ public function add_class( $class_name ): bool { return $this->is_virtual() ? false : parent::add_class( $class_name ); } /** * Removes a class name from the currently matched tag. * * @since 6.6.0 Subclassed for the HTML Processor. * * @param string $class_name The class name to remove. * @return bool Whether the class was set to be removed. */ public function remove_class( $class_name ): bool { return $this->is_virtual() ? false : parent::remove_class( $class_name ); } /** * Returns if a matched tag contains the given ASCII case-insensitive class name. * * @since 6.6.0 Subclassed for the HTML Processor. * * @todo When reconstructing active formatting elements with attributes, find a way * to indicate if the virtually-reconstructed formatting elements contain the * wanted class name. * * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive. * @return bool|null Whether the matched tag contains the given class name, or null if not matched. */ public function has_class( $wanted_class ): ?bool { return $this->is_virtual() ? null : parent::has_class( $wanted_class ); } /** * Generator for a foreach loop to step through each class name for the matched tag. * * This generator function is designed to be used inside a "foreach" loop. * * Example: * * $p = WP_HTML_Processor::create_fragment( "<div class='free <egg<\tlang-en'>" ); * $p->next_tag(); * foreach ( $p->class_list() as $class_name ) { * echo "{$class_name} "; * } * // Outputs: "free <egg> lang-en " * * @since 6.6.0 Subclassed for the HTML Processor. */ public function class_list() { return $this->is_virtual() ? null : parent::class_list(); } /** * Returns the modifiable text for a matched token, or an empty string. * * Modifiable text is text content that may be read and changed without * changing the HTML structure of the document around it. This includes * the contents of `#text` nodes in the HTML as well as the inner * contents of HTML comments, Processing Instructions, and others, even * though these nodes aren't part of a parsed DOM tree. They also contain * the contents of SCRIPT and STYLE tags, of TEXTAREA tags, and of any * other section in an HTML document which cannot contain HTML markup (DATA). * * If a token has no modifiable text then an empty string is returned to * avoid needless crashing or type errors. An empty string does not mean * that a token has modifiable text, and a token with modifiable text may * have an empty string (e.g. a comment with no contents). * * @since 6.6.0 Subclassed for the HTML Processor. * * @return string */ public function get_modifiable_text(): string { return $this->is_virtual() ? '' : parent::get_modifiable_text(); } /** * Indicates what kind of comment produced the comment node. * * Because there are different kinds of HTML syntax which produce * comments, the Tag Processor tracks and exposes this as a type * for the comment. Nominally only regular HTML comments exist as * they are commonly known, but a number of unrelated syntax errors * also produce comments. * * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT * @see self::COMMENT_AS_CDATA_LOOKALIKE * @see self::COMMENT_AS_INVALID_HTML * @see self::COMMENT_AS_HTML_COMMENT * @see self::COMMENT_AS_PI_NODE_LOOKALIKE * * @since 6.6.0 Subclassed for the HTML Processor. * * @return string|null */ public function get_comment_type(): ?string { return $this->is_virtual() ? null : parent::get_comment_type(); } /** * Removes a bookmark that is no longer needed. * * Releasing a bookmark frees up the small * performance overhead it requires. * * @since 6.4.0 * * @param string $bookmark_name Name of the bookmark to remove. * @return bool Whether the bookmark already existed before removal. */ public function release_bookmark( $bookmark_name ): bool { return parent::release_bookmark( "_{$bookmark_name}" ); } /** * Moves the internal cursor in the HTML Processor to a given bookmark's location. * * Be careful! Seeking backwards to a previous location resets the parser to the * start of the document and reparses the entire contents up until it finds the * sought-after bookmarked location. * * In order to prevent accidental infinite loops, there's a * maximum limit on the number of times seek() can be called. * * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document. * * @since 6.4.0 * * @param string $bookmark_name Jump to the place in the document identified by this bookmark name. * @return bool Whether the internal cursor was successfully moved to the bookmark's location. */ public function seek( $bookmark_name ): bool { // Flush any pending updates to the document before beginning. $this->get_updated_html(); $actual_bookmark_name = "_{$bookmark_name}"; $processor_started_at = $this->state->current_token ? $this->bookmarks[ $this->state->current_token->bookmark_name ]->start : 0; $bookmark_starts_at = $this->bookmarks[ $actual_bookmark_name ]->start; $direction = $bookmark_starts_at > $processor_started_at ? 'forward' : 'backward'; /* * If seeking backwards, it's possible that the sought-after bookmark exists within an element * which has been closed before the current cursor; in other words, it has already been removed * from the stack of open elements. This means that it's insufficient to simply pop off elements * from the stack of open elements which appear after the bookmarked location and then jump to * that location, as the elements which were open before won't be re-opened. * * In order to maintain consistency, the HTML Processor rewinds to the start of the document * and reparses everything until it finds the sought-after bookmark. * * There are potentially better ways to do this: cache the parser state for each bookmark and * restore it when seeking; store an immutable and idempotent register of where elements open * and close. * * If caching the parser state it will be essential to properly maintain the cached stack of * open elements and active formatting elements when modifying the document. This could be a * tedious and time-consuming process as well, and so for now will not be performed. * * It may be possible to track bookmarks for where elements open and close, and in doing so * be able to quickly recalculate breadcrumbs for any element in the document. It may even * be possible to remove the stack of open elements and compute it on the fly this way. * If doing this, the parser would need to track the opening and closing locations for all * tokens in the breadcrumb path for any and all bookmarks. By utilizing bookmarks themselves * this list could be automatically maintained while modifying the document. Finding the * breadcrumbs would then amount to traversing that list from the start until the token * being inspected. Once an element closes, if there are no bookmarks pointing to locations * within that element, then all of these locations may be forgotten to save on memory use * and computation time. */ if ( 'backward' === $direction ) { /* * When moving backward, stateful stacks should be cleared. */ foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->remove_node( $item ); } foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { $this->state->active_formatting_elements->remove_node( $item ); } /* * **After** clearing stacks, more processor state can be reset. * This must be done after clearing the stack because those stacks generate events that * would appear on a subsequent call to `next_token()`. */ $this->state->frameset_ok = true; $this->state->stack_of_template_insertion_modes = array(); $this->state->head_element = null; $this->state->form_element = null; $this->state->current_token = null; $this->current_element = null; $this->element_queue = array(); /* * The absence of a context node indicates a full parse. * The presence of a context node indicates a fragment parser. */ if ( null === $this->context_node ) { $this->change_parsing_namespace( 'html' ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_INITIAL; $this->breadcrumbs = array(); $this->bookmarks['initial'] = new WP_HTML_Span( 0, 0 ); parent::seek( 'initial' ); unset( $this->bookmarks['initial'] ); } else { /* * Push the root-node (HTML) back onto the stack of open elements. * * Fragment parsers require this extra bit of setup. * It's handled in full parsers by advancing the processor state. */ $this->state->stack_of_open_elements->push( new WP_HTML_Token( 'root-node', 'HTML', false ) ); $this->change_parsing_namespace( $this->context_node->integration_node_type ? 'html' : $this->context_node->namespace ); if ( 'TEMPLATE' === $this->context_node->node_name ) { $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE; } $this->reset_insertion_mode_appropriately(); $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 ); parent::seek( $this->context_node->bookmark_name ); } } /* * Here, the processor moves forward through the document until it matches the bookmark. * do-while is used here because the processor is expected to already be stopped on * a token than may match the bookmarked location. */ do { /* * The processor will stop on virtual tokens, but bookmarks may not be set on them. * They should not be matched when seeking a bookmark, skip them. */ if ( $this->is_virtual() ) { continue; } if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) { return true; } } while ( $this->next_token() ); return false; } /** * Sets a bookmark in the HTML document. * * Bookmarks represent specific places or tokens in the HTML * document, such as a tag opener or closer. When applying * edits to a document, such as setting an attribute, the * text offsets of that token may shift; the bookmark is * kept updated with those shifts and remains stable unless * the entire span of text in which the token sits is removed. * * Release bookmarks when they are no longer needed. * * Example: * * <main><h2>Surprising fact you may not know!</h2></main> * ^ ^ * \-|-- this `H2` opener bookmark tracks the token * * <main class="clickbait"><h2>Surprising fact you may no… * ^ ^ * \-|-- it shifts with edits * * Bookmarks provide the ability to seek to a previously-scanned * place in the HTML document. This avoids the need to re-scan * the entire document. * * Example: * * <ul><li>One</li><li>Two</li><li>Three</li></ul> * ^^^^ * want to note this last item * * $p = new WP_HTML_Tag_Processor( $html ); * $in_list = false; * while ( $p->next_tag( array( 'tag_closers' => $in_list ? 'visit' : 'skip' ) ) ) { * if ( 'UL' === $p->get_tag() ) { * if ( $p->is_tag_closer() ) { * $in_list = false; * $p->set_bookmark( 'resume' ); * if ( $p->seek( 'last-li' ) ) { * $p->add_class( 'last-li' ); * } * $p->seek( 'resume' ); * $p->release_bookmark( 'last-li' ); * $p->release_bookmark( 'resume' ); * } else { * $in_list = true; * } * } * * if ( 'LI' === $p->get_tag() ) { * $p->set_bookmark( 'last-li' ); * } * } * * Bookmarks intentionally hide the internal string offsets * to which they refer. They are maintained internally as * updates are applied to the HTML document and therefore * retain their "position" - the location to which they * originally pointed. The inability to use bookmarks with * functions like `substr` is therefore intentional to guard * against accidentally breaking the HTML. * * Because bookmarks allocate memory and require processing * for every applied update, they are limited and require * a name. They should not be created with programmatically-made * names, such as "li_{$index}" with some loop. As a general * rule they should only be created with string-literal names * like "start-of-section" or "last-paragraph". * * Bookmarks are a powerful tool to enable complicated behavior. * Consider double-checking that you need this tool if you are * reaching for it, as inappropriate use could lead to broken * HTML structure or unwanted processing overhead. * * Bookmarks cannot be set on tokens that do no appear in the original * HTML text. For example, the HTML `<table><td>` stops at tags `TABLE`, * `TBODY`, `TR`, and `TD`. The `TBODY` and `TR` tags do not appear in * the original HTML and cannot be used as bookmarks. * * @since 6.4.0 * * @param string $bookmark_name Identifies this particular bookmark. * @return bool Whether the bookmark was successfully created. */ public function set_bookmark( $bookmark_name ): bool { if ( $this->is_virtual() ) { _doing_it_wrong( __METHOD__, __( 'Cannot set bookmarks on tokens that do no appear in the original HTML text.' ), '6.8.0' ); return false; } return parent::set_bookmark( "_{$bookmark_name}" ); } /** * Checks whether a bookmark with the given name exists. * * @since 6.5.0 * * @param string $bookmark_name Name to identify a bookmark that potentially exists. * @return bool Whether that bookmark exists. */ public function has_bookmark( $bookmark_name ): bool { return parent::has_bookmark( "_{$bookmark_name}" ); } /* * HTML Parsing Algorithms */ /** * Closes a P element. * * @since 6.4.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#close-a-p-element */ private function close_a_p_element(): void { $this->generate_implied_end_tags( 'P' ); $this->state->stack_of_open_elements->pop_until( 'P' ); } /** * Closes elements that have implied end tags. * * @since 6.4.0 * @since 6.7.0 Full spec support. * * @see https://html.spec.whatwg.org/#generate-implied-end-tags * * @param string|null $except_for_this_element Perform as if this element doesn't exist in the stack of open elements. */ private function generate_implied_end_tags( ?string $except_for_this_element = null ): void { $elements_with_implied_end_tags = array( 'DD', 'DT', 'LI', 'OPTGROUP', 'OPTION', 'P', 'RB', 'RP', 'RT', 'RTC', ); $no_exclusions = ! isset( $except_for_this_element ); while ( ( $no_exclusions || ! $this->state->stack_of_open_elements->current_node_is( $except_for_this_element ) ) && in_array( $this->state->stack_of_open_elements->current_node()->node_name, $elements_with_implied_end_tags, true ) ) { $this->state->stack_of_open_elements->pop(); } } /** * Closes elements that have implied end tags, thoroughly. * * See the HTML specification for an explanation why this is * different from generating end tags in the normal sense. * * @since 6.4.0 * @since 6.7.0 Full spec support. * * @see WP_HTML_Processor::generate_implied_end_tags * @see https://html.spec.whatwg.org/#generate-implied-end-tags */ private function generate_implied_end_tags_thoroughly(): void { $elements_with_implied_end_tags = array( 'CAPTION', 'COLGROUP', 'DD', 'DT', 'LI', 'OPTGROUP', 'OPTION', 'P', 'RB', 'RP', 'RT', 'RTC', 'TBODY', 'TD', 'TFOOT', 'TH', 'THEAD', 'TR', ); while ( in_array( $this->state->stack_of_open_elements->current_node()->node_name, $elements_with_implied_end_tags, true ) ) { $this->state->stack_of_open_elements->pop(); } } /** * Returns the adjusted current node. * * > The adjusted current node is the context element if the parser was created as * > part of the HTML fragment parsing algorithm and the stack of open elements * > has only one element in it (fragment case); otherwise, the adjusted current * > node is the current node. * * @see https://html.spec.whatwg.org/#adjusted-current-node * * @since 6.7.0 * * @return WP_HTML_Token|null The adjusted current node. */ private function get_adjusted_current_node(): ?WP_HTML_Token { if ( isset( $this->context_node ) && 1 === $this->state->stack_of_open_elements->count() ) { return $this->context_node; } return $this->state->stack_of_open_elements->current_node(); } /** * Reconstructs the active formatting elements. * * > This has the effect of reopening all the formatting elements that were opened * > in the current body, cell, or caption (whichever is youngest) that haven't * > been explicitly closed. * * @since 6.4.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#reconstruct-the-active-formatting-elements * * @return bool Whether any formatting elements needed to be reconstructed. */ private function reconstruct_active_formatting_elements(): bool { /* * > If there are no entries in the list of active formatting elements, then there is nothing * > to reconstruct; stop this algorithm. */ if ( 0 === $this->state->active_formatting_elements->count() ) { return false; } $last_entry = $this->state->active_formatting_elements->current_node(); if ( /* * > If the last (most recently added) entry in the list of active formatting elements is a marker; * > stop this algorithm. */ 'marker' === $last_entry->node_name || /* * > If the last (most recently added) entry in the list of active formatting elements is an * > element that is in the stack of open elements, then there is nothing to reconstruct; * > stop this algorithm. */ $this->state->stack_of_open_elements->contains_node( $last_entry ) ) { return false; } $this->bail( 'Cannot reconstruct active formatting elements when advancing and rewinding is required.' ); } /** * Runs the reset the insertion mode appropriately algorithm. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately */ private function reset_insertion_mode_appropriately(): void { // Set the first node. $first_node = null; foreach ( $this->state->stack_of_open_elements->walk_down() as $first_node ) { break; } /* * > 1. Let _last_ be false. */ $last = false; foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { /* * > 2. Let _node_ be the last node in the stack of open elements. * > 3. _Loop_: If _node_ is the first node in the stack of open elements, then set _last_ * > to true, and, if the parser was created as part of the HTML fragment parsing * > algorithm (fragment case), set node to the context element passed to * > that algorithm. * > … */ if ( $node === $first_node ) { $last = true; if ( isset( $this->context_node ) ) { $node = $this->context_node; } } // All of the following rules are for matching HTML elements. if ( 'html' !== $node->namespace ) { continue; } switch ( $node->node_name ) { /* * > 4. If node is a `select` element, run these substeps: * > 1. If _last_ is true, jump to the step below labeled done. * > 2. Let _ancestor_ be _node_. * > 3. _Loop_: If _ancestor_ is the first node in the stack of open elements, * > jump to the step below labeled done. * > 4. Let ancestor be the node before ancestor in the stack of open elements. * > … * > 7. Jump back to the step labeled _loop_. * > 8. _Done_: Switch the insertion mode to "in select" and return. */ case 'SELECT': if ( ! $last ) { foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $ancestor ) { if ( 'html' !== $ancestor->namespace ) { continue; } switch ( $ancestor->node_name ) { /* * > 5. If _ancestor_ is a `template` node, jump to the step below * > labeled _done_. */ case 'TEMPLATE': break 2; /* * > 6. If _ancestor_ is a `table` node, switch the insertion mode to * > "in select in table" and return. */ case 'TABLE': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; return; } } } $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; return; /* * > 5. If _node_ is a `td` or `th` element and _last_ is false, then switch the * > insertion mode to "in cell" and return. */ case 'TD': case 'TH': if ( ! $last ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL; return; } break; /* * > 6. If _node_ is a `tr` element, then switch the insertion mode to "in row" * > and return. */ case 'TR': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; return; /* * > 7. If _node_ is a `tbody`, `thead`, or `tfoot` element, then switch the * > insertion mode to "in table body" and return. */ case 'TBODY': case 'THEAD': case 'TFOOT': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return; /* * > 8. If _node_ is a `caption` element, then switch the insertion mode to * > "in caption" and return. */ case 'CAPTION': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; return; /* * > 9. If _node_ is a `colgroup` element, then switch the insertion mode to * > "in column group" and return. */ case 'COLGROUP': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; return; /* * > 10. If _node_ is a `table` element, then switch the insertion mode to * > "in table" and return. */ case 'TABLE': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return; /* * > 11. If _node_ is a `template` element, then switch the insertion mode to the * > current template insertion mode and return. */ case 'TEMPLATE': $this->state->insertion_mode = end( $this->state->stack_of_template_insertion_modes ); return; /* * > 12. If _node_ is a `head` element and _last_ is false, then switch the * > insertion mode to "in head" and return. */ case 'HEAD': if ( ! $last ) { $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; return; } break; /* * > 13. If _node_ is a `body` element, then switch the insertion mode to "in body" * > and return. */ case 'BODY': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; return; /* * > 14. If _node_ is a `frameset` element, then switch the insertion mode to * > "in frameset" and return. (fragment case) */ case 'FRAMESET': $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET; return; /* * > 15. If _node_ is an `html` element, run these substeps: * > 1. If the head element pointer is null, switch the insertion mode to * > "before head" and return. (fragment case) * > 2. Otherwise, the head element pointer is not null, switch the insertion * > mode to "after head" and return. */ case 'HTML': $this->state->insertion_mode = isset( $this->state->head_element ) ? WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD : WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; return; } } /* * > 16. If _last_ is true, then switch the insertion mode to "in body" * > and return. (fragment case) * * This is only reachable if `$last` is true, as per the fragment parsing case. */ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; } /** * Runs the adoption agency algorithm. * * @since 6.4.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * * @see https://html.spec.whatwg.org/#adoption-agency-algorithm */ private function run_adoption_agency_algorithm(): void { $budget = 1000; $subject = $this->get_tag(); $current_node = $this->state->stack_of_open_elements->current_node(); if ( // > If the current node is an HTML element whose tag name is subject $current_node && $subject === $current_node->node_name && // > the current node is not in the list of active formatting elements ! $this->state->active_formatting_elements->contains_node( $current_node ) ) { $this->state->stack_of_open_elements->pop(); return; } $outer_loop_counter = 0; while ( $budget-- > 0 ) { if ( $outer_loop_counter++ >= 8 ) { return; } /* * > Let formatting element be the last element in the list of active formatting elements that: * > - is between the end of the list and the last marker in the list, * > if any, or the start of the list otherwise, * > - and has the tag name subject. */ $formatting_element = null; foreach ( $this->state->active_formatting_elements->walk_up() as $item ) { if ( 'marker' === $item->node_name ) { break; } if ( $subject === $item->node_name ) { $formatting_element = $item; break; } } // > If there is no such element, then return and instead act as described in the "any other end tag" entry above. if ( null === $formatting_element ) { $this->bail( 'Cannot run adoption agency when "any other end tag" is required.' ); } // > If formatting element is not in the stack of open elements, then this is a parse error; remove the element from the list, and return. if ( ! $this->state->stack_of_open_elements->contains_node( $formatting_element ) ) { $this->state->active_formatting_elements->remove_node( $formatting_element ); return; } // > If formatting element is in the stack of open elements, but the element is not in scope, then this is a parse error; return. if ( ! $this->state->stack_of_open_elements->has_element_in_scope( $formatting_element->node_name ) ) { return; } /* * > Let furthest block be the topmost node in the stack of open elements that is lower in the stack * > than formatting element, and is an element in the special category. There might not be one. */ $is_above_formatting_element = true; $furthest_block = null; foreach ( $this->state->stack_of_open_elements->walk_down() as $item ) { if ( $is_above_formatting_element && $formatting_element->bookmark_name !== $item->bookmark_name ) { continue; } if ( $is_above_formatting_element ) { $is_above_formatting_element = false; continue; } if ( self::is_special( $item ) ) { $furthest_block = $item; break; } } /* * > If there is no furthest block, then the UA must first pop all the nodes from the bottom of the * > stack of open elements, from the current node up to and including formatting element, then * > remove formatting element from the list of active formatting elements, and finally return. */ if ( null === $furthest_block ) { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { $this->state->stack_of_open_elements->pop(); if ( $formatting_element->bookmark_name === $item->bookmark_name ) { $this->state->active_formatting_elements->remove_node( $formatting_element ); return; } } } $this->bail( 'Cannot extract common ancestor in adoption agency algorithm.' ); } $this->bail( 'Cannot run adoption agency when looping required.' ); } /** * Runs the "close the cell" algorithm. * * > Where the steps above say to close the cell, they mean to run the following algorithm: * > 1. Generate implied end tags. * > 2. If the current node is not now a td element or a th element, then this is a parse error. * > 3. Pop elements from the stack of open elements stack until a td element or a th element has been popped from the stack. * > 4. Clear the list of active formatting elements up to the last marker. * > 5. Switch the insertion mode to "in row". * * @see https://html.spec.whatwg.org/multipage/parsing.html#close-the-cell * * @since 6.7.0 */ private function close_cell(): void { $this->generate_implied_end_tags(); // @todo Parse error if the current node is a "td" or "th" element. foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) { $this->state->stack_of_open_elements->pop(); if ( 'TD' === $element->node_name || 'TH' === $element->node_name ) { break; } } $this->state->active_formatting_elements->clear_up_to_last_marker(); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; } /** * Inserts an HTML element on the stack of open elements. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#insert-a-foreign-element * * @param WP_HTML_Token $token Name of bookmark pointing to element in original input HTML. */ private function insert_html_element( WP_HTML_Token $token ): void { $this->state->stack_of_open_elements->push( $token ); } /** * Inserts a foreign element on to the stack of open elements. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#insert-a-foreign-element * * @param WP_HTML_Token $token Insert this token. The token's namespace and * insertion point will be updated correctly. * @param bool $only_add_to_element_stack Whether to skip the "insert an element at the adjusted * insertion location" algorithm when adding this element. */ private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to_element_stack ): void { $adjusted_current_node = $this->get_adjusted_current_node(); $token->namespace = $adjusted_current_node ? $adjusted_current_node->namespace : 'html'; if ( $this->is_mathml_integration_point() ) { $token->integration_node_type = 'math'; } elseif ( $this->is_html_integration_point() ) { $token->integration_node_type = 'html'; } if ( false === $only_add_to_element_stack ) { /* * @todo Implement the "appropriate place for inserting a node" and the * "insert an element at the adjusted insertion location" algorithms. * * These algorithms mostly impacts DOM tree construction and not the HTML API. * Here, there's no DOM node onto which the element will be appended, so the * parser will skip this step. * * @see https://html.spec.whatwg.org/#insert-an-element-at-the-adjusted-insertion-location */ } $this->insert_html_element( $token ); } /** * Inserts a virtual element on the stack of open elements. * * @since 6.7.0 * * @param string $token_name Name of token to create and insert into the stack of open elements. * @param string|null $bookmark_name Optional. Name to give bookmark for created virtual node. * Defaults to auto-creating a bookmark name. * @return WP_HTML_Token Newly-created virtual token. */ private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_HTML_Token { $here = $this->bookmarks[ $this->state->current_token->bookmark_name ]; $name = $bookmark_name ?? $this->bookmark_token(); $this->bookmarks[ $name ] = new WP_HTML_Span( $here->start, 0 ); $token = new WP_HTML_Token( $name, $token_name, false ); $this->insert_html_element( $token ); return $token; } /* * HTML Specification Helpers */ /** * Indicates if the current token is a MathML integration point. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#mathml-text-integration-point * * @return bool Whether the current token is a MathML integration point. */ private function is_mathml_integration_point(): bool { $current_token = $this->state->current_token; if ( ! isset( $current_token ) ) { return false; } if ( 'math' !== $current_token->namespace || 'M' !== $current_token->node_name[0] ) { return false; } $tag_name = $current_token->node_name; return ( 'MI' === $tag_name || 'MO' === $tag_name || 'MN' === $tag_name || 'MS' === $tag_name || 'MTEXT' === $tag_name ); } /** * Indicates if the current token is an HTML integration point. * * Note that this method must be an instance method with access * to the current token, since it needs to examine the attributes * of the currently-matched tag, if it's in the MathML namespace. * Otherwise it would be required to scan the HTML and ensure that * no other accounting is overlooked. * * @since 6.7.0 * * @see https://html.spec.whatwg.org/#html-integration-point * * @return bool Whether the current token is an HTML integration point. */ private function is_html_integration_point(): bool { $current_token = $this->state->current_token; if ( ! isset( $current_token ) ) { return false; } if ( 'html' === $current_token->namespace ) { return false; } $tag_name = $current_token->node_name; if ( 'svg' === $current_token->namespace ) { return ( 'DESC' === $tag_name || 'FOREIGNOBJECT' === $tag_name || 'TITLE' === $tag_name ); } if ( 'math' === $current_token->namespace ) { if ( 'ANNOTATION-XML' !== $tag_name ) { return false; } $encoding = $this->get_attribute( 'encoding' ); return ( is_string( $encoding ) && ( 0 === strcasecmp( $encoding, 'application/xhtml+xml' ) || 0 === strcasecmp( $encoding, 'text/html' ) ) ); } $this->bail( 'Should not have reached end of HTML Integration Point detection: check HTML API code.' ); // This unnecessary return prevents tools from inaccurately reporting type errors. return false; } /** * Returns whether an element of a given name is in the HTML special category. * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#special * * @param WP_HTML_Token|string $tag_name Node to check, or only its name if in the HTML namespace. * @return bool Whether the element of the given name is in the special category. */ public static function is_special( $tag_name ): bool { if ( is_string( $tag_name ) ) { $tag_name = strtoupper( $tag_name ); } else { $tag_name = 'html' === $tag_name->namespace ? strtoupper( $tag_name->node_name ) : "{$tag_name->namespace} {$tag_name->node_name}"; } return ( 'ADDRESS' === $tag_name || 'APPLET' === $tag_name || 'AREA' === $tag_name || 'ARTICLE' === $tag_name || 'ASIDE' === $tag_name || 'BASE' === $tag_name || 'BASEFONT' === $tag_name || 'BGSOUND' === $tag_name || 'BLOCKQUOTE' === $tag_name || 'BODY' === $tag_name || 'BR' === $tag_name || 'BUTTON' === $tag_name || 'CAPTION' === $tag_name || 'CENTER' === $tag_name || 'COL' === $tag_name || 'COLGROUP' === $tag_name || 'DD' === $tag_name || 'DETAILS' === $tag_name || 'DIR' === $tag_name || 'DIV' === $tag_name || 'DL' === $tag_name || 'DT' === $tag_name || 'EMBED' === $tag_name || 'FIELDSET' === $tag_name || 'FIGCAPTION' === $tag_name || 'FIGURE' === $tag_name || 'FOOTER' === $tag_name || 'FORM' === $tag_name || 'FRAME' === $tag_name || 'FRAMESET' === $tag_name || 'H1' === $tag_name || 'H2' === $tag_name || 'H3' === $tag_name || 'H4' === $tag_name || 'H5' === $tag_name || 'H6' === $tag_name || 'HEAD' === $tag_name || 'HEADER' === $tag_name || 'HGROUP' === $tag_name || 'HR' === $tag_name || 'HTML' === $tag_name || 'IFRAME' === $tag_name || 'IMG' === $tag_name || 'INPUT' === $tag_name || 'KEYGEN' === $tag_name || 'LI' === $tag_name || 'LINK' === $tag_name || 'LISTING' === $tag_name || 'MAIN' === $tag_name || 'MARQUEE' === $tag_name || 'MENU' === $tag_name || 'META' === $tag_name || 'NAV' === $tag_name || 'NOEMBED' === $tag_name || 'NOFRAMES' === $tag_name || 'NOSCRIPT' === $tag_name || 'OBJECT' === $tag_name || 'OL' === $tag_name || 'P' === $tag_name || 'PARAM' === $tag_name || 'PLAINTEXT' === $tag_name || 'PRE' === $tag_name || 'SCRIPT' === $tag_name || 'SEARCH' === $tag_name || 'SECTION' === $tag_name || 'SELECT' === $tag_name || 'SOURCE' === $tag_name || 'STYLE' === $tag_name || 'SUMMARY' === $tag_name || 'TABLE' === $tag_name || 'TBODY' === $tag_name || 'TD' === $tag_name || 'TEMPLATE' === $tag_name || 'TEXTAREA' === $tag_name || 'TFOOT' === $tag_name || 'TH' === $tag_name || 'THEAD' === $tag_name || 'TITLE' === $tag_name || 'TR' === $tag_name || 'TRACK' === $tag_name || 'UL' === $tag_name || 'WBR' === $tag_name || 'XMP' === $tag_name || // MathML. 'math MI' === $tag_name || 'math MO' === $tag_name || 'math MN' === $tag_name || 'math MS' === $tag_name || 'math MTEXT' === $tag_name || 'math ANNOTATION-XML' === $tag_name || // SVG. 'svg DESC' === $tag_name || 'svg FOREIGNOBJECT' === $tag_name || 'svg TITLE' === $tag_name ); } /** * Returns whether a given element is an HTML Void Element * * > area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr * * @since 6.4.0 * * @see https://html.spec.whatwg.org/#void-elements * * @param string $tag_name Name of HTML tag to check. * @return bool Whether the given tag is an HTML Void Element. */ public static function is_void( $tag_name ): bool { $tag_name = strtoupper( $tag_name ); return ( 'AREA' === $tag_name || 'BASE' === $tag_name || 'BASEFONT' === $tag_name || // Obsolete but still treated as void. 'BGSOUND' === $tag_name || // Obsolete but still treated as void. 'BR' === $tag_name || 'COL' === $tag_name || 'EMBED' === $tag_name || 'FRAME' === $tag_name || 'HR' === $tag_name || 'IMG' === $tag_name || 'INPUT' === $tag_name || 'KEYGEN' === $tag_name || // Obsolete but still treated as void. 'LINK' === $tag_name || 'META' === $tag_name || 'PARAM' === $tag_name || // Obsolete but still treated as void. 'SOURCE' === $tag_name || 'TRACK' === $tag_name || 'WBR' === $tag_name ); } /** * Gets an encoding from a given string. * * This is an algorithm defined in the WHAT-WG specification. * * Example: * * 'UTF-8' === self::get_encoding( 'utf8' ); * 'UTF-8' === self::get_encoding( " \tUTF-8 " ); * null === self::get_encoding( 'UTF-7' ); * null === self::get_encoding( 'utf8; charset=' ); * * @see https://encoding.spec.whatwg.org/#concept-encoding-get * * @todo As this parser only supports UTF-8, only the UTF-8 * encodings are detected. Add more as desired, but the * parser will bail on non-UTF-8 encodings. * * @since 6.7.0 * * @param string $label A string which may specify a known encoding. * @return string|null Known encoding if matched, otherwise null. */ protected static function get_encoding( string $label ): ?string { /* * > Remove any leading and trailing ASCII whitespace from label. */ $label = trim( $label, " \t\f\r\n" ); /* * > If label is an ASCII case-insensitive match for any of the labels listed in the * > table below, then return the corresponding encoding; otherwise return failure. */ switch ( strtolower( $label ) ) { case 'unicode-1-1-utf-8': case 'unicode11utf8': case 'unicode20utf8': case 'utf-8': case 'utf8': case 'x-unicode20utf8': return 'UTF-8'; default: return null; } } /* * Constants that would pollute the top of the class if they were found there. */ /** * Indicates that the next HTML token should be parsed and processed. * * @since 6.4.0 * * @var string */ const PROCESS_NEXT_NODE = 'process-next-node'; /** * Indicates that the current HTML token should be reprocessed in the newly-selected insertion mode. * * @since 6.4.0 * * @var string */ const REPROCESS_CURRENT_NODE = 'reprocess-current-node'; /** * Indicates that the current HTML token should be processed without advancing the parser. * * @since 6.5.0 * * @var string */ const PROCESS_CURRENT_NODE = 'process-current-node'; /** * Indicates that the parser encountered unsupported markup and has bailed. * * @since 6.4.0 * * @var string */ const ERROR_UNSUPPORTED = 'unsupported'; /** * Indicates that the parser encountered more HTML tokens than it * was able to process and has bailed. * * @since 6.4.0 * * @var string */ const ERROR_EXCEEDED_MAX_BOOKMARKS = 'exceeded-max-bookmarks'; /** * Unlock code that must be passed into the constructor to create this class. * * This class extends the WP_HTML_Tag_Processor, which has a public class * constructor. Therefore, it's not possible to have a private constructor here. * * This unlock code is used to ensure that anyone calling the constructor is * doing so with a full understanding that it's intended to be a private API. * * @access private */ const CONSTRUCTOR_UNLOCK_CODE = 'Use WP_HTML_Processor::create_fragment() instead of calling the class constructor directly.'; } <?php /** * HTML API: WP_HTML_Unsupported_Exception class * * @package WordPress * @subpackage HTML-API * @since 6.4.0 */ /** * Core class used by the HTML processor during HTML parsing * for indicating that a given operation is unsupported. * * This class is designed for internal use by the HTML processor. * * The HTML API aims to operate in compliance with the HTML5 * specification, but does not implement the full specification. * In cases where it lacks support it should not cause breakage * or unexpected behavior. In the cases where it recognizes that * it cannot proceed, this class is used to abort from any * operation and signify that the given HTML cannot be processed. * * @since 6.4.0 * @since 6.7.0 Gained contextual information for use in debugging parse failures. * * @access private * * @see WP_HTML_Processor */ class WP_HTML_Unsupported_Exception extends Exception { /** * Name of the matched token when the exception was raised, * if matched on a token. * * This does not imply that the token itself was unsupported, but it * may have been the case that the token triggered part of the HTML * parsing that isn't supported, such as the adoption agency algorithm. * * @since 6.7.0 * * @var string */ public $token_name; /** * Number of bytes into the input HTML document where the parser was * parsing when the exception was raised. * * Use this to reconstruct context for the failure. * * @since 6.7.0 * * @var int */ public $token_at; /** * Full raw text of the matched token when the exception was raised, * if matched on a token. * * Whereas the `$token_name` will be normalized, this contains the full * raw text of the token, including original casing, duplicated attributes, * and other syntactic variations that are normally abstracted in the HTML API. * * @since 6.7.0 * * @var string */ public $token; /** * Stack of open elements when the exception was raised. * * Use this to trace the parsing circumstances which led to the exception. * * @since 6.7.0 * * @var string[] */ public $stack_of_open_elements = array(); /** * List of active formatting elements when the exception was raised. * * Use this to trace the parsing circumstances which led to the exception. * * @since 6.7.0 * * @var string[] */ public $active_formatting_elements = array(); /** * Constructor function. * * @since 6.7.0 * * @param string $message Brief message explaining what is unsupported, the reason this exception was raised. * @param string $token_name Normalized name of matched token when this exception was raised. * @param int $token_at Number of bytes into source HTML document where matched token starts. * @param string $token Full raw text of matched token when this exception was raised. * @param string[] $stack_of_open_elements Stack of open elements when this exception was raised. * @param string[] $active_formatting_elements List of active formatting elements when this exception was raised. */ public function __construct( string $message, string $token_name, int $token_at, string $token, array $stack_of_open_elements, array $active_formatting_elements ) { parent::__construct( $message ); $this->token_name = $token_name; $this->token_at = $token_at; $this->token = $token; $this->stack_of_open_elements = $stack_of_open_elements; $this->active_formatting_elements = $active_formatting_elements; } } <?php /** * RSS2 Feed Template for displaying RSS2 Posts feed. * * @package WordPress */ header( 'Content-Type: ' . feed_content_type( 'rss2' ) . '; charset=' . get_option( 'blog_charset' ), true ); $more = 1; echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?' . '>'; /** * Fires between the xml and rss tags in a feed. * * @since 4.0.0 * * @param string $context Type of feed. Possible values include 'rss2', 'rss2-comments', * 'rdf', 'atom', and 'atom-comments'. */ do_action( 'rss_tag_pre', 'rss2' ); ?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" <?php /** * Fires at the end of the RSS root to add namespaces. * * @since 2.0.0 */ do_action( 'rss2_ns' ); ?> > <channel> <title><?php wp_title_rss(); ?></title> <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" /> <link><?php bloginfo_rss( 'url' ); ?></link> <description><?php bloginfo_rss( 'description' ); ?></description> <lastBuildDate><?php echo get_feed_build_date( 'r' ); ?></lastBuildDate> <language><?php bloginfo_rss( 'language' ); ?></language> <sy:updatePeriod> <?php $duration = 'hourly'; /** * Filters how often to update the RSS feed. * * @since 2.1.0 * * @param string $duration The update period. Accepts 'hourly', 'daily', 'weekly', 'monthly', * 'yearly'. Default 'hourly'. */ echo apply_filters( 'rss_update_period', $duration ); ?> </sy:updatePeriod> <sy:updateFrequency> <?php $frequency = '1'; /** * Filters the RSS update frequency. * * @since 2.1.0 * * @param string $frequency An integer passed as a string representing the frequency * of RSS updates within the update period. Default '1'. */ echo apply_filters( 'rss_update_frequency', $frequency ); ?> </sy:updateFrequency> <?php /** * Fires at the end of the RSS2 Feed Header. * * @since 2.0.0 */ do_action( 'rss2_head' ); while ( have_posts() ) : the_post(); ?> <item> <title><?php the_title_rss(); ?></title> <link><?php the_permalink_rss(); ?></link> <?php if ( get_comments_number() || comments_open() ) : ?> <comments><?php comments_link_feed(); ?></comments> <?php endif; ?> <dc:creator><![CDATA[<?php the_author(); ?>]]></dc:creator> <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); ?></pubDate> <?php the_category_rss( 'rss2' ); ?> <guid isPermaLink="false"><?php the_guid(); ?></guid> <?php if ( get_option( 'rss_use_excerpt' ) ) : ?> <description><![CDATA[<?php the_excerpt_rss(); ?>]]></description> <?php else : ?> <description><![CDATA[<?php the_excerpt_rss(); ?>]]></description> <?php $content = get_the_content_feed( 'rss2' ); ?> <?php if ( strlen( $content ) > 0 ) : ?> <content:encoded><![CDATA[<?php echo $content; ?>]]></content:encoded> <?php else : ?> <content:encoded><![CDATA[<?php the_excerpt_rss(); ?>]]></content:encoded> <?php endif; ?> <?php endif; ?> <?php if ( get_comments_number() || comments_open() ) : ?> <wfw:commentRss><?php echo esc_url( get_post_comments_feed_link( null, 'rss2' ) ); ?></wfw:commentRss> <slash:comments><?php echo get_comments_number(); ?></slash:comments> <?php endif; ?> <?php rss_enclosure(); ?> <?php /** * Fires at the end of each RSS2 feed item. * * @since 2.0.0 */ do_action( 'rss2_item' ); ?> </item> <?php endwhile; ?> </channel> </rss> <?php /** * Dependencies API: Scripts functions * * @since 2.6.0 * * @package WordPress * @subpackage Dependencies */ /** * Initializes $wp_scripts if it has not been set. * * @since 4.2.0 * * @global WP_Scripts $wp_scripts * * @return WP_Scripts WP_Scripts instance. */ function wp_scripts() { global $wp_scripts; if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { $wp_scripts = new WP_Scripts(); } return $wp_scripts; } /** * Helper function to output a _doing_it_wrong message when applicable. * * @ignore * @since 4.2.0 * @since 5.5.0 Added the `$handle` parameter. * * @param string $function_name Function name. * @param string $handle Optional. Name of the script or stylesheet that was * registered or enqueued too early. Default empty. */ function _wp_scripts_maybe_doing_it_wrong( $function_name, $handle = '' ) { if ( did_action( 'init' ) || did_action( 'wp_enqueue_scripts' ) || did_action( 'admin_enqueue_scripts' ) || did_action( 'login_enqueue_scripts' ) ) { return; } $message = sprintf( /* translators: 1: wp_enqueue_scripts, 2: admin_enqueue_scripts, 3: login_enqueue_scripts */ __( 'Scripts and styles should not be registered or enqueued until the %1$s, %2$s, or %3$s hooks.' ), '<code>wp_enqueue_scripts</code>', '<code>admin_enqueue_scripts</code>', '<code>login_enqueue_scripts</code>' ); if ( $handle ) { $message .= ' ' . sprintf( /* translators: %s: Name of the script or stylesheet. */ __( 'This notice was triggered by the %s handle.' ), '<code>' . $handle . '</code>' ); } _doing_it_wrong( $function_name, $message, '3.3.0' ); } /** * Prints scripts in document head that are in the $handles queue. * * Called by admin-header.php and {@see 'wp_head'} hook. Since it is called by wp_head on every page load, * the function does not instantiate the WP_Scripts object unless script names are explicitly passed. * Makes use of already-instantiated `$wp_scripts` global if present. Use provided {@see 'wp_print_scripts'} * hook to register/enqueue new scripts. * * @see WP_Scripts::do_item() * @since 2.1.0 * * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts. * * @param string|string[]|false $handles Optional. Scripts to be printed. Default 'false'. * @return string[] On success, an array of handles of processed WP_Dependencies items; otherwise, an empty array. */ function wp_print_scripts( $handles = false ) { global $wp_scripts; /** * Fires before scripts in the $handles queue are printed. * * @since 2.1.0 */ do_action( 'wp_print_scripts' ); if ( '' === $handles ) { // For 'wp_head'. $handles = false; } _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ ); if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { if ( ! $handles ) { return array(); // No need to instantiate if nothing is there. } } return wp_scripts()->do_items( $handles ); } /** * Adds extra code to a registered script. * * Code will only be added if the script is already in the queue. * Accepts a string `$data` containing the code. If two or more code blocks * are added to the same script `$handle`, they will be printed in the order * they were added, i.e. the latter added code can redeclare the previous. * * @since 4.5.0 * * @see WP_Scripts::add_inline_script() * * @param string $handle Name of the script to add the inline script to. * @param string $data String containing the JavaScript to be added. * @param string $position Optional. Whether to add the inline script before the handle * or after. Default 'after'. * @return bool True on success, false on failure. */ function wp_add_inline_script( $handle, $data, $position = 'after' ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); if ( false !== stripos( $data, '</script>' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( /* translators: 1: <script>, 2: wp_add_inline_script() */ __( 'Do not pass %1$s tags to %2$s.' ), '<code><script></code>', '<code>wp_add_inline_script()</code>' ), '4.5.0' ); $data = trim( preg_replace( '#<script[^>]*>(.*)</script>#is', '$1', $data ) ); } return wp_scripts()->add_inline_script( $handle, $data, $position ); } /** * Registers a new script. * * Registers a script to be enqueued later using the wp_enqueue_script() function. * * @see WP_Dependencies::add() * @see WP_Dependencies::add_data() * * @since 2.1.0 * @since 4.3.0 A return value was added. * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. * * @param string $handle Name of the script. Should be unique. * @param string|false $src Full URL of the script, or path of the script relative to the WordPress root directory. * If source is set to false, script is an alias of other scripts it depends on. * @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array. * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL * 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 { * Optional. An array of additional script loading strategies. Default empty array. * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. * * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. * } * @return bool Whether the script has been registered. True on success, false on failure. */ function wp_register_script( $handle, $src, $deps = array(), $ver = false, $args = array() ) { if ( ! is_array( $args ) ) { $args = array( 'in_footer' => (bool) $args, ); } _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); $wp_scripts = wp_scripts(); $registered = $wp_scripts->add( $handle, $src, $deps, $ver ); if ( ! empty( $args['in_footer'] ) ) { $wp_scripts->add_data( $handle, 'group', 1 ); } if ( ! empty( $args['strategy'] ) ) { $wp_scripts->add_data( $handle, 'strategy', $args['strategy'] ); } return $registered; } /** * Localizes a script. * * Works only if the script has already been registered. * * Accepts an associative array `$l10n` and creates a JavaScript object: * * "$object_name": { * key: value, * key: value, * ... * } * * @see WP_Scripts::localize() * @link https://core.trac.wordpress.org/ticket/11520 * * @since 2.2.0 * * @todo Documentation cleanup * * @param string $handle Script handle the data will be attached to. * @param string $object_name Name for the JavaScript object. Passed directly, so it should be qualified JS variable. * Example: '/[a-zA-Z0-9_]+/'. * @param array $l10n The data itself. The data can be either a single or multi-dimensional array. * @return bool True if the script was successfully localized, false otherwise. */ function wp_localize_script( $handle, $object_name, $l10n ) { $wp_scripts = wp_scripts(); return $wp_scripts->localize( $handle, $object_name, $l10n ); } /** * Sets translated strings for a script. * * Works only if the script has already been registered. * * @see WP_Scripts::set_translations() * @since 5.0.0 * @since 5.1.0 The `$domain` parameter was made optional. * * @global WP_Scripts $wp_scripts The WP_Scripts object for printing scripts. * * @param string $handle Script handle the textdomain will be attached to. * @param string $domain Optional. Text domain. Default 'default'. * @param string $path Optional. The full file path to the directory containing translation files. * @return bool True if the text domain was successfully localized, false otherwise. */ function wp_set_script_translations( $handle, $domain = 'default', $path = '' ) { global $wp_scripts; if ( ! ( $wp_scripts instanceof WP_Scripts ) ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); return false; } return $wp_scripts->set_translations( $handle, $domain, $path ); } /** * Removes a registered script. * * Note: there are intentional safeguards in place to prevent critical admin scripts, * such as jQuery core, from being unregistered. * * @see WP_Dependencies::remove() * * @since 2.1.0 * * @global string $pagenow The filename of the current screen. * * @param string $handle Name of the script to be removed. */ function wp_deregister_script( $handle ) { global $pagenow; _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); /** * Do not allow accidental or negligent de-registering of critical scripts in the admin. * Show minimal remorse if the correct hook is used. */ $current_filter = current_filter(); if ( ( is_admin() && 'admin_enqueue_scripts' !== $current_filter ) || ( 'wp-login.php' === $pagenow && 'login_enqueue_scripts' !== $current_filter ) ) { $not_allowed = array( 'jquery', 'jquery-core', 'jquery-migrate', 'jquery-ui-core', 'jquery-ui-accordion', 'jquery-ui-autocomplete', 'jquery-ui-button', 'jquery-ui-datepicker', 'jquery-ui-dialog', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-menu', 'jquery-ui-mouse', 'jquery-ui-position', 'jquery-ui-progressbar', 'jquery-ui-resizable', 'jquery-ui-selectable', 'jquery-ui-slider', 'jquery-ui-sortable', 'jquery-ui-spinner', 'jquery-ui-tabs', 'jquery-ui-tooltip', 'jquery-ui-widget', 'underscore', 'backbone', ); if ( in_array( $handle, $not_allowed, true ) ) { _doing_it_wrong( __FUNCTION__, sprintf( /* translators: 1: Script name, 2: wp_enqueue_scripts */ __( 'Do not deregister the %1$s script in the administration area. To target the front-end theme, use the %2$s hook.' ), "<code>$handle</code>", '<code>wp_enqueue_scripts</code>' ), '3.6.0' ); return; } } wp_scripts()->remove( $handle ); } /** * Enqueues a script. * * Registers the script if `$src` provided (does NOT overwrite), and enqueues it. * * @see WP_Dependencies::add() * @see WP_Dependencies::add_data() * @see WP_Dependencies::enqueue() * * @since 2.1.0 * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. * * @param string $handle Name of the script. Should be unique. * @param string $src Full URL of the script, or path of the script relative to the WordPress root directory. * Default empty. * @param string[] $deps Optional. An array of registered script handles this script depends on. Default empty array. * @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL * 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 { * Optional. An array of additional script loading strategies. Default empty array. * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. * * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. * } */ function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $args = array() ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); $wp_scripts = wp_scripts(); if ( $src || ! empty( $args ) ) { $_handle = explode( '?', $handle ); if ( ! is_array( $args ) ) { $args = array( 'in_footer' => (bool) $args, ); } if ( $src ) { $wp_scripts->add( $_handle[0], $src, $deps, $ver ); } if ( ! empty( $args['in_footer'] ) ) { $wp_scripts->add_data( $_handle[0], 'group', 1 ); } if ( ! empty( $args['strategy'] ) ) { $wp_scripts->add_data( $_handle[0], 'strategy', $args['strategy'] ); } } $wp_scripts->enqueue( $handle ); } /** * Removes a previously enqueued script. * * @see WP_Dependencies::dequeue() * * @since 3.1.0 * * @param string $handle Name of the script to be removed. */ function wp_dequeue_script( $handle ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); wp_scripts()->dequeue( $handle ); } /** * Determines whether a script has been added to the queue. * * For more information on this and similar theme functions, check out * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ * Conditional Tags} article in the Theme Developer Handbook. * * @since 2.8.0 * @since 3.5.0 'enqueued' added as an alias of the 'queue' list. * * @param string $handle Name of the script. * @param string $status Optional. Status of the script to check. Default 'enqueued'. * Accepts 'enqueued', 'registered', 'queue', 'to_do', and 'done'. * @return bool Whether the script is queued. */ function wp_script_is( $handle, $status = 'enqueued' ) { _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); return (bool) wp_scripts()->query( $handle, $status ); } /** * Adds metadata to a script. * * Works only if the script has already been registered. * * Possible values for $key and $value: * 'conditional' string Comments for IE 6, lte IE 7, etc. * * @since 4.2.0 * * @see WP_Dependencies::add_data() * * @param string $handle Name of the script. * @param string $key Name of data point for which we're storing a value. * @param mixed $value String containing the data to be added. * @return bool True on success, false on failure. */ function wp_script_add_data( $handle, $key, $value ) { return wp_scripts()->add_data( $handle, $key, $value ); } :root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.preference-base-option+.preference-base-option{margin-top:16px}@media (min-width:600px){.preferences-modal{height:calc(100% - 120px);width:calc(100% - 32px)}}@media (min-width:782px){.preferences-modal{width:750px}}@media (min-width:960px){.preferences-modal{height:70%}}@media (max-width:781px){.preferences-modal .components-modal__content{padding:0}}.preferences__tabs-tablist{position:absolute!important;right:16px;top:84px;width:160px}.preferences__tabs-tabpanel{margin-right:160px;padding-right:24px}@media (max-width:781px){.preferences__provider{height:100%}}.preferences-modal__section{margin:0 0 2.5rem}.preferences-modal__section:last-child{margin:0}.preferences-modal__section-legend{margin-bottom:8px}.preferences-modal__section-title{font-size:.9rem;font-weight:600;margin-top:0}.preferences-modal__section-description{color:#757575;font-size:12px;font-style:normal;margin:-8px 0 8px}.preferences-modal__section:has(.preferences-modal__section-content:empty){display:none}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.preference-base-option+.preference-base-option{margin-top:16px}@media (min-width:600px){.preferences-modal{height:calc(100% - 120px);width:calc(100% - 32px)}}@media (min-width:782px){.preferences-modal{width:750px}}@media (min-width:960px){.preferences-modal{height:70%}}@media (max-width:781px){.preferences-modal .components-modal__content{padding:0}}.preferences__tabs-tablist{left:16px;position:absolute!important;top:84px;width:160px}.preferences__tabs-tabpanel{margin-left:160px;padding-left:24px}@media (max-width:781px){.preferences__provider{height:100%}}.preferences-modal__section{margin:0 0 2.5rem}.preferences-modal__section:last-child{margin:0}.preferences-modal__section-legend{margin-bottom:8px}.preferences-modal__section-title{font-size:.9rem;font-weight:600;margin-top:0}.preferences-modal__section-description{color:#757575;font-size:12px;font-style:normal;margin:-8px 0 8px}.preferences-modal__section:has(.preferences-modal__section-content:empty){display:none}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .preference-base-option+.preference-base-option{ margin-top:16px; } @media (min-width:600px){ .preferences-modal{ height:calc(100% - 120px); width:calc(100% - 32px); } } @media (min-width:782px){ .preferences-modal{ width:750px; } } @media (min-width:960px){ .preferences-modal{ height:70%; } } @media (max-width:781px){ .preferences-modal .components-modal__content{ padding:0; } } .preferences__tabs-tablist{ position:absolute !important; right:16px; top:84px; width:160px; } .preferences__tabs-tabpanel{ margin-right:160px; padding-right:24px; } @media (max-width:781px){ .preferences__provider{ height:100%; } } .preferences-modal__section{ margin:0 0 2.5rem; } .preferences-modal__section:last-child{ margin:0; } .preferences-modal__section-legend{ margin-bottom:8px; } .preferences-modal__section-title{ font-size:.9rem; font-weight:600; margin-top:0; } .preferences-modal__section-description{ color:#757575; font-size:12px; font-style:normal; margin:-8px 0 8px; } .preferences-modal__section:has(.preferences-modal__section-content:empty){ display:none; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .preference-base-option+.preference-base-option{ margin-top:16px; } @media (min-width:600px){ .preferences-modal{ height:calc(100% - 120px); width:calc(100% - 32px); } } @media (min-width:782px){ .preferences-modal{ width:750px; } } @media (min-width:960px){ .preferences-modal{ height:70%; } } @media (max-width:781px){ .preferences-modal .components-modal__content{ padding:0; } } .preferences__tabs-tablist{ left:16px; position:absolute !important; top:84px; width:160px; } .preferences__tabs-tabpanel{ margin-left:160px; padding-left:24px; } @media (max-width:781px){ .preferences__provider{ height:100%; } } .preferences-modal__section{ margin:0 0 2.5rem; } .preferences-modal__section:last-child{ margin:0; } .preferences-modal__section-legend{ margin-bottom:8px; } .preferences-modal__section-title{ font-size:.9rem; font-weight:600; margin-top:0; } .preferences-modal__section-description{ color:#757575; font-size:12px; font-style:normal; margin:-8px 0 8px; } .preferences-modal__section:has(.preferences-modal__section-content:empty){ display:none; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.commands-command-menu{border-radius:4px;margin:auto;max-width:400px;position:relative;top:calc(5% + 60px);width:calc(100% - 32px)}@media (min-width:600px){.commands-command-menu{top:calc(10% + 60px)}}.commands-command-menu .components-modal__content{margin:0;padding:0}.commands-command-menu__overlay{align-items:start;display:block}.commands-command-menu__header{align-items:center;display:flex;padding:0 16px}.commands-command-menu__header .components-button{border:1px solid #949494;border-left:0;border-radius:0 2px 2px 0;height:56px;justify-content:center;width:56px}.commands-command-menu__header .components-button+[cmdk-input]{border-bottom-right-radius:0;border-top-right-radius:0}.commands-command-menu__container{will-change:transform}.commands-command-menu__container [cmdk-input]{border:none;border-radius:0;color:#1e1e1e;font-size:15px;line-height:28px;margin:0;outline:none;padding:16px 4px;width:100%}.commands-command-menu__container [cmdk-input]::placeholder{color:#757575}.commands-command-menu__container [cmdk-input]:focus{box-shadow:none;outline:none}.commands-command-menu__container [cmdk-item]{align-items:center;border-radius:2px;color:#1e1e1e;cursor:pointer;display:flex;font-size:13px}.commands-command-menu__container [cmdk-item]:active,.commands-command-menu__container [cmdk-item][aria-selected=true]{background:var(--wp-admin-theme-color);color:#fff}.commands-command-menu__container [cmdk-item]:active svg,.commands-command-menu__container [cmdk-item][aria-selected=true] svg{fill:#fff}.commands-command-menu__container [cmdk-item][aria-disabled=true]{color:#949494;cursor:not-allowed}.commands-command-menu__container [cmdk-item] svg{fill:#1e1e1e}.commands-command-menu__container [cmdk-item]>div{min-height:40px;padding:4px 40px 4px 4px}.commands-command-menu__container [cmdk-item]>.has-icon{padding-right:8px}.commands-command-menu__container [cmdk-root]>[cmdk-list]{max-height:368px;overflow:auto}.commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]:last-child [cmdk-group-items]:not(:empty){padding-bottom:8px}.commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]>[cmdk-group-items]:not(:empty){padding:0 8px}.commands-command-menu__container [cmdk-empty]{align-items:center;color:#1e1e1e;display:flex;justify-content:center;padding:8px 0 32px;white-space:pre-wrap}.commands-command-menu__container [cmdk-loading]{padding:16px}.commands-command-menu__container [cmdk-list-sizer]{position:relative}.commands-command-menu__item span{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.commands-command-menu__item mark{background:unset;color:inherit;font-weight:600}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.commands-command-menu{border-radius:4px;margin:auto;max-width:400px;position:relative;top:calc(5% + 60px);width:calc(100% - 32px)}@media (min-width:600px){.commands-command-menu{top:calc(10% + 60px)}}.commands-command-menu .components-modal__content{margin:0;padding:0}.commands-command-menu__overlay{align-items:start;display:block}.commands-command-menu__header{align-items:center;display:flex;padding:0 16px}.commands-command-menu__header .components-button{border:1px solid #949494;border-radius:2px 0 0 2px;border-right:0;height:56px;justify-content:center;width:56px}.commands-command-menu__header .components-button+[cmdk-input]{border-bottom-left-radius:0;border-top-left-radius:0}.commands-command-menu__container{will-change:transform}.commands-command-menu__container [cmdk-input]{border:none;border-radius:0;color:#1e1e1e;font-size:15px;line-height:28px;margin:0;outline:none;padding:16px 4px;width:100%}.commands-command-menu__container [cmdk-input]::placeholder{color:#757575}.commands-command-menu__container [cmdk-input]:focus{box-shadow:none;outline:none}.commands-command-menu__container [cmdk-item]{align-items:center;border-radius:2px;color:#1e1e1e;cursor:pointer;display:flex;font-size:13px}.commands-command-menu__container [cmdk-item]:active,.commands-command-menu__container [cmdk-item][aria-selected=true]{background:var(--wp-admin-theme-color);color:#fff}.commands-command-menu__container [cmdk-item]:active svg,.commands-command-menu__container [cmdk-item][aria-selected=true] svg{fill:#fff}.commands-command-menu__container [cmdk-item][aria-disabled=true]{color:#949494;cursor:not-allowed}.commands-command-menu__container [cmdk-item] svg{fill:#1e1e1e}.commands-command-menu__container [cmdk-item]>div{min-height:40px;padding:4px 4px 4px 40px}.commands-command-menu__container [cmdk-item]>.has-icon{padding-left:8px}.commands-command-menu__container [cmdk-root]>[cmdk-list]{max-height:368px;overflow:auto}.commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]:last-child [cmdk-group-items]:not(:empty){padding-bottom:8px}.commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]>[cmdk-group-items]:not(:empty){padding:0 8px}.commands-command-menu__container [cmdk-empty]{align-items:center;color:#1e1e1e;display:flex;justify-content:center;padding:8px 0 32px;white-space:pre-wrap}.commands-command-menu__container [cmdk-loading]{padding:16px}.commands-command-menu__container [cmdk-list-sizer]{position:relative}.commands-command-menu__item span{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.commands-command-menu__item mark{background:unset;color:inherit;font-weight:600}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .commands-command-menu{ border-radius:4px; margin:auto; max-width:400px; position:relative; top:calc(5% + 60px); width:calc(100% - 32px); } @media (min-width:600px){ .commands-command-menu{ top:calc(10% + 60px); } } .commands-command-menu .components-modal__content{ margin:0; padding:0; } .commands-command-menu__overlay{ align-items:start; display:block; } .commands-command-menu__header{ align-items:center; display:flex; padding:0 16px; } .commands-command-menu__header .components-button{ border:1px solid #949494; border-left:0; border-radius:0 2px 2px 0; height:56px; justify-content:center; width:56px; } .commands-command-menu__header .components-button+[cmdk-input]{ border-bottom-right-radius:0; border-top-right-radius:0; } .commands-command-menu__container{ will-change:transform; } .commands-command-menu__container [cmdk-input]{ border:none; border-radius:0; color:#1e1e1e; font-size:15px; line-height:28px; margin:0; outline:none; padding:16px 4px; width:100%; } .commands-command-menu__container [cmdk-input]::placeholder{ color:#757575; } .commands-command-menu__container [cmdk-input]:focus{ box-shadow:none; outline:none; } .commands-command-menu__container [cmdk-item]{ align-items:center; border-radius:2px; color:#1e1e1e; cursor:pointer; display:flex; font-size:13px; } .commands-command-menu__container [cmdk-item]:active,.commands-command-menu__container [cmdk-item][aria-selected=true]{ background:var(--wp-admin-theme-color); color:#fff; } .commands-command-menu__container [cmdk-item]:active svg,.commands-command-menu__container [cmdk-item][aria-selected=true] svg{ fill:#fff; } .commands-command-menu__container [cmdk-item][aria-disabled=true]{ color:#949494; cursor:not-allowed; } .commands-command-menu__container [cmdk-item] svg{ fill:#1e1e1e; } .commands-command-menu__container [cmdk-item]>div{ min-height:40px; padding:4px 40px 4px 4px; } .commands-command-menu__container [cmdk-item]>.has-icon{ padding-right:8px; } .commands-command-menu__container [cmdk-root]>[cmdk-list]{ max-height:368px; overflow:auto; } .commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]:last-child [cmdk-group-items]:not(:empty){ padding-bottom:8px; } .commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]>[cmdk-group-items]:not(:empty){ padding:0 8px; } .commands-command-menu__container [cmdk-empty]{ align-items:center; color:#1e1e1e; display:flex; justify-content:center; padding:8px 0 32px; white-space:pre-wrap; } .commands-command-menu__container [cmdk-loading]{ padding:16px; } .commands-command-menu__container [cmdk-list-sizer]{ position:relative; } .commands-command-menu__item span{ display:inline-block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .commands-command-menu__item mark{ background:unset; color:inherit; font-weight:600; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .commands-command-menu{ border-radius:4px; margin:auto; max-width:400px; position:relative; top:calc(5% + 60px); width:calc(100% - 32px); } @media (min-width:600px){ .commands-command-menu{ top:calc(10% + 60px); } } .commands-command-menu .components-modal__content{ margin:0; padding:0; } .commands-command-menu__overlay{ align-items:start; display:block; } .commands-command-menu__header{ align-items:center; display:flex; padding:0 16px; } .commands-command-menu__header .components-button{ border:1px solid #949494; border-radius:2px 0 0 2px; border-right:0; height:56px; justify-content:center; width:56px; } .commands-command-menu__header .components-button+[cmdk-input]{ border-bottom-left-radius:0; border-top-left-radius:0; } .commands-command-menu__container{ will-change:transform; } .commands-command-menu__container [cmdk-input]{ border:none; border-radius:0; color:#1e1e1e; font-size:15px; line-height:28px; margin:0; outline:none; padding:16px 4px; width:100%; } .commands-command-menu__container [cmdk-input]::placeholder{ color:#757575; } .commands-command-menu__container [cmdk-input]:focus{ box-shadow:none; outline:none; } .commands-command-menu__container [cmdk-item]{ align-items:center; border-radius:2px; color:#1e1e1e; cursor:pointer; display:flex; font-size:13px; } .commands-command-menu__container [cmdk-item]:active,.commands-command-menu__container [cmdk-item][aria-selected=true]{ background:var(--wp-admin-theme-color); color:#fff; } .commands-command-menu__container [cmdk-item]:active svg,.commands-command-menu__container [cmdk-item][aria-selected=true] svg{ fill:#fff; } .commands-command-menu__container [cmdk-item][aria-disabled=true]{ color:#949494; cursor:not-allowed; } .commands-command-menu__container [cmdk-item] svg{ fill:#1e1e1e; } .commands-command-menu__container [cmdk-item]>div{ min-height:40px; padding:4px 4px 4px 40px; } .commands-command-menu__container [cmdk-item]>.has-icon{ padding-left:8px; } .commands-command-menu__container [cmdk-root]>[cmdk-list]{ max-height:368px; overflow:auto; } .commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]:last-child [cmdk-group-items]:not(:empty){ padding-bottom:8px; } .commands-command-menu__container [cmdk-root]>[cmdk-list] [cmdk-list-sizer]>[cmdk-group]>[cmdk-group-items]:not(:empty){ padding:0 8px; } .commands-command-menu__container [cmdk-empty]{ align-items:center; color:#1e1e1e; display:flex; justify-content:center; padding:8px 0 32px; white-space:pre-wrap; } .commands-command-menu__container [cmdk-loading]{ padding:16px; } .commands-command-menu__container [cmdk-list-sizer]{ position:relative; } .commands-command-menu__item span{ display:inline-block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .commands-command-menu__item mark{ background:unset; color:inherit; font-weight:600; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .wp-element-button{ cursor:pointer; } :root{ --wp--preset--font-size--normal:16px; --wp--preset--font-size--huge:42px; } :root .has-very-light-gray-background-color{ background-color:#eee; } :root .has-very-dark-gray-background-color{ background-color:#313131; } :root .has-very-light-gray-color{ color:#eee; } :root .has-very-dark-gray-color{ color:#313131; } :root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(-135deg, #00d084, #0693e3); } :root .has-purple-crush-gradient-background{ background:linear-gradient(-135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .has-hazy-dawn-gradient-background{ background:linear-gradient(-135deg, #faaca8, #dad0ec); } :root .has-subdued-olive-gradient-background{ background:linear-gradient(-135deg, #fafae1, #67a671); } :root .has-atomic-cream-gradient-background{ background:linear-gradient(-135deg, #fdd79a, #004a59); } :root .has-nightshade-gradient-background{ background:linear-gradient(-135deg, #330968, #31cdcf); } :root .has-midnight-gradient-background{ background:linear-gradient(-135deg, #020381, #2874fc); } .has-regular-font-size{ font-size:1em; } .has-larger-font-size{ font-size:2.625em; } .has-normal-font-size{ font-size:var(--wp--preset--font-size--normal); } .has-huge-font-size{ font-size:var(--wp--preset--font-size--huge); } .has-text-align-center{ text-align:center; } .has-text-align-left{ text-align:left; } .has-text-align-right{ text-align:right; } #end-resizable-editor-section{ display:none; } .aligncenter{ clear:both; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } .screen-reader-text{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .screen-reader-text:focus{ background-color:#ddd; clip-path:none; color:#444; display:block; font-size:1em; height:auto; line-height:normal; padding:15px 23px 14px; right:5px; text-decoration:none; top:5px; width:auto; z-index:100000; } html :where(.has-border-color){ border-style:solid; } html :where([style*=border-top-color]){ border-top-style:solid; } html :where([style*=border-right-color]){ border-left-style:solid; } html :where([style*=border-bottom-color]){ border-bottom-style:solid; } html :where([style*=border-left-color]){ border-right-style:solid; } html :where([style*=border-width]){ border-style:solid; } html :where([style*=border-top-width]){ border-top-style:solid; } html :where([style*=border-right-width]){ border-left-style:solid; } html :where([style*=border-bottom-width]){ border-bottom-style:solid; } html :where([style*=border-left-width]){ border-right-style:solid; } html :where(img[class*=wp-image-]){ height:auto; max-width:100%; } :where(figure){ margin:0 0 1em; } html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height, 0px); } @media screen and (max-width:600px){ html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:0px; } }ul.wp-block-archives{padding-right:2.5em}.wp-block-archives .wp-block-archives{border:0;margin:0}.wp-block-audio{margin-left:0;margin-right:0;position:relative}.wp-block-audio.is-transient audio{opacity:.3}.wp-block-audio .components-spinner{margin-right:-9px;margin-top:-9px;position:absolute;right:50%;top:50%}.wp-block-avatar__image img{width:100%}.wp-block-avatar.aligncenter .components-resizable-box__container{margin:0 auto}.wp-block[data-align=center]>.wp-block-button{margin-left:auto;margin-right:auto;text-align:center}.wp-block[data-align=right]>.wp-block-button{text-align:right}.wp-block-button{cursor:text;position:relative}.wp-block-button:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:-2px}.wp-block-button[data-rich-text-placeholder]:after{opacity:.8}div[data-type="core/button"]{display:table}.wp-block-buttons>.wp-block,.wp-block-buttons>.wp-block-button.wp-block-button.wp-block-button.wp-block-button.wp-block-button{margin:0}.wp-block-buttons>.block-list-appender{align-items:center;display:inline-flex}.wp-block-buttons.is-vertical>.block-list-appender .block-list-appender__toggle{justify-content:flex-start}.wp-block-buttons>.wp-block-button:focus{box-shadow:none}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center]{margin-left:auto;margin-right:auto;margin-top:0;width:100%}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center] .wp-block-button{margin-bottom:0}.wp-block[data-align=center]>.wp-block-buttons{align-items:center;justify-content:center}.wp-block[data-align=right]>.wp-block-buttons{justify-content:flex-end}.wp-block-categories ul{padding-right:2.5em}.wp-block-categories ul ul{margin-top:6px}[data-align=center] .wp-block-categories{text-align:center}.wp-block-categories__indentation{padding-right:16px}.wp-block-code code{background:none}.wp-block-columns :where(.wp-block){margin-left:0;margin-right:0;max-width:none}html :where(.wp-block-column){margin-bottom:0;margin-top:0}.wp-block-comments__legacy-placeholder,.wp-block-post-comments{box-sizing:border-box}.wp-block-comments__legacy-placeholder .alignleft,.wp-block-post-comments .alignleft{float:right}.wp-block-comments__legacy-placeholder .alignright,.wp-block-post-comments .alignright{float:left}.wp-block-comments__legacy-placeholder .navigation:after,.wp-block-post-comments .navigation:after{clear:both;content:"";display:table}.wp-block-comments__legacy-placeholder .commentlist,.wp-block-post-comments .commentlist{clear:both;list-style:none;margin:0;padding:0}.wp-block-comments__legacy-placeholder .commentlist .comment,.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-right:3.25em}.wp-block-comments__legacy-placeholder .commentlist .comment p,.wp-block-post-comments .commentlist .comment p{font-size:1em;line-height:1.8;margin:1em 0}.wp-block-comments__legacy-placeholder .commentlist .children,.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-comments__legacy-placeholder .comment-author,.wp-block-post-comments .comment-author{line-height:1.5}.wp-block-comments__legacy-placeholder .comment-author .avatar,.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:right;height:2.5em;margin-left:.75em;margin-top:.5em;width:2.5em}.wp-block-comments__legacy-placeholder .comment-author cite,.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-comments__legacy-placeholder .comment-meta,.wp-block-post-comments .comment-meta{font-size:.875em;line-height:1.5}.wp-block-comments__legacy-placeholder .comment-meta b,.wp-block-post-comments .comment-meta b{font-weight:400}.wp-block-comments__legacy-placeholder .comment-meta .comment-awaiting-moderation,.wp-block-post-comments .comment-meta .comment-awaiting-moderation{display:block;margin-bottom:1em;margin-top:1em}.wp-block-comments__legacy-placeholder .comment-body .commentmetadata,.wp-block-post-comments .comment-body .commentmetadata{font-size:.875em}.wp-block-comments__legacy-placeholder .comment-form-author label,.wp-block-comments__legacy-placeholder .comment-form-comment label,.wp-block-comments__legacy-placeholder .comment-form-email label,.wp-block-comments__legacy-placeholder .comment-form-url label,.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-comments__legacy-placeholder .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder .comment-form textarea,.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-comments__legacy-placeholder .comment-form-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-comments__legacy-placeholder .comment-form-cookies-consent #wp-comment-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-comments__legacy-placeholder .comment-reply-title,.wp-block-post-comments .comment-reply-title{margin-bottom:0}.wp-block-comments__legacy-placeholder .comment-reply-title :where(small),.wp-block-post-comments .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-right:.5em}.wp-block-comments__legacy-placeholder .reply,.wp-block-post-comments .reply{font-size:.875em;margin-bottom:1.4em}.wp-block-comments__legacy-placeholder input:not([type=submit]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-family:inherit;font-size:1em}.wp-block-comments__legacy-placeholder input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}:where(.wp-block-post-comments input[type=submit],.wp-block-comments__legacy-placeholder input[type=submit]){border:none}.wp-block-comments{box-sizing:border-box}.block-library-comments-toolbar__popover .components-popover__content{min-width:230px}.wp-block-comments__legacy-placeholder *{pointer-events:none}.wp-block-comment-author-avatar__placeholder{border:1px dashed;height:100%;width:100%;stroke:currentColor;stroke-dasharray:3}.wp-block[data-align=center]>.wp-block-comments-pagination{justify-content:center}:where(.editor-styles-wrapper) .wp-block-comments-pagination{max-width:100%}:where(.editor-styles-wrapper) .wp-block-comments-pagination.block-editor-block-list__layout{margin:0}.wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{font-size:inherit;margin-bottom:.5em;margin-right:.5em;margin-top:.5em}.wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{margin-right:0}.wp-block-comments-pagination-numbers a{text-decoration:underline}.wp-block-comments-pagination-numbers .page-numbers{margin-left:2px}.wp-block-comments-pagination-numbers .page-numbers:last-child{margin-right:0}.wp-block-comments-title.has-background{padding:inherit}.wp-block-cover.is-placeholder{align-items:stretch;display:flex;min-height:240px;padding:0!important}.wp-block-cover.is-placeholder .components-placeholder.is-large{justify-content:flex-start;z-index:1}.wp-block-cover.is-placeholder:focus:after{min-height:auto}.wp-block-cover.components-placeholder h2{color:inherit}.wp-block-cover.is-transient{position:relative}.wp-block-cover.is-transient:before{background-color:#fff;content:"";height:100%;opacity:.3;position:absolute;width:100%;z-index:1}.wp-block-cover.is-transient .wp-block-cover__inner-container{z-index:2}.wp-block-cover .components-spinner{margin:0;position:absolute;right:50%;top:50%;transform:translate(50%,-50%)}.wp-block-cover .wp-block-cover__inner-container{margin-left:0;margin-right:0;text-align:right}.wp-block-cover .wp-block-cover__placeholder-background-options{width:100%}.wp-block-cover .wp-block-cover__image--placeholder-image{bottom:0;left:0;position:absolute;right:0;top:0}[data-align=left]>.wp-block-cover,[data-align=right]>.wp-block-cover{max-width:420px;width:100%}.block-library-cover__reset-button{margin-right:auto}.block-library-cover__resize-container{bottom:0;left:0;min-height:50px;position:absolute!important;right:0;top:0}.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .block-library-cover__resize-container,.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .components-popover__content>div{overflow:visible;pointer-events:none}.block-editor-block-patterns-list__list-item .has-parallax.wp-block-cover{background-attachment:scroll}.color-block-support-panel__inner-wrapper>:not(.block-editor-tools-panel-color-gradient-settings__item){margin-top:24px}.wp-block-details summary div{display:inline}.wp-block-embed{clear:both;margin-left:0;margin-right:0}.wp-block-embed.is-loading{display:flex;justify-content:center}.wp-block-embed .wp-block-embed__placeholder-input{flex:1 1 auto}.wp-block-embed .components-placeholder__error{word-break:break-word}.wp-block-post-content .wp-block-embed__learn-more a{color:var(--wp-admin-theme-color)}.block-library-embed__interactive-overlay{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.wp-block[data-align=left]>.wp-block-embed,.wp-block[data-align=right]>.wp-block-embed{max-width:360px;width:100%}.wp-block[data-align=left]>.wp-block-embed .wp-block-embed__wrapper,.wp-block[data-align=right]>.wp-block-embed .wp-block-embed__wrapper{min-width:280px}.wp-block-file{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:0}.wp-block[data-align=left]>.wp-block-file,.wp-block[data-align=right]>.wp-block-file{height:auto}.wp-block[data-align=center]>.wp-block-file{text-align:center}.wp-block-file .components-resizable-box__container{margin-bottom:1em}.wp-block-file .wp-block-file__preview{height:100%;margin-bottom:1em;width:100%}.wp-block-file .wp-block-file__preview-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.wp-block-file .wp-block-file__content-wrapper{flex-grow:1}.wp-block-file a{min-width:1em}.wp-block-file a:not(.wp-block-file__button){display:inline-block}.wp-block-file .wp-block-file__button-richtext-wrapper{display:inline-block;margin-right:.75em}.wp-block-form-input .is-input-hidden{background:repeating-linear-gradient(-45deg,#0000,#0000 5px,currentColor 0,currentColor 6px);border:1px dashed;box-sizing:border-box;font-size:.85em;opacity:.3;padding:.5em}.wp-block-form-input .is-input-hidden input[type=text]{background:#0000}.wp-block-form-input.is-selected .is-input-hidden{background:none;opacity:1}.wp-block-form-input.is-selected .is-input-hidden input[type=text]{background:unset}.wp-block-form-submission-notification>*{background:repeating-linear-gradient(-45deg,#0000,#0000 5px,currentColor 0,currentColor 6px);border:1px dashed;box-sizing:border-box;opacity:.25}.wp-block-form-submission-notification.is-selected>*,.wp-block-form-submission-notification:has(.is-selected)>*{background:none;opacity:1}.wp-block-form-submission-notification.is-selected:after,.wp-block-form-submission-notification:has(.is-selected):after{display:none!important}.wp-block-form-submission-notification:after{align-items:center;display:flex;font-size:1.1em;height:100%;justify-content:center;position:absolute;right:0;top:0;width:100%}.wp-block-form-submission-notification.form-notification-type-success:after{content:attr(data-message-success)}.wp-block-form-submission-notification.form-notification-type-error:after{content:attr(data-message-error)}.wp-block-freeform.block-library-rich-text__tinymce{height:auto}.wp-block-freeform.block-library-rich-text__tinymce li,.wp-block-freeform.block-library-rich-text__tinymce p{line-height:1.8}.wp-block-freeform.block-library-rich-text__tinymce ol,.wp-block-freeform.block-library-rich-text__tinymce ul{margin-right:0;padding-right:2.5em}.wp-block-freeform.block-library-rich-text__tinymce blockquote{border-right:4px solid #000;box-shadow:inset 0 0 0 0 #ddd;margin:0;padding-right:1em}.wp-block-freeform.block-library-rich-text__tinymce pre{color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:15px;white-space:pre-wrap}.wp-block-freeform.block-library-rich-text__tinymce>:first-child{margin-top:0}.wp-block-freeform.block-library-rich-text__tinymce>:last-child{margin-bottom:0}.wp-block-freeform.block-library-rich-text__tinymce.mce-edit-focus{outline:none}.wp-block-freeform.block-library-rich-text__tinymce a{color:var(--wp-admin-theme-color)}.wp-block-freeform.block-library-rich-text__tinymce:focus a[data-mce-selected]{background:#e5f5fa;border-radius:2px;box-shadow:0 0 0 1px #e5f5fa;margin:0 -2px;padding:0 2px}.wp-block-freeform.block-library-rich-text__tinymce code{background:#f0f0f0;border-radius:2px;color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:14px;padding:2px}.wp-block-freeform.block-library-rich-text__tinymce:focus code[data-mce-selected]{background:#ddd}.wp-block-freeform.block-library-rich-text__tinymce .alignright{float:right;margin:.5em 0 .5em 1em}.wp-block-freeform.block-library-rich-text__tinymce .alignleft{float:left;margin:.5em 1em .5em 0}.wp-block-freeform.block-library-rich-text__tinymce .aligncenter{display:block;margin-left:auto;margin-right:auto}.wp-block-freeform.block-library-rich-text__tinymce .wp-more-tag{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADtgAAAAoBAMAAAA86gLBAAAAJFBMVEVMaXG7u7vBwcHDw8POzs68vLzGxsbMzMy+vr7AwMDQ0NDGxsYKLGzpAAAADHRSTlMA///zWf+/f///TMxNVGuqAAABwklEQVR4Ae3dMXLaQBTH4bfj8UCpx8hq0vgKvgFNemhT6Qo6gg6R+0ZahM2QLmyBJ99XWP9V5+o3jIUcLQEAAAAAAAAAAAAAAAAAAAAAAABQ8j0WL9lfTtlt18uNXAUA8O/KVtfa1tdcrOdSh9gCQAMlh1hMNbZZ1bsrsQWABsrhLRbz7z5in/32UbfUMUbkMQCAh5RfGYv82UdMdZ6HS2wjT2ILAI8r3XmM2B3WvM59vfO2xXYW2yYAENuPU8S+X/N67mKxzy225yaxBQCxLV392UdcvwV0jPVUj98ntkBWT7C7+9u2/V/vGtvXIWJ6/4rtbottWa6Ri0NUT/u72LYttrb97LHdvUXMxxrb8TO2W2TF1rYbbLG1bbGNjMi4+2Sbi1FsbbvNFlvbFtt5fDnE3d9sP1/XeIyV2Nr2U2/guZUuptNrH/dPI9eLB6SaAEBs6wPJf3/PNk9tYgsAYrv/8TFuzx/fvkFqGtrEFgDEdpcZUb7ejXy6ntrEFgDENvL6gsas4vbdyKt4DACI7TxElJv/Z7udpqFNbAFAbKduy2uU2trttM/x28UWAAAAAAAAAAAAAAAAAAAAAAAAAADgDyPwGmGTCZp7AAAAAElFTkSuQmCC);background-position:50%;background-repeat:no-repeat;background-size:1900px 20px;cursor:default;display:block;height:20px;margin:15px auto;outline:0;width:96%}.wp-block-freeform.block-library-rich-text__tinymce img::selection{background-color:initial}.wp-block-freeform.block-library-rich-text__tinymce div.mceTemp{-ms-user-select:element}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption{margin:0;max-width:100%}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption a,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption img{display:block}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption *{-webkit-user-drag:none}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption .wp-caption-dd{margin:0;padding-top:.5em}.wp-block-freeform.block-library-rich-text__tinymce .wpview{border:1px solid #0000;clear:both;margin-bottom:16px;position:relative;width:99.99%}.wp-block-freeform.block-library-rich-text__tinymce .wpview iframe{background:#0000;display:block;max-width:100%}.wp-block-freeform.block-library-rich-text__tinymce .wpview .mce-shim{bottom:0;left:0;position:absolute;right:0;top:0}.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected="2"] .mce-shim{display:none}.wp-block-freeform.block-library-rich-text__tinymce .wpview .loading-placeholder{border:1px dashed #ddd;padding:10px}.wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error{border:1px solid #ddd;margin:0;padding:1em 0;word-wrap:break-word}.wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error p{margin:0;text-align:center}.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .loading-placeholder,.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .wpview-error{border-color:#0000}.wp-block-freeform.block-library-rich-text__tinymce .wpview .dashicons{display:block;font-size:32px;height:32px;margin:0 auto;width:32px}.wp-block-freeform.block-library-rich-text__tinymce .wpview.wpview-type-gallery:after{clear:both;content:"";display:table}.wp-block-freeform.block-library-rich-text__tinymce .gallery img[data-mce-selected]:focus{outline:none}.wp-block-freeform.block-library-rich-text__tinymce .gallery a{cursor:default}.wp-block-freeform.block-library-rich-text__tinymce .gallery{line-height:1;margin:auto -6px;overflow-x:hidden;padding:6px 0}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-item{box-sizing:border-box;float:right;margin:0;padding:6px;text-align:center}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption,.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-icon{margin:0}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption{font-size:13px;margin:4px 0}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-1 .gallery-item{width:100%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-2 .gallery-item{width:50%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-3 .gallery-item{width:33.3333333333%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-4 .gallery-item{width:25%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-5 .gallery-item{width:20%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-6 .gallery-item{width:16.6666666667%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-7 .gallery-item{width:14.2857142857%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-8 .gallery-item{width:12.5%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-9 .gallery-item{width:11.1111111111%}.wp-block-freeform.block-library-rich-text__tinymce .gallery img{border:none;height:auto;max-width:100%;padding:0}div[data-type="core/freeform"]:before{border:1px solid #ddd;outline:1px solid #0000}@media not (prefers-reduced-motion){div[data-type="core/freeform"]:before{transition:border-color .1s linear,box-shadow .1s linear}}div[data-type="core/freeform"].is-selected:before{border-color:#1e1e1e}div[data-type="core/freeform"] .block-editor-block-contextual-toolbar+div{margin-top:0;padding-top:0}div[data-type="core/freeform"].is-selected .block-library-rich-text__tinymce:after{clear:both;content:"";display:table}.mce-toolbar-grp .mce-btn.mce-active button,.mce-toolbar-grp .mce-btn.mce-active i,.mce-toolbar-grp .mce-btn.mce-active:hover button,.mce-toolbar-grp .mce-btn.mce-active:hover i{color:#1e1e1e}.mce-toolbar-grp .mce-rtl .mce-flow-layout-item.mce-last{margin-left:0;margin-right:8px}.mce-toolbar-grp .mce-btn i{font-style:normal}.block-library-classic__toolbar{border:1px solid #ddd;border-bottom:none;border-radius:2px;display:none;margin:0 0 8px;padding:0;position:sticky;top:0;width:auto;z-index:31}div[data-type="core/freeform"].is-selected .block-library-classic__toolbar{border-color:#1e1e1e;display:block}.block-library-classic__toolbar .mce-tinymce{box-shadow:none}@media (min-width:600px){.block-library-classic__toolbar{padding:0}}.block-library-classic__toolbar:empty{background:#f5f5f5;border-bottom:1px solid #e2e4e7;display:block}.block-library-classic__toolbar:empty:before{color:#555d66;content:attr(data-placeholder);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:37px;padding:14px}.block-library-classic__toolbar div.mce-toolbar-grp{border-bottom:1px solid #1e1e1e}.block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar .mce-menubar>div,.block-library-classic__toolbar .mce-tinymce-inline,.block-library-classic__toolbar .mce-tinymce-inline>div,.block-library-classic__toolbar div.mce-toolbar-grp,.block-library-classic__toolbar div.mce-toolbar-grp>div{height:auto!important;width:100%!important}.block-library-classic__toolbar .mce-container-body.mce-abs-layout{overflow:visible}.block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar div.mce-toolbar-grp{position:static}.block-library-classic__toolbar .mce-toolbar-grp>div{padding:1px 3px}.block-library-classic__toolbar .mce-toolbar-grp .mce-toolbar:not(:first-child){display:none}.block-library-classic__toolbar.has-advanced-toolbar .mce-toolbar-grp .mce-toolbar{display:block}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{height:50vh!important}@media (min-width:960px){.block-editor-freeform-modal .block-editor-freeform-modal__content:not(.is-full-screen){height:9999rem}.block-editor-freeform-modal .block-editor-freeform-modal__content .components-modal__header+div{height:100%}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-tinymce{height:calc(100% - 52px)}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-container-body{display:flex;flex-direction:column;height:100%;min-width:50vw}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area{display:flex;flex-direction:column;flex-grow:1}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{flex-grow:1;height:10px!important}}.block-editor-freeform-modal__actions{margin-top:16px}:root :where(figure.wp-block-gallery){display:block}:root :where(figure.wp-block-gallery)>.blocks-gallery-caption{flex:0 0 100%}:root :where(figure.wp-block-gallery)>.blocks-gallery-media-placeholder-wrapper{flex-basis:100%}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice.is-error{display:block}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice__content{margin:4px 0}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice__dismiss{left:5px;position:absolute;top:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .components-placeholder__label{display:none}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .block-editor-media-placeholder__button{margin-bottom:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder{margin:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder .components-placeholder__label{display:flex}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder figcaption{z-index:2}:root :where(figure.wp-block-gallery) .components-spinner{margin-right:-9px;margin-top:-9px;position:absolute;right:50%;top:50%}.gallery-settings-buttons .components-button:first-child{margin-left:8px}.gallery-image-sizes .components-base-control__label{margin-bottom:4px}.gallery-image-sizes .gallery-image-sizes__loading{align-items:center;color:#757575;display:flex;font-size:12px}.gallery-image-sizes .components-spinner{margin:0 4px 0 8px}.blocks-gallery-item figure:not(.is-selected):focus,.blocks-gallery-item img:focus{outline:none}.blocks-gallery-item figure.is-selected:before{bottom:0;box-shadow:0 0 0 1px #fff inset,0 0 0 3px var(--wp-admin-theme-color) inset;content:"";left:0;outline:2px solid #0000;pointer-events:none;position:absolute;right:0;top:0;z-index:1}.blocks-gallery-item figure.is-transient img{opacity:.3}.blocks-gallery-item .block-editor-media-placeholder{height:100%;margin:0}.blocks-gallery-item .block-editor-media-placeholder .components-placeholder__label{display:flex}.wp-block-gallery ul.blocks-gallery-grid{margin:0;padding:0}@media (min-width:600px){.wp-block-update-gallery-modal{max-width:480px}}.wp-block-update-gallery-modal-buttons{display:flex;gap:12px;justify-content:flex-end}.wp-block-group .block-editor-block-list__insertion-point{left:0;right:0}[data-type="core/group"].is-selected .block-list-appender{margin-left:0;margin-right:0}[data-type="core/group"].is-selected .has-background .block-list-appender{margin-bottom:18px;margin-top:18px}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child{gap:inherit;pointer-events:none}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-default-block-appender__content,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{display:inherit;flex:1;flex-direction:inherit;width:100%}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child:after{border:1px dashed;content:"";display:flex;flex:1 0 40px;min-height:38px;pointer-events:none}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-button-block-appender,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{pointer-events:all}.block-library-html__edit .block-library-html__preview-overlay{height:100%;position:absolute;right:0;top:0;width:100%}.block-library-html__edit .block-editor-plain-text{background:#fff!important;border:1px solid #1e1e1e!important;border-radius:2px!important;box-shadow:none!important;box-sizing:border-box;color:#1e1e1e!important;direction:ltr;font-family:Menlo,Consolas,monaco,monospace!important;font-size:16px!important;max-height:250px;padding:12px!important}@media (min-width:600px){.block-library-html__edit .block-editor-plain-text{font-size:13px!important}}.block-library-html__edit .block-editor-plain-text:focus{border-color:var(--wp-admin-theme-color)!important;box-shadow:0 0 0 1px var(--wp-admin-theme-color)!important;outline:2px solid #0000!important}.wp-block-image.wp-block-image .block-editor-media-placeholder.is-small{min-height:60px}figure.wp-block-image:not(.wp-block){margin:0}.wp-block-image{position:relative}.wp-block-image .is-applying img,.wp-block-image.is-transient img{opacity:.3}.wp-block-image figcaption img{display:inline}.wp-block-image .components-spinner{margin:0;position:absolute;right:50%;top:50%;transform:translate(50%,-50%)}.wp-block-image__placeholder{aspect-ratio:4/3}.wp-block-image__placeholder.has-illustration:before{background:#fff;opacity:.8}.wp-block-image__placeholder .components-placeholder__illustration{opacity:.1}.wp-block-image .components-resizable-box__container{display:table}.wp-block-image .components-resizable-box__container img{display:block;height:inherit;width:inherit}.block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{left:0;margin:-1px 0;position:absolute;right:0}@media (min-width:600px){.block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{margin:-1px}}[data-align=full]>.wp-block-image img,[data-align=wide]>.wp-block-image img{height:auto;width:100%}.wp-block[data-align=center]>.wp-block-image,.wp-block[data-align=left]>.wp-block-image,.wp-block[data-align=right]>.wp-block-image{display:table}.wp-block[data-align=center]>.wp-block-image>figcaption,.wp-block[data-align=left]>.wp-block-image>figcaption,.wp-block[data-align=right]>.wp-block-image>figcaption{caption-side:bottom;display:table-caption}.wp-block[data-align=left]>.wp-block-image{margin:.5em 0 .5em 1em}.wp-block[data-align=right]>.wp-block-image{margin:.5em 1em .5em 0}.wp-block[data-align=center]>.wp-block-image{margin-left:auto;margin-right:auto;text-align:center}.wp-block[data-align]:has(>.wp-block-image){position:relative}.wp-block-image__crop-area{max-width:100%;overflow:hidden;position:relative;width:100%}.wp-block-image__crop-area .reactEasyCrop_Container{pointer-events:auto}.wp-block-image__crop-area .reactEasyCrop_Container .reactEasyCrop_Image{border:none;border-radius:0}.wp-block-image__crop-icon{align-items:center;display:flex;justify-content:center;min-width:48px;padding:0 8px}.wp-block-image__crop-icon svg{fill:currentColor}.wp-block-image__zoom .components-popover__content{min-width:260px;overflow:visible!important}.wp-block-image__toolbar_content_textarea__container{padding:8px}.wp-block-image__toolbar_content_textarea{width:250px}.wp-block-latest-posts>li{overflow:hidden}.wp-block-latest-posts li a>div{display:inline}:root :where(.wp-block-latest-posts){padding-right:2.5em}:root :where(.wp-block-latest-posts.is-grid),:root :where(.wp-block-latest-posts__list){padding-right:0}.wp-block-media-text__media{position:relative}.wp-block-media-text__media.is-transient img{opacity:.3}.wp-block-media-text__media .components-spinner{margin-right:-9px;margin-top:-9px;position:absolute;right:50%;top:50%}.wp-block-media-text .__resizable_base__{grid-column:1/span 2;grid-row:2}.wp-block-media-text .editor-media-container__resizer{width:100%!important}.wp-block-media-text.is-image-fill .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill .editor-media-container__resizer,.wp-block-media-text.is-image-fill-element .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill-element .editor-media-container__resizer{height:100%!important}.wp-block-media-text>.block-editor-block-list__layout>.block-editor-block-list__block{max-width:unset}.wp-block-media-text--placeholder-image{min-height:205px}.block-editor-block-list__block[data-type="core/more"]{margin-bottom:28px;margin-top:28px;max-width:100%;text-align:center}.wp-block-more{display:block;text-align:center;white-space:nowrap}.wp-block-more input[type=text]{background:#fff;border:none;border-radius:4px;box-shadow:none;color:#757575;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;height:24px;margin:0;max-width:100%;padding:6px 8px;position:relative;text-align:center;text-transform:uppercase;white-space:nowrap}.wp-block-more input[type=text]:focus{box-shadow:none}.wp-block-more:before{border-top:3px dashed #ccc;content:"";left:0;position:absolute;right:0;top:50%}.editor-styles-wrapper .wp-block-navigation ul{margin-bottom:0;margin-right:0;margin-top:0;padding-right:0}.editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block{margin:revert}.wp-block-navigation-item__label{display:inline}.wp-block-navigation-item,.wp-block-navigation__container{background-color:inherit}.wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover>.wp-block-navigation__submenu-container{opacity:0;visibility:hidden}.has-child.has-child-selected>.wp-block-navigation__submenu-container,.has-child.is-selected>.wp-block-navigation__submenu-container{display:flex;opacity:1;visibility:visible}.is-dragging-components-draggable .has-child.is-dragging-within>.wp-block-navigation__submenu-container{opacity:1;visibility:visible}.is-editing>.wp-block-navigation__container{display:flex;flex-direction:column;opacity:1;visibility:visible}.is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container{opacity:1;visibility:hidden}.is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container .block-editor-block-draggable-chip-wrapper{visibility:visible}.is-editing>.wp-block-navigation__submenu-container>.block-list-appender{display:block;position:static;width:100%}.is-editing>.wp-block-navigation__submenu-container>.block-list-appender .block-editor-button-block-appender{background:#1e1e1e;color:#fff;margin-left:0;margin-right:auto;padding:0;width:24px}.wp-block-navigation__submenu-container .block-list-appender{display:none}.block-library-colors-selector{width:auto}.block-library-colors-selector .block-library-colors-selector__toggle{display:block;margin:0 auto;padding:3px;width:auto}.block-library-colors-selector .block-library-colors-selector__icon-container{align-items:center;border-radius:4px;display:flex;height:30px;margin:0 auto;padding:3px;position:relative}.block-library-colors-selector .block-library-colors-selector__state-selection{border-radius:11px;box-shadow:inset 0 0 0 1px #0003;height:22px;line-height:20px;margin-left:auto;margin-right:auto;min-height:22px;min-width:22px;padding:2px;width:22px}.block-library-colors-selector .block-library-colors-selector__state-selection>svg{min-width:auto!important}.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg,.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg path{color:inherit}.block-library-colors-selector__popover .color-palette-controller-container{padding:16px}.block-library-colors-selector__popover .components-base-control__label{height:20px;line-height:20px}.block-library-colors-selector__popover .component-color-indicator{float:left;margin-top:2px}.block-library-colors-selector__popover .components-panel__body-title{display:none}.wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender{background-color:#1e1e1e;color:#fff;height:24px}.wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender.block-editor-button-block-appender.block-editor-button-block-appender{padding:0}.wp-block-navigation .wp-block .wp-block .block-editor-button-block-appender{background-color:initial;color:#1e1e1e}@keyframes loadingpulse{0%{opacity:1}50%{opacity:.5}to{opacity:1}}.components-placeholder.wp-block-navigation-placeholder{background:none;box-shadow:none;color:inherit;min-height:0;outline:none;padding:0}.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset{font-size:inherit}.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button{margin-bottom:0}.wp-block-navigation.is-selected .components-placeholder.wp-block-navigation-placeholder{color:#1e1e1e}.wp-block-navigation-placeholder__preview{align-items:center;background:#0000;color:currentColor;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;min-width:96px}.wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview{display:none}.wp-block-navigation-placeholder__preview:before{border:1px dashed;border-radius:inherit;bottom:0;content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0}.wp-block-navigation-placeholder__preview>svg{fill:currentColor}.wp-block-navigation.is-vertical .is-medium .components-placeholder__fieldset,.wp-block-navigation.is-vertical .is-small .components-placeholder__fieldset{min-height:90px}.wp-block-navigation.is-vertical .is-large .components-placeholder__fieldset{min-height:132px}.wp-block-navigation-placeholder__controls,.wp-block-navigation-placeholder__preview{align-items:flex-start;flex-direction:row;padding:6px 8px}.wp-block-navigation-placeholder__controls{background-color:#fff;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;display:none;float:right;position:relative;width:100%;z-index:1}.wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls{display:flex}.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr{display:none}.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions{align-items:flex-start;flex-direction:column}.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr{display:none}.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon{height:36px;margin-left:12px}.wp-block-navigation-placeholder__actions__indicator{align-items:center;display:flex;height:36px;justify-content:flex-start;line-height:0;margin-right:4px;padding:0 0 0 6px}.wp-block-navigation-placeholder__actions__indicator svg{margin-left:4px;fill:currentColor}.wp-block-navigation .components-placeholder.is-medium .components-placeholder__fieldset{flex-direction:row!important}.wp-block-navigation-placeholder__actions{align-items:center;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;gap:6px;height:100%}.wp-block-navigation-placeholder__actions .components-dropdown,.wp-block-navigation-placeholder__actions>.components-button{margin-left:0}.wp-block-navigation-placeholder__actions.wp-block-navigation-placeholder__actions hr{background-color:#1e1e1e;border:0;height:100%;margin:auto 0;max-height:16px;min-height:1px;min-width:1px}@media (min-width:600px){.wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close{display:none}}.wp-block-navigation__responsive-container.is-menu-open{position:fixed;top:155px}@media (min-width:782px){.wp-block-navigation__responsive-container.is-menu-open{right:36px;top:93px}}@media (min-width:960px){.wp-block-navigation__responsive-container.is-menu-open{right:160px}}.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{top:141px}.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{right:0;top:155px}@media (min-width:782px){.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{top:61px}}.is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{top:109px}body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open{bottom:0;left:0;right:0;top:0}.components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close,.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{color:inherit;height:auto;padding:0}.components-heading.wp-block-navigation-off-canvas-editor__title{margin:0}.wp-block-navigation-off-canvas-editor__header{margin-bottom:8px}.is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender{margin-top:16px}@keyframes fadein{0%{opacity:0}to{opacity:1}}.wp-block-navigation__loading-indicator-container{padding:8px 12px}.wp-block-navigation .wp-block-navigation__uncontrolled-inner-blocks-loading-indicator{margin-top:0}@keyframes fadeouthalf{0%{opacity:1}to{opacity:.5}}.wp-block-navigation-delete-menu-button{justify-content:center;margin-bottom:16px;width:100%}.components-button.is-link.wp-block-navigation-manage-menus-button{margin-bottom:16px}.wp-block-navigation__overlay-menu-preview{align-items:center;background-color:#f0f0f0;display:flex;height:64px!important;justify-content:space-between;margin-bottom:12px;padding:0 24px;width:100%}.wp-block-navigation__overlay-menu-preview.open{background-color:#fff;box-shadow:inset 0 0 0 1px #e0e0e0;outline:1px solid #0000}.wp-block-navigation-placeholder__actions hr+hr,.wp-block-navigation__toolbar-menu-selector.components-toolbar-group:empty{display:none}.wp-block-navigation__navigation-selector{margin-bottom:16px;width:100%}.wp-block-navigation__navigation-selector-button{border:1px solid;justify-content:space-between;width:100%}.wp-block-navigation__navigation-selector-button__icon{flex:0 0 auto}.wp-block-navigation__navigation-selector-button__label{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wp-block-navigation__navigation-selector-button--createnew{border:1px solid;margin-bottom:16px;width:100%}.wp-block-navigation__responsive-container-open.components-button{opacity:1}.wp-block-navigation__menu-inspector-controls{overflow-x:auto;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-width:thin;will-change:transform}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar{height:12px;width:12px}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-track{background-color:initial}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.wp-block-navigation__menu-inspector-controls:focus-within::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:focus::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:hover::-webkit-scrollbar-thumb{background-color:#949494}.wp-block-navigation__menu-inspector-controls:focus,.wp-block-navigation__menu-inspector-controls:focus-within,.wp-block-navigation__menu-inspector-controls:hover{scrollbar-color:#949494 #0000}@media (hover:none){.wp-block-navigation__menu-inspector-controls{scrollbar-color:#949494 #0000}}.wp-block-navigation__menu-inspector-controls__empty-message{margin-right:24px}.wp-block-navigation__overlay-menu-icon-toggle-group{margin-bottom:16px}.wp-block-navigation .block-list-appender{position:relative}.wp-block-navigation .has-child{cursor:pointer}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{z-index:29}.wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{height:auto!important;min-width:200px!important;opacity:1!important;overflow:visible!important;visibility:visible!important;width:auto!important}.wp-block-navigation-item .wp-block-navigation-item__content{cursor:text}.wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{min-width:20px}.wp-block-navigation-item .block-list-appender{margin:16px 16px 16px auto}.wp-block-navigation-link__invalid-item{color:#000}.wp-block-navigation-link__placeholder{background-image:none!important;box-shadow:none!important;position:relative;text-decoration:none!important}.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{-webkit-text-decoration:wavy underline;text-decoration:wavy underline;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;text-underline-offset:.25rem}.wp-block-navigation-link__placeholder.wp-block-navigation-item__content{cursor:pointer}.link-control-transform{border-top:1px solid #ccc;padding:0 16px 8px}.link-control-transform__subheading{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.link-control-transform__items{display:flex;justify-content:space-between}.link-control-transform__item{flex-basis:33%;flex-direction:column;gap:8px;height:auto}.wp-block-navigation-submenu{display:block}.wp-block-navigation-submenu .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{height:auto!important;min-width:200px!important;opacity:1!important;position:absolute;right:-1px;top:100%;visibility:visible!important;width:auto!important}@media (min-width:782px){.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{right:100%;top:-1px}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{background:#0000;content:"";display:block;height:100%;left:100%;position:absolute;width:.5em}}.block-editor-block-list__block[data-type="core/nextpage"]{margin-bottom:28px;margin-top:28px;max-width:100%;text-align:center}.wp-block-nextpage{display:block;text-align:center;white-space:nowrap}.wp-block-nextpage>span{background:#fff;border-radius:4px;color:#757575;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;height:24px;padding:6px 8px;position:relative;text-transform:uppercase}.wp-block-nextpage:before{border-top:3px dashed #ccc;content:"";left:0;position:absolute;right:0;top:50%}.wp-block-navigation .wp-block-page-list,.wp-block-navigation .wp-block-page-list>div{background-color:inherit}.wp-block-navigation.items-justified-space-between .wp-block-page-list,.wp-block-navigation.items-justified-space-between .wp-block-page-list>div{display:contents;flex:1}.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list>div,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list>div{flex:inherit}.wp-block-navigation .wp-block-navigation__submenu-container>.wp-block-page-list{display:block}.wp-block-pages-list__item__link{pointer-events:none}@media (min-width:600px){.wp-block-page-list-modal{max-width:480px}}.wp-block-page-list-modal-buttons{display:flex;gap:12px;justify-content:flex-end}.wp-block-page-list .open-on-click:focus-within>.wp-block-navigation__submenu-container{height:auto;min-width:200px;opacity:1;visibility:visible;width:auto}.wp-block-page-list__loading-indicator-container{padding:8px 12px}.block-editor-block-list__block[data-type="core/paragraph"].has-drop-cap:focus{min-height:auto!important}.block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{opacity:1}.block-editor-block-list__block[data-empty=true]+.block-editor-block-list__block[data-empty=true]:not([data-custom-placeholder=true]) [data-rich-text-placeholder]{opacity:0}.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-left[style*="writing-mode: vertical-lr"],.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-right[style*="writing-mode: vertical-rl"]{rotate:180deg}.is-zoomed-out .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{opacity:0}.wp-block-post-author__inspector-settings .components-base-control,.wp-block-post-author__inspector-settings .components-base-control:last-child{margin-bottom:0}.wp-block-post-excerpt .wp-block-post-excerpt__excerpt.is-inline{display:inline}.wp-block-pullquote.is-style-solid-color blockquote p{font-size:32px}.wp-block-pullquote.is-style-solid-color .wp-block-pullquote__citation{font-style:normal;text-transform:none}.wp-block-pullquote .wp-block-pullquote__citation{color:inherit}.wp-block-rss li a>div{display:inline}.wp-block-rss__placeholder-form .wp-block-rss__placeholder-input{flex:1 1 auto}.wp-block-rss .wp-block-rss{all:inherit;margin:0;padding:0}.wp-block[data-align=center] .wp-block-search .wp-block-search__inside-wrapper{margin:auto}.wp-block-search :where(.wp-block-search__button){align-items:center;border-radius:initial;display:flex;height:auto;justify-content:center;text-align:center}.wp-block-search__inspector-controls .components-base-control{margin-bottom:0}.block-editor-block-list__block[data-type="core/separator"]{padding-bottom:.1px;padding-top:.1px}.blocks-shortcode__textarea{background:#fff!important;border:1px solid #1e1e1e!important;border-radius:2px!important;box-shadow:none!important;box-sizing:border-box;color:#1e1e1e!important;font-family:Menlo,Consolas,monaco,monospace!important;font-size:16px!important;max-height:250px;padding:12px!important;resize:none}@media (min-width:600px){.blocks-shortcode__textarea{font-size:13px!important}}.blocks-shortcode__textarea:focus{border-color:var(--wp-admin-theme-color)!important;box-shadow:0 0 0 1px var(--wp-admin-theme-color)!important;outline:2px solid #0000!important}.wp-block-site-logo.aligncenter>div,.wp-block[data-align=center]>.wp-block-site-logo{display:table;margin-left:auto;margin-right:auto}.wp-block-site-logo a{pointer-events:none}.wp-block-site-logo .custom-logo-link{cursor:inherit}.wp-block-site-logo .custom-logo-link:focus{box-shadow:none}.wp-block-site-logo img{display:block;height:auto;max-width:100%}.wp-block-site-logo.is-transient{position:relative}.wp-block-site-logo.is-transient img{opacity:.3}.wp-block-site-logo.is-transient .components-spinner{margin:0;position:absolute;right:50%;top:50%;transform:translate(50%,-50%)}.wp-block-site-logo.wp-block-site-logo.is-default-size .components-placeholder{height:60px;width:60px}.wp-block-site-logo.wp-block-site-logo .components-resizable-box__container,.wp-block-site-logo.wp-block-site-logo>div{border-radius:inherit}.wp-block-site-logo.wp-block-site-logo .components-placeholder{align-items:center;border-radius:inherit;display:flex;height:100%;justify-content:center;min-height:48px;min-width:48px;padding:0;width:100%}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-drop-zone__content-text,.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-form-file-upload{display:none}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button{align-items:center;background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);border-radius:50%;border-style:solid;color:#fff;display:flex;height:48px;justify-content:center;margin:auto;padding:0;position:relative;width:48px}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button>svg{color:inherit}.block-library-site-logo__inspector-media-replace-container{position:relative}.block-library-site-logo__inspector-media-replace-container .components-drop-zone__content-icon{display:none}.block-library-site-logo__inspector-media-replace-container button.components-button{box-shadow:inset 0 0 0 1px #ccc;color:#1e1e1e;display:block;height:40px;width:100%}.block-library-site-logo__inspector-media-replace-container button.components-button:hover{color:var(--wp-admin-theme-color)}.block-library-site-logo__inspector-media-replace-container button.components-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-media-replace-title{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-library-site-logo__inspector-media-replace-container .components-dropdown{display:block}.block-library-site-logo__inspector-media-replace-container img{aspect-ratio:1;border-radius:50%!important;box-shadow:inset 0 0 0 1px #0003;min-width:20px;width:20px}.block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-readonly-logo-preview{display:flex;height:40px;padding:6px 12px}.wp-block-site-tagline__placeholder,.wp-block-site-title__placeholder{border:1px dashed;padding:1em 0}.wp-block-social-links .wp-social-link{line-height:0}.wp-block-social-link-anchor{align-items:center;background:none;border:0;box-sizing:border-box;color:currentColor;cursor:pointer;display:inline-flex;font-family:inherit;font-size:inherit;font-weight:inherit;height:auto;margin:0;opacity:1;padding:.25em}.wp-block-social-link-anchor:hover{transform:none}:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link button){padding-left:.6666666667em;padding-right:.6666666667em}:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link button){padding:0}.wp-block-social-link__toolbar_content_text{width:250px}.wp-block-social-links div.block-editor-url-input{display:inline-block;margin-right:8px}.wp-social-link:hover{transform:none}:root :where(.wp-block-social-links),:root :where(.wp-block-social-links.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link){padding:0}:root :where(.wp-block-social-links__social-placeholder .wp-social-link){padding:.25em}:root :where(.wp-block-social-links.is-style-pill-shape .wp-block-social-links__social-placeholder .wp-social-link){padding-left:.6666666667em;padding-right:.6666666667em}.wp-block-social-links__social-placeholder{display:flex;list-style:none;opacity:.8}.wp-block-social-links__social-placeholder>.wp-social-link{margin-left:0!important;margin-right:0!important;padding-left:0!important;padding-right:0!important;visibility:hidden;width:0!important}.wp-block-social-links__social-placeholder>.wp-block-social-links__social-placeholder-icons{display:flex}.wp-block-social-links__social-placeholder .wp-social-link:before{border-radius:50%;content:"";display:block;height:1em;width:1em}.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link:before{background:currentColor}.wp-block-social-links .wp-block-social-links__social-prompt{cursor:default;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:24px;list-style:none;margin-bottom:auto;margin-top:auto;min-height:24px;padding-left:8px}.wp-block.wp-block-social-links.aligncenter,.wp-block[data-align=center]>.wp-block-social-links{justify-content:center}.block-editor-block-preview__content .components-button:disabled{opacity:1}.wp-social-link.wp-social-link__is-incomplete{opacity:.5}.wp-block-social-links .is-selected .wp-social-link__is-incomplete,.wp-social-link.wp-social-link__is-incomplete:focus,.wp-social-link.wp-social-link__is-incomplete:hover{opacity:1}.wp-block-social-links .block-list-appender{position:static}.wp-block-social-links .block-list-appender .block-editor-inserter{font-size:inherit}.wp-block-social-links .block-list-appender .block-editor-button-block-appender{font-size:inherit;height:1.5em;padding:0;width:1.5em}.block-editor-block-list__block[data-type="core/spacer"]:before{content:"";display:block;height:100%;min-height:8px;min-width:8px;position:absolute;width:100%;z-index:1}.block-library-spacer__resize-container.has-show-handle,.wp-block-spacer.is-hovered .block-library-spacer__resize-container,.wp-block-spacer.is-selected.custom-sizes-disabled{background:#0000001a}.is-dark-theme .block-library-spacer__resize-container.has-show-handle,.is-dark-theme .wp-block-spacer.is-hovered .block-library-spacer__resize-container,.is-dark-theme .wp-block-spacer.is-selected.custom-sizes-disabled{background:#ffffff26}.block-library-spacer__resize-container{clear:both}.block-library-spacer__resize-container:not(.is-resizing){height:100%!important;width:100%!important}.block-library-spacer__resize-container .components-resizable-box__handle:before{content:none}.block-library-spacer__resize-container.resize-horizontal{height:100%!important;margin-bottom:0}.wp-block[data-align=center]>.wp-block-table,.wp-block[data-align=left]>.wp-block-table,.wp-block[data-align=right]>.wp-block-table{height:auto}.wp-block[data-align=center]>.wp-block-table table,.wp-block[data-align=left]>.wp-block-table table,.wp-block[data-align=right]>.wp-block-table table{width:auto}.wp-block[data-align=center]>.wp-block-table td,.wp-block[data-align=center]>.wp-block-table th,.wp-block[data-align=left]>.wp-block-table td,.wp-block[data-align=left]>.wp-block-table th,.wp-block[data-align=right]>.wp-block-table td,.wp-block[data-align=right]>.wp-block-table th{word-break:break-word}.wp-block[data-align=center]>.wp-block-table{text-align:initial}.wp-block[data-align=center]>.wp-block-table table{margin:0 auto}.wp-block-table td,.wp-block-table th{border:1px solid;padding:.5em}.wp-block-table td.is-selected,.wp-block-table th.is-selected{border-color:var(--wp-admin-theme-color);border-style:double;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.wp-block-table table.has-individual-borders td,.wp-block-table table.has-individual-borders th,.wp-block-table table.has-individual-borders tr,.wp-block-table table.has-individual-borders>*{border:1px solid}.blocks-table__placeholder-form.blocks-table__placeholder-form{align-items:flex-start;display:flex;flex-direction:column;gap:8px}@media (min-width:782px){.blocks-table__placeholder-form.blocks-table__placeholder-form{align-items:flex-end;flex-direction:row}}.blocks-table__placeholder-input{width:112px}.wp-block-tag-cloud .wp-block-tag-cloud{border:none;border-radius:inherit;margin:0;padding:0}.block-editor-template-part__selection-modal{z-index:1000001}.block-editor-template-part__selection-modal .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:1280px){.block-editor-template-part__selection-modal .block-editor-block-patterns-list{column-count:3}}.block-editor-template-part__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.block-library-template-part__selection-search{background:#fff;padding:16px 0;position:sticky;top:0;z-index:2}.block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{outline-color:var(--wp-block-synced-color)}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.has-editable-outline:after{border:none}.wp-block-text-columns .block-editor-rich-text__editable:focus{outline:1px solid #ddd}.wp-block[data-align=center]>.wp-block-video{text-align:center}.wp-block-video{position:relative}.wp-block-video.is-transient video{opacity:.3}.wp-block-video .components-spinner{margin-right:-9px;margin-top:-9px;position:absolute;right:50%;top:50%}.editor-video-poster-control .components-button{margin-left:8px}.block-library-video-tracks-editor{z-index:159990}.block-library-video-tracks-editor__track-list-track{padding-right:12px}.block-library-video-tracks-editor__single-track-editor-kind-select{max-width:240px}.block-library-video-tracks-editor__single-track-editor-edit-track-label,.block-library-video-tracks-editor__tracks-informative-message-title{color:#757575;display:block;font-size:11px;font-weight:500;margin-top:4px;text-transform:uppercase}.block-library-video-tracks-editor>.components-popover__content{width:360px}.block-library-video-tracks-editor__add-tracks-container .components-menu-group__label,.block-library-video-tracks-editor__track-list .components-menu-group__label{padding:0}.block-library-video-tracks-editor__tracks-informative-message{padding:8px}.block-library-video-tracks-editor__tracks-informative-message-description{margin-bottom:0}.block-library-query-pattern__selection-modal .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:1280px){.block-library-query-pattern__selection-modal .block-editor-block-patterns-list{column-count:3}}.block-library-query-pattern__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.block-library-query-pattern__selection-modal .block-library-query-pattern__selection-search{background:#fff;margin-bottom:-4px;padding:16px 0;position:sticky;top:0;transform:translateY(-4px);z-index:2}@media (min-width:600px){.wp-block-query__enhanced-pagination-modal{max-width:480px}}.block-editor-block-settings-menu__popover.is-expanded{overflow-y:scroll}.block-editor-block-settings-menu__popover .block-library-query-pattern__selection-content{height:100%}.block-editor-block-settings-menu__popover .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr;grid-gap:12px;min-width:280px}@media (min-width:600px){.block-editor-block-settings-menu__popover .block-editor-block-patterns-list{grid-template-columns:1fr 1fr;min-width:480px}}.block-editor-block-settings-menu__popover .block-editor-block-patterns-list__list-item{margin-bottom:0}.wp-block[data-align=center]>.wp-block-query-pagination{justify-content:center}:where(.editor-styles-wrapper) .wp-block-query-pagination{max-width:100%}:where(.editor-styles-wrapper) .wp-block-query-pagination.block-editor-block-list__layout{margin:0}.wp-block-query-pagination-numbers a{text-decoration:underline}.wp-block-query-pagination-numbers .page-numbers{margin-left:2px}.wp-block-query-pagination-numbers .page-numbers:last-child{margin-right:0}.wp-block-post-featured-image .block-editor-media-placeholder{-webkit-backdrop-filter:none;backdrop-filter:none;z-index:1}.wp-block-post-featured-image .components-placeholder,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder{align-items:center;display:flex;justify-content:center;min-height:200px;padding:0}.wp-block-post-featured-image .components-placeholder .components-form-file-upload,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-form-file-upload{display:none}.wp-block-post-featured-image .components-placeholder .components-button,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button{align-items:center;background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);border-radius:50%;border-style:solid;color:#fff;display:flex;height:48px;justify-content:center;margin:auto;padding:0;position:relative;width:48px}.wp-block-post-featured-image .components-placeholder .components-button>svg,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button>svg{color:inherit}.wp-block-post-featured-image .components-placeholder:where(.has-border-color),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where(.has-border-color),.wp-block-post-featured-image img:where(.has-border-color){border-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-top-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-color]),.wp-block-post-featured-image img:where([style*=border-top-color]){border-top-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-right-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-color]),.wp-block-post-featured-image img:where([style*=border-right-color]){border-left-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image img:where([style*=border-bottom-color]){border-bottom-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-left-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-color]),.wp-block-post-featured-image img:where([style*=border-left-color]){border-right-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-width]),.wp-block-post-featured-image img:where([style*=border-width]){border-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-top-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-width]),.wp-block-post-featured-image img:where([style*=border-top-width]){border-top-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-right-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-width]),.wp-block-post-featured-image img:where([style*=border-right-width]){border-left-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image img:where([style*=border-bottom-width]){border-bottom-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-left-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-width]),.wp-block-post-featured-image img:where([style*=border-left-width]){border-right-style:solid}.wp-block-post-featured-image[style*=height] .components-placeholder{height:100%;min-height:48px;min-width:48px;width:100%}.wp-block-post-featured-image>a{pointer-events:none}.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-button,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__instructions,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__label{opacity:1;pointer-events:auto}.wp-block-post-featured-image.is-transient{position:relative}.wp-block-post-featured-image.is-transient img{opacity:.3}.wp-block-post-featured-image.is-transient .components-spinner{position:absolute;right:50%;top:50%;transform:translate(50%,-50%)}div[data-type="core/post-featured-image"] img{display:block;height:auto;max-width:100%}.wp-block-post-comments-form *{pointer-events:none}.wp-block-post-comments-form .block-editor-warning *{pointer-events:auto}.wp-element-button{cursor:revert}.wp-element-button[role=textbox]{cursor:text}:root .editor-styles-wrapper .has-very-light-gray-background-color{background-color:#eee}:root .editor-styles-wrapper .has-very-dark-gray-background-color{background-color:#313131}:root .editor-styles-wrapper .has-very-light-gray-color{color:#eee}:root .editor-styles-wrapper .has-very-dark-gray-color{color:#313131}:root .editor-styles-wrapper .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(-135deg,#00d084,#0693e3)}:root .editor-styles-wrapper .has-purple-crush-gradient-background{background:linear-gradient(-135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .editor-styles-wrapper .has-hazy-dawn-gradient-background{background:linear-gradient(-135deg,#faaca8,#dad0ec)}:root .editor-styles-wrapper .has-subdued-olive-gradient-background{background:linear-gradient(-135deg,#fafae1,#67a671)}:root .editor-styles-wrapper .has-atomic-cream-gradient-background{background:linear-gradient(-135deg,#fdd79a,#004a59)}:root .editor-styles-wrapper .has-nightshade-gradient-background{background:linear-gradient(-135deg,#330968,#31cdcf)}:root .editor-styles-wrapper .has-midnight-gradient-background{background:linear-gradient(-135deg,#020381,#2874fc)}:where(.editor-styles-wrapper) .has-regular-font-size{font-size:16px}:where(.editor-styles-wrapper) .has-larger-font-size{font-size:42px}:where(.editor-styles-wrapper) iframe:not([frameborder]){border:0}.wp-block-audio :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-audio :where(figcaption){ color:#ffffffa6; } .wp-block-audio{ margin:0 0 1em; } .wp-block-code{ border:1px solid #ccc; border-radius:4px; font-family:Menlo,Consolas,monaco,monospace; padding:.8em 1em; } .wp-block-embed :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-embed :where(figcaption){ color:#ffffffa6; } .wp-block-embed{ margin:0 0 1em; } .blocks-gallery-caption{ color:#555; font-size:13px; text-align:center; } .is-dark-theme .blocks-gallery-caption{ color:#ffffffa6; } :root :where(.wp-block-image figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme :root :where(.wp-block-image figcaption){ color:#ffffffa6; } .wp-block-image{ margin:0 0 1em; } .wp-block-pullquote{ border-bottom:4px solid; border-top:4px solid; color:currentColor; margin-bottom:1.75em; } .wp-block-pullquote cite,.wp-block-pullquote footer,.wp-block-pullquote__citation{ color:currentColor; font-size:.8125em; font-style:normal; text-transform:uppercase; } .wp-block-quote{ border-right:.25em solid; margin:0 0 1.75em; padding-right:1em; } .wp-block-quote cite,.wp-block-quote footer{ color:currentColor; font-size:.8125em; font-style:normal; position:relative; } .wp-block-quote:where(.has-text-align-right){ border-left:.25em solid; border-right:none; padding-left:1em; padding-right:0; } .wp-block-quote:where(.has-text-align-center){ border:none; padding-right:0; } .wp-block-quote.is-large,.wp-block-quote.is-style-large,.wp-block-quote:where(.is-style-plain){ border:none; } .wp-block-search .wp-block-search__label{ font-weight:700; } .wp-block-search__button{ border:1px solid #ccc; padding:.375em .625em; } :where(.wp-block-group.has-background){ padding:1.25em 2.375em; } .wp-block-separator.has-css-opacity{ opacity:.4; } .wp-block-separator{ border:none; border-bottom:2px solid; margin-left:auto; margin-right:auto; } .wp-block-separator.has-alpha-channel-opacity{ opacity:1; } .wp-block-separator:not(.is-style-wide):not(.is-style-dots){ width:100px; } .wp-block-separator.has-background:not(.is-style-dots){ border-bottom:none; height:1px; } .wp-block-separator.has-background:not(.is-style-wide):not(.is-style-dots){ height:2px; } .wp-block-table{ margin:0 0 1em; } .wp-block-table td,.wp-block-table th{ word-break:normal; } .wp-block-table :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-table :where(figcaption){ color:#ffffffa6; } .wp-block-video :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-video :where(figcaption){ color:#ffffffa6; } .wp-block-video{ margin:0 0 1em; } :root :where(.wp-block-template-part.has-background){ margin-bottom:0; margin-top:0; padding:1.25em 2.375em; }.wp-element-button{cursor:revert}.wp-element-button[role=textbox]{cursor:text}.wp-block-button__link{ background-color:#32373c; border-radius:9999px; box-shadow:none; color:#fff; font-size:1.125em; padding:calc(.667em + 2px) calc(1.333em + 2px); text-decoration:none; } .wp-block-file__button{ background:#32373c; color:#fff; }.wp-element-button{ cursor:revert; } .wp-element-button[role=textbox]{ cursor:text; }.wp-block-audio :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-audio :where(figcaption){color:#ffffffa6}.wp-block-audio{margin:0 0 1em}.wp-block-code{border:1px solid #ccc;border-radius:4px;font-family:Menlo,Consolas,monaco,monospace;padding:.8em 1em}.wp-block-embed :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-embed :where(figcaption){color:#ffffffa6}.wp-block-embed{margin:0 0 1em}.blocks-gallery-caption{color:#555;font-size:13px;text-align:center}.is-dark-theme .blocks-gallery-caption{color:#ffffffa6}:root :where(.wp-block-image figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme :root :where(.wp-block-image figcaption){color:#ffffffa6}.wp-block-image{margin:0 0 1em}.wp-block-pullquote{border-bottom:4px solid;border-top:4px solid;color:currentColor;margin-bottom:1.75em}.wp-block-pullquote cite,.wp-block-pullquote footer,.wp-block-pullquote__citation{color:currentColor;font-size:.8125em;font-style:normal;text-transform:uppercase}.wp-block-quote{border-right:.25em solid;margin:0 0 1.75em;padding-right:1em}.wp-block-quote cite,.wp-block-quote footer{color:currentColor;font-size:.8125em;font-style:normal;position:relative}.wp-block-quote:where(.has-text-align-right){border-left:.25em solid;border-right:none;padding-left:1em;padding-right:0}.wp-block-quote:where(.has-text-align-center){border:none;padding-right:0}.wp-block-quote.is-large,.wp-block-quote.is-style-large,.wp-block-quote:where(.is-style-plain){border:none}.wp-block-search .wp-block-search__label{font-weight:700}.wp-block-search__button{border:1px solid #ccc;padding:.375em .625em}:where(.wp-block-group.has-background){padding:1.25em 2.375em}.wp-block-separator.has-css-opacity{opacity:.4}.wp-block-separator{border:none;border-bottom:2px solid;margin-left:auto;margin-right:auto}.wp-block-separator.has-alpha-channel-opacity{opacity:1}.wp-block-separator:not(.is-style-wide):not(.is-style-dots){width:100px}.wp-block-separator.has-background:not(.is-style-dots){border-bottom:none;height:1px}.wp-block-separator.has-background:not(.is-style-wide):not(.is-style-dots){height:2px}.wp-block-table{margin:0 0 1em}.wp-block-table td,.wp-block-table th{word-break:normal}.wp-block-table :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-table :where(figcaption){color:#ffffffa6}.wp-block-video :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-video :where(figcaption){color:#ffffffa6}.wp-block-video{margin:0 0 1em}:root :where(.wp-block-template-part.has-background){margin-bottom:0;margin-top:0;padding:1.25em 2.375em}html :where(.editor-styles-wrapper){ background:#fff; color:initial; font-family:serif; font-size:medium; line-height:normal; } :where(.editor-styles-wrapper) .wp-align-wrapper{ max-width:840px; } :where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-full,:where(.editor-styles-wrapper) .wp-align-wrapper>.wp-block{ max-width:none; } :where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-wide{ max-width:840px; } :where(.editor-styles-wrapper) a{ transition:none; } :where(.editor-styles-wrapper) code,:where(.editor-styles-wrapper) kbd{ background:inherit; font-family:monospace; font-size:inherit; margin:0; padding:0; } :where(.editor-styles-wrapper) p{ font-size:revert; line-height:revert; margin:revert; } :where(.editor-styles-wrapper) ol,:where(.editor-styles-wrapper) ul{ box-sizing:border-box; list-style-type:revert; margin:revert; padding:revert; } :where(.editor-styles-wrapper) ol ol,:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ol,:where(.editor-styles-wrapper) ul ul{ margin:revert; } :where(.editor-styles-wrapper) ol li,:where(.editor-styles-wrapper) ul li{ margin:revert; } :where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ul{ list-style-type:revert; } :where(.editor-styles-wrapper) h1,:where(.editor-styles-wrapper) h2,:where(.editor-styles-wrapper) h3,:where(.editor-styles-wrapper) h4,:where(.editor-styles-wrapper) h5,:where(.editor-styles-wrapper) h6{ color:revert; font-size:revert; font-weight:revert; line-height:revert; margin:revert; } :where(.editor-styles-wrapper) select{ -webkit-appearance:revert; background:revert; border:revert; border-radius:revert; box-shadow:revert; color:revert; cursor:revert; font-family:system-ui; font-size:revert; font-weight:revert; line-height:revert; margin:revert; max-width:revert; min-height:revert; outline:revert; padding:revert; text-shadow:revert; transform:revert; vertical-align:revert; } :where(.editor-styles-wrapper) select:disabled,:where(.editor-styles-wrapper) select:focus{ background-color:revert; background-image:revert; border-color:revert; box-shadow:revert; color:revert; cursor:revert; text-shadow:revert; transform:revert; }.wp-block-button__link{ background-color:#32373c; border-radius:9999px; box-shadow:none; color:#fff; font-size:1.125em; padding:calc(.667em + 2px) calc(1.333em + 2px); text-decoration:none; } .wp-block-file__button{ background:#32373c; color:#fff; }.wp-block-audio :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-audio :where(figcaption){color:#ffffffa6}.wp-block-audio{margin:0 0 1em}.wp-block-code{border:1px solid #ccc;border-radius:4px;font-family:Menlo,Consolas,monaco,monospace;padding:.8em 1em}.wp-block-embed :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-embed :where(figcaption){color:#ffffffa6}.wp-block-embed{margin:0 0 1em}.blocks-gallery-caption{color:#555;font-size:13px;text-align:center}.is-dark-theme .blocks-gallery-caption{color:#ffffffa6}:root :where(.wp-block-image figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme :root :where(.wp-block-image figcaption){color:#ffffffa6}.wp-block-image{margin:0 0 1em}.wp-block-pullquote{border-bottom:4px solid;border-top:4px solid;color:currentColor;margin-bottom:1.75em}.wp-block-pullquote cite,.wp-block-pullquote footer,.wp-block-pullquote__citation{color:currentColor;font-size:.8125em;font-style:normal;text-transform:uppercase}.wp-block-quote{border-left:.25em solid;margin:0 0 1.75em;padding-left:1em}.wp-block-quote cite,.wp-block-quote footer{color:currentColor;font-size:.8125em;font-style:normal;position:relative}.wp-block-quote:where(.has-text-align-right){border-left:none;border-right:.25em solid;padding-left:0;padding-right:1em}.wp-block-quote:where(.has-text-align-center){border:none;padding-left:0}.wp-block-quote.is-large,.wp-block-quote.is-style-large,.wp-block-quote:where(.is-style-plain){border:none}.wp-block-search .wp-block-search__label{font-weight:700}.wp-block-search__button{border:1px solid #ccc;padding:.375em .625em}:where(.wp-block-group.has-background){padding:1.25em 2.375em}.wp-block-separator.has-css-opacity{opacity:.4}.wp-block-separator{border:none;border-bottom:2px solid;margin-left:auto;margin-right:auto}.wp-block-separator.has-alpha-channel-opacity{opacity:1}.wp-block-separator:not(.is-style-wide):not(.is-style-dots){width:100px}.wp-block-separator.has-background:not(.is-style-dots){border-bottom:none;height:1px}.wp-block-separator.has-background:not(.is-style-wide):not(.is-style-dots){height:2px}.wp-block-table{margin:0 0 1em}.wp-block-table td,.wp-block-table th{word-break:normal}.wp-block-table :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-table :where(figcaption){color:#ffffffa6}.wp-block-video :where(figcaption){color:#555;font-size:13px;text-align:center}.is-dark-theme .wp-block-video :where(figcaption){color:#ffffffa6}.wp-block-video{margin:0 0 1em}:root :where(.wp-block-template-part.has-background){margin-bottom:0;margin-top:0;padding:1.25em 2.375em}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .wp-element-button{ cursor:pointer; } :root{ --wp--preset--font-size--normal:16px; --wp--preset--font-size--huge:42px; } :root .has-very-light-gray-background-color{ background-color:#eee; } :root .has-very-dark-gray-background-color{ background-color:#313131; } :root .has-very-light-gray-color{ color:#eee; } :root .has-very-dark-gray-color{ color:#313131; } :root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(135deg, #00d084, #0693e3); } :root .has-purple-crush-gradient-background{ background:linear-gradient(135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .has-hazy-dawn-gradient-background{ background:linear-gradient(135deg, #faaca8, #dad0ec); } :root .has-subdued-olive-gradient-background{ background:linear-gradient(135deg, #fafae1, #67a671); } :root .has-atomic-cream-gradient-background{ background:linear-gradient(135deg, #fdd79a, #004a59); } :root .has-nightshade-gradient-background{ background:linear-gradient(135deg, #330968, #31cdcf); } :root .has-midnight-gradient-background{ background:linear-gradient(135deg, #020381, #2874fc); } .has-regular-font-size{ font-size:1em; } .has-larger-font-size{ font-size:2.625em; } .has-normal-font-size{ font-size:var(--wp--preset--font-size--normal); } .has-huge-font-size{ font-size:var(--wp--preset--font-size--huge); } .has-text-align-center{ text-align:center; } .has-text-align-left{ text-align:left; } .has-text-align-right{ text-align:right; } #end-resizable-editor-section{ display:none; } .aligncenter{ clear:both; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } .screen-reader-text{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .screen-reader-text:focus{ background-color:#ddd; clip-path:none; color:#444; display:block; font-size:1em; height:auto; left:5px; line-height:normal; padding:15px 23px 14px; text-decoration:none; top:5px; width:auto; z-index:100000; } html :where(.has-border-color){ border-style:solid; } html :where([style*=border-top-color]){ border-top-style:solid; } html :where([style*=border-right-color]){ border-right-style:solid; } html :where([style*=border-bottom-color]){ border-bottom-style:solid; } html :where([style*=border-left-color]){ border-left-style:solid; } html :where([style*=border-width]){ border-style:solid; } html :where([style*=border-top-width]){ border-top-style:solid; } html :where([style*=border-right-width]){ border-right-style:solid; } html :where([style*=border-bottom-width]){ border-bottom-style:solid; } html :where([style*=border-left-width]){ border-left-style:solid; } html :where(img[class*=wp-image-]){ height:auto; max-width:100%; } :where(figure){ margin:0 0 1em; } html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height, 0px); } @media screen and (max-width:600px){ html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:0px; } }.wp-block-audio :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-audio :where(figcaption){ color:#ffffffa6; } .wp-block-audio{ margin:0 0 1em; } .wp-block-code{ border:1px solid #ccc; border-radius:4px; font-family:Menlo,Consolas,monaco,monospace; padding:.8em 1em; } .wp-block-embed :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-embed :where(figcaption){ color:#ffffffa6; } .wp-block-embed{ margin:0 0 1em; } .blocks-gallery-caption{ color:#555; font-size:13px; text-align:center; } .is-dark-theme .blocks-gallery-caption{ color:#ffffffa6; } :root :where(.wp-block-image figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme :root :where(.wp-block-image figcaption){ color:#ffffffa6; } .wp-block-image{ margin:0 0 1em; } .wp-block-pullquote{ border-bottom:4px solid; border-top:4px solid; color:currentColor; margin-bottom:1.75em; } .wp-block-pullquote cite,.wp-block-pullquote footer,.wp-block-pullquote__citation{ color:currentColor; font-size:.8125em; font-style:normal; text-transform:uppercase; } .wp-block-quote{ border-left:.25em solid; margin:0 0 1.75em; padding-left:1em; } .wp-block-quote cite,.wp-block-quote footer{ color:currentColor; font-size:.8125em; font-style:normal; position:relative; } .wp-block-quote:where(.has-text-align-right){ border-left:none; border-right:.25em solid; padding-left:0; padding-right:1em; } .wp-block-quote:where(.has-text-align-center){ border:none; padding-left:0; } .wp-block-quote.is-large,.wp-block-quote.is-style-large,.wp-block-quote:where(.is-style-plain){ border:none; } .wp-block-search .wp-block-search__label{ font-weight:700; } .wp-block-search__button{ border:1px solid #ccc; padding:.375em .625em; } :where(.wp-block-group.has-background){ padding:1.25em 2.375em; } .wp-block-separator.has-css-opacity{ opacity:.4; } .wp-block-separator{ border:none; border-bottom:2px solid; margin-left:auto; margin-right:auto; } .wp-block-separator.has-alpha-channel-opacity{ opacity:1; } .wp-block-separator:not(.is-style-wide):not(.is-style-dots){ width:100px; } .wp-block-separator.has-background:not(.is-style-dots){ border-bottom:none; height:1px; } .wp-block-separator.has-background:not(.is-style-wide):not(.is-style-dots){ height:2px; } .wp-block-table{ margin:0 0 1em; } .wp-block-table td,.wp-block-table th{ word-break:normal; } .wp-block-table :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-table :where(figcaption){ color:#ffffffa6; } .wp-block-video :where(figcaption){ color:#555; font-size:13px; text-align:center; } .is-dark-theme .wp-block-video :where(figcaption){ color:#ffffffa6; } .wp-block-video{ margin:0 0 1em; } :root :where(.wp-block-template-part.has-background){ margin-bottom:0; margin-top:0; padding:1.25em 2.375em; }.wp-block-button__link{background-color:#32373c;border-radius:9999px;box-shadow:none;color:#fff;font-size:1.125em;padding:calc(.667em + 2px) calc(1.333em + 2px);text-decoration:none}.wp-block-file__button{background:#32373c;color:#fff}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-element-button{cursor:pointer}:root{--wp--preset--font-size--normal:16px;--wp--preset--font-size--huge:42px}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(-135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(-135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(-135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(-135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(-135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(-135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(-135deg,#020381,#2874fc)}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}.has-text-align-center{text-align:center}.has-text-align-left{text-align:left}.has-text-align-right{text-align:right}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;line-height:normal;padding:15px 23px 14px;right:5px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-left-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-right-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-left-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-right-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}@charset "UTF-8";.wp-block-archives{box-sizing:border-box}.wp-block-archives-dropdown label{display:block}.wp-block-avatar{line-height:0}.wp-block-avatar,.wp-block-avatar img{box-sizing:border-box}.wp-block-avatar.aligncenter{text-align:center}.wp-block-audio{box-sizing:border-box}.wp-block-audio :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-audio audio{min-width:300px;width:100%}.wp-block-button__link{align-content:center;box-sizing:border-box;cursor:pointer;display:inline-block;height:100%;text-align:center;word-break:break-word}.wp-block-button__link.aligncenter{text-align:center}.wp-block-button__link.alignright{text-align:right}:where(.wp-block-button__link){border-radius:9999px;box-shadow:none;padding:calc(.667em + 2px) calc(1.333em + 2px);text-decoration:none}.wp-block-button[style*=text-decoration] .wp-block-button__link{text-decoration:inherit}.wp-block-buttons>.wp-block-button.has-custom-width{max-width:none}.wp-block-buttons>.wp-block-button.has-custom-width .wp-block-button__link{width:100%}.wp-block-buttons>.wp-block-button.has-custom-font-size .wp-block-button__link{font-size:inherit}.wp-block-buttons>.wp-block-button.wp-block-button__width-25{width:calc(25% - var(--wp--style--block-gap, .5em)*.75)}.wp-block-buttons>.wp-block-button.wp-block-button__width-50{width:calc(50% - var(--wp--style--block-gap, .5em)*.5)}.wp-block-buttons>.wp-block-button.wp-block-button__width-75{width:calc(75% - var(--wp--style--block-gap, .5em)*.25)}.wp-block-buttons>.wp-block-button.wp-block-button__width-100{flex-basis:100%;width:100%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-25{width:25%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-50{width:50%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-75{width:75%}.wp-block-button.is-style-squared,.wp-block-button__link.wp-block-button.is-style-squared{border-radius:0}.wp-block-button.no-border-radius,.wp-block-button__link.no-border-radius{border-radius:0!important}:root :where(.wp-block-button .wp-block-button__link.is-style-outline),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link){border:2px solid;padding:.667em 1.333em}:root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-text-color)){color:currentColor}:root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-background)){background-color:initial;background-image:none}.wp-block-buttons{box-sizing:border-box}.wp-block-buttons.is-vertical{flex-direction:column}.wp-block-buttons.is-vertical>.wp-block-button:last-child{margin-bottom:0}.wp-block-buttons>.wp-block-button{display:inline-block;margin:0}.wp-block-buttons.is-content-justification-left{justify-content:flex-start}.wp-block-buttons.is-content-justification-left.is-vertical{align-items:flex-start}.wp-block-buttons.is-content-justification-center{justify-content:center}.wp-block-buttons.is-content-justification-center.is-vertical{align-items:center}.wp-block-buttons.is-content-justification-right{justify-content:flex-end}.wp-block-buttons.is-content-justification-right.is-vertical{align-items:flex-end}.wp-block-buttons.is-content-justification-space-between{justify-content:space-between}.wp-block-buttons.aligncenter{text-align:center}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block-button.aligncenter{margin-left:auto;margin-right:auto;width:100%}.wp-block-buttons[style*=text-decoration] .wp-block-button,.wp-block-buttons[style*=text-decoration] .wp-block-button__link{text-decoration:inherit}.wp-block-buttons.has-custom-font-size .wp-block-button__link{font-size:inherit}.wp-block-buttons .wp-block-button__link{width:100%}.wp-block-button.aligncenter,.wp-block-calendar{text-align:center}.wp-block-calendar td,.wp-block-calendar th{border:1px solid;padding:.25em}.wp-block-calendar th{font-weight:400}.wp-block-calendar caption{background-color:inherit}.wp-block-calendar table{border-collapse:collapse;width:100%}.wp-block-calendar table:where(:not(.has-text-color)){color:#40464d}.wp-block-calendar table:where(:not(.has-text-color)) td,.wp-block-calendar table:where(:not(.has-text-color)) th{border-color:#ddd}.wp-block-calendar table.has-background th{background-color:inherit}.wp-block-calendar table.has-text-color th{color:inherit}:where(.wp-block-calendar table:not(.has-background) th){background:#ddd}.wp-block-categories{box-sizing:border-box}.wp-block-categories.alignleft{margin-right:2em}.wp-block-categories.alignright{margin-left:2em}.wp-block-categories.wp-block-categories-dropdown.aligncenter{text-align:center}.wp-block-categories .wp-block-categories__label{display:block;width:100%}.wp-block-code{box-sizing:border-box}.wp-block-code code{direction:ltr;display:block;font-family:inherit;overflow-wrap:break-word;text-align:initial;white-space:pre-wrap}.wp-block-columns{align-items:normal!important;box-sizing:border-box;display:flex;flex-wrap:wrap!important}@media (min-width:782px){.wp-block-columns{flex-wrap:nowrap!important}}.wp-block-columns.are-vertically-aligned-top{align-items:flex-start}.wp-block-columns.are-vertically-aligned-center{align-items:center}.wp-block-columns.are-vertically-aligned-bottom{align-items:flex-end}@media (max-width:781px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:100%!important}}@media (min-width:782px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column[style*=flex-basis]{flex-grow:0}}.wp-block-columns.is-not-stacked-on-mobile{flex-wrap:nowrap!important}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column[style*=flex-basis]{flex-grow:0}:where(.wp-block-columns){margin-bottom:1.75em}:where(.wp-block-columns.has-background){padding:1.25em 2.375em}.wp-block-column{flex-grow:1;min-width:0;overflow-wrap:break-word;word-break:break-word}.wp-block-column.is-vertically-aligned-top{align-self:flex-start}.wp-block-column.is-vertically-aligned-center{align-self:center}.wp-block-column.is-vertically-aligned-bottom{align-self:flex-end}.wp-block-column.is-vertically-aligned-stretch{align-self:stretch}.wp-block-column.is-vertically-aligned-bottom,.wp-block-column.is-vertically-aligned-center,.wp-block-column.is-vertically-aligned-top{width:100%}.wp-block-post-comments{box-sizing:border-box}.wp-block-post-comments .alignleft{float:right}.wp-block-post-comments .alignright{float:left}.wp-block-post-comments .navigation:after{clear:both;content:"";display:table}.wp-block-post-comments .commentlist{clear:both;list-style:none;margin:0;padding:0}.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-right:3.25em}.wp-block-post-comments .commentlist .comment p{font-size:1em;line-height:1.8;margin:1em 0}.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-post-comments .comment-author{line-height:1.5}.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:right;height:2.5em;margin-left:.75em;margin-top:.5em;width:2.5em}.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-post-comments .comment-meta{font-size:.875em;line-height:1.5}.wp-block-post-comments .comment-meta b{font-weight:400}.wp-block-post-comments .comment-meta .comment-awaiting-moderation{display:block;margin-bottom:1em;margin-top:1em}.wp-block-post-comments .comment-body .commentmetadata{font-size:.875em}.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments .comment-reply-title{margin-bottom:0}.wp-block-post-comments .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-right:.5em}.wp-block-post-comments .reply{font-size:.875em;margin-bottom:1.4em}.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-family:inherit;font-size:1em}.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}:where(.wp-block-post-comments input[type=submit]){border:none}.wp-block-comments{box-sizing:border-box}.wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{font-size:inherit;margin-bottom:.5em;margin-right:.5em}.wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{margin-right:0}.wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow{display:inline-block;margin-left:1ch}.wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-comments-pagination .wp-block-comments-pagination-next-arrow{display:inline-block;margin-right:1ch}.wp-block-comments-pagination .wp-block-comments-pagination-next-arrow:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-comments-pagination.aligncenter{justify-content:center}.wp-block-comment-template{box-sizing:border-box;list-style:none;margin-bottom:0;max-width:100%;padding:0}.wp-block-comment-template li{clear:both}.wp-block-comment-template ol{list-style:none;margin-bottom:0;max-width:100%;padding-right:2rem}.wp-block-comment-template.alignleft{float:right}.wp-block-comment-template.aligncenter{margin-left:auto;margin-right:auto;width:fit-content}.wp-block-comment-template.alignright{float:left}.wp-block-comment-date{box-sizing:border-box}.comment-awaiting-moderation{display:block;font-size:.875em;line-height:1.5}.wp-block-comment-author-name,.wp-block-comment-content,.wp-block-comment-edit-link,.wp-block-comment-reply-link{box-sizing:border-box}.wp-block-cover,.wp-block-cover-image{align-items:center;background-position:50%;box-sizing:border-box;direction:ltr;display:flex;justify-content:center;min-height:430px;overflow:hidden;overflow:clip;padding:1em;position:relative}.wp-block-cover .has-background-dim:not([class*=-background-color]),.wp-block-cover-image .has-background-dim:not([class*=-background-color]),.wp-block-cover-image.has-background-dim:not([class*=-background-color]),.wp-block-cover.has-background-dim:not([class*=-background-color]){background-color:#000}.wp-block-cover .has-background-dim.has-background-gradient,.wp-block-cover-image .has-background-dim.has-background-gradient{background-color:initial}.wp-block-cover-image.has-background-dim:before,.wp-block-cover.has-background-dim:before{background-color:inherit;content:""}.wp-block-cover .wp-block-cover__background,.wp-block-cover .wp-block-cover__gradient-background,.wp-block-cover-image .wp-block-cover__background,.wp-block-cover-image .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim:not(.has-background-gradient):before,.wp-block-cover.has-background-dim:not(.has-background-gradient):before{bottom:0;left:0;opacity:.5;position:absolute;right:0;top:0}.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-10:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-10:not(.has-background-gradient):before{opacity:.1}.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-20:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-20:not(.has-background-gradient):before{opacity:.2}.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-30:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-30:not(.has-background-gradient):before{opacity:.3}.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-40:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-40:not(.has-background-gradient):before{opacity:.4}.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-50:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-50:not(.has-background-gradient):before{opacity:.5}.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-60:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-60:not(.has-background-gradient):before{opacity:.6}.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-70:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-70:not(.has-background-gradient):before{opacity:.7}.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-80:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-80:not(.has-background-gradient):before{opacity:.8}.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-90:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-90:not(.has-background-gradient):before{opacity:.9}.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-100:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-100:not(.has-background-gradient):before{opacity:1}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0{opacity:0}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10{opacity:.1}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20{opacity:.2}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30{opacity:.3}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40{opacity:.4}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50{opacity:.5}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60{opacity:.6}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70{opacity:.7}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80{opacity:.8}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90{opacity:.9}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100{opacity:1}.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.alignleft,.wp-block-cover.alignright{max-width:420px;width:100%}.wp-block-cover-image.aligncenter,.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.aligncenter,.wp-block-cover.alignleft,.wp-block-cover.alignright{display:flex}.wp-block-cover .wp-block-cover__inner-container,.wp-block-cover-image .wp-block-cover__inner-container{color:inherit;direction:rtl;position:relative;width:100%}.wp-block-cover-image.is-position-top-left,.wp-block-cover.is-position-top-left{align-items:flex-start;justify-content:flex-start}.wp-block-cover-image.is-position-top-center,.wp-block-cover.is-position-top-center{align-items:flex-start;justify-content:center}.wp-block-cover-image.is-position-top-right,.wp-block-cover.is-position-top-right{align-items:flex-start;justify-content:flex-end}.wp-block-cover-image.is-position-center-left,.wp-block-cover.is-position-center-left{align-items:center;justify-content:flex-start}.wp-block-cover-image.is-position-center-center,.wp-block-cover.is-position-center-center{align-items:center;justify-content:center}.wp-block-cover-image.is-position-center-right,.wp-block-cover.is-position-center-right{align-items:center;justify-content:flex-end}.wp-block-cover-image.is-position-bottom-left,.wp-block-cover.is-position-bottom-left{align-items:flex-end;justify-content:flex-start}.wp-block-cover-image.is-position-bottom-center,.wp-block-cover.is-position-bottom-center{align-items:flex-end;justify-content:center}.wp-block-cover-image.is-position-bottom-right,.wp-block-cover.is-position-bottom-right{align-items:flex-end;justify-content:flex-end}.wp-block-cover-image.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container{margin:0}.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container{margin:0;width:auto}.wp-block-cover .wp-block-cover__image-background,.wp-block-cover video.wp-block-cover__video-background,.wp-block-cover-image .wp-block-cover__image-background,.wp-block-cover-image video.wp-block-cover__video-background{border:none;bottom:0;box-shadow:none;height:100%;left:0;margin:0;max-height:none;max-width:none;object-fit:cover;outline:none;padding:0;position:absolute;right:0;top:0;width:100%}.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:fixed;background-repeat:no-repeat;background-size:cover}@supports (-webkit-touch-callout:inherit){.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:scroll}}@media (prefers-reduced-motion:reduce){.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:scroll}}.wp-block-cover-image.is-repeated,.wp-block-cover.is-repeated,.wp-block-cover__image-background.is-repeated,video.wp-block-cover__video-background.is-repeated{background-repeat:repeat;background-size:auto}.wp-block-cover-image-text,.wp-block-cover-image-text a,.wp-block-cover-image-text a:active,.wp-block-cover-image-text a:focus,.wp-block-cover-image-text a:hover,.wp-block-cover-text,.wp-block-cover-text a,.wp-block-cover-text a:active,.wp-block-cover-text a:focus,.wp-block-cover-text a:hover,section.wp-block-cover-image h2,section.wp-block-cover-image h2 a,section.wp-block-cover-image h2 a:active,section.wp-block-cover-image h2 a:focus,section.wp-block-cover-image h2 a:hover{color:#fff}.wp-block-cover-image .wp-block-cover.has-left-content{justify-content:flex-start}.wp-block-cover-image .wp-block-cover.has-right-content{justify-content:flex-end}.wp-block-cover-image.has-left-content .wp-block-cover-image-text,.wp-block-cover.has-left-content .wp-block-cover-text,section.wp-block-cover-image.has-left-content>h2{margin-right:0;text-align:right}.wp-block-cover-image.has-right-content .wp-block-cover-image-text,.wp-block-cover.has-right-content .wp-block-cover-text,section.wp-block-cover-image.has-right-content>h2{margin-left:0;text-align:left}.wp-block-cover .wp-block-cover-text,.wp-block-cover-image .wp-block-cover-image-text,section.wp-block-cover-image>h2{font-size:2em;line-height:1.25;margin-bottom:0;max-width:840px;padding:.44em;text-align:center;z-index:1}:where(.wp-block-cover-image:not(.has-text-color)),:where(.wp-block-cover:not(.has-text-color)){color:#fff}:where(.wp-block-cover-image.is-light:not(.has-text-color)),:where(.wp-block-cover.is-light:not(.has-text-color)){color:#000}:root :where(.wp-block-cover h1:not(.has-text-color)),:root :where(.wp-block-cover h2:not(.has-text-color)),:root :where(.wp-block-cover h3:not(.has-text-color)),:root :where(.wp-block-cover h4:not(.has-text-color)),:root :where(.wp-block-cover h5:not(.has-text-color)),:root :where(.wp-block-cover h6:not(.has-text-color)),:root :where(.wp-block-cover p:not(.has-text-color)){color:inherit}body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__image-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__video-background{z-index:0}body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__gradient-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)).has-background-dim:not(.has-background-gradient):before{z-index:1}.has-modal-open body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container{z-index:auto}.wp-block-details{box-sizing:border-box}.wp-block-details summary{cursor:pointer}.wp-block-embed.alignleft,.wp-block-embed.alignright,.wp-block[data-align=left]>[data-type="core/embed"],.wp-block[data-align=right]>[data-type="core/embed"]{max-width:360px;width:100%}.wp-block-embed.alignleft .wp-block-embed__wrapper,.wp-block-embed.alignright .wp-block-embed__wrapper,.wp-block[data-align=left]>[data-type="core/embed"] .wp-block-embed__wrapper,.wp-block[data-align=right]>[data-type="core/embed"] .wp-block-embed__wrapper{min-width:280px}.wp-block-cover .wp-block-embed{min-height:240px;min-width:320px}.wp-block-embed{overflow-wrap:break-word}.wp-block-embed :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-embed iframe{max-width:100%}.wp-block-embed__wrapper{position:relative}.wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper:before{content:"";display:block;padding-top:50%}.wp-embed-responsive .wp-has-aspect-ratio iframe{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.wp-embed-responsive .wp-embed-aspect-21-9 .wp-block-embed__wrapper:before{padding-top:42.85%}.wp-embed-responsive .wp-embed-aspect-18-9 .wp-block-embed__wrapper:before{padding-top:50%}.wp-embed-responsive .wp-embed-aspect-16-9 .wp-block-embed__wrapper:before{padding-top:56.25%}.wp-embed-responsive .wp-embed-aspect-4-3 .wp-block-embed__wrapper:before{padding-top:75%}.wp-embed-responsive .wp-embed-aspect-1-1 .wp-block-embed__wrapper:before{padding-top:100%}.wp-embed-responsive .wp-embed-aspect-9-16 .wp-block-embed__wrapper:before{padding-top:177.77%}.wp-embed-responsive .wp-embed-aspect-1-2 .wp-block-embed__wrapper:before{padding-top:200%}.wp-block-file{box-sizing:border-box}.wp-block-file:not(.wp-element-button){font-size:.8em}.wp-block-file.aligncenter{text-align:center}.wp-block-file.alignright{text-align:right}.wp-block-file *+.wp-block-file__button{margin-right:.75em}:where(.wp-block-file){margin-bottom:1.5em}.wp-block-file__embed{margin-bottom:1em}:where(.wp-block-file__button){border-radius:2em;display:inline-block;padding:.5em 1em}:where(.wp-block-file__button):is(a):active,:where(.wp-block-file__button):is(a):focus,:where(.wp-block-file__button):is(a):hover,:where(.wp-block-file__button):is(a):visited{box-shadow:none;color:#fff;opacity:.85;text-decoration:none}.wp-block-form-input__label{display:flex;flex-direction:column;gap:.25em;margin-bottom:.5em;width:100%}.wp-block-form-input__label.is-label-inline{align-items:center;flex-direction:row;gap:.5em}.wp-block-form-input__label.is-label-inline .wp-block-form-input__label-content{margin-bottom:.5em}.wp-block-form-input__label:has(input[type=checkbox]){flex-direction:row;width:fit-content}.wp-block-form-input__label:has(input[type=checkbox]) .wp-block-form-input__label-content{margin:0}.wp-block-form-input__label:has(.wp-block-form-input__label-content+input[type=checkbox]){flex-direction:row-reverse}.wp-block-form-input__label-content{width:fit-content}.wp-block-form-input__input{font-size:1em;margin-bottom:.5em;padding:0 .5em}.wp-block-form-input__input[type=date],.wp-block-form-input__input[type=datetime-local],.wp-block-form-input__input[type=datetime],.wp-block-form-input__input[type=email],.wp-block-form-input__input[type=month],.wp-block-form-input__input[type=number],.wp-block-form-input__input[type=password],.wp-block-form-input__input[type=search],.wp-block-form-input__input[type=tel],.wp-block-form-input__input[type=text],.wp-block-form-input__input[type=time],.wp-block-form-input__input[type=url],.wp-block-form-input__input[type=week]{border:1px solid;line-height:2;min-height:2em}textarea.wp-block-form-input__input{min-height:10em}.blocks-gallery-grid:not(.has-nested-images),.wp-block-gallery:not(.has-nested-images){display:flex;flex-wrap:wrap;list-style-type:none;margin:0;padding:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item{display:flex;flex-direction:column;flex-grow:1;justify-content:center;margin:0 0 1em 1em;position:relative;width:calc(50% - 1em)}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n){margin-left:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figure,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figure{align-items:flex-end;display:flex;height:100%;justify-content:flex-start;margin:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item img{display:block;height:auto;max-width:100%;width:auto}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption{background:linear-gradient(0deg,#000000b3,#0000004d 70%,#0000);bottom:0;box-sizing:border-box;color:#fff;font-size:.8em;margin:0;max-height:100%;overflow:auto;padding:3em .77em .7em;position:absolute;text-align:center;width:100%;z-index:2}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption img{display:inline}.blocks-gallery-grid:not(.has-nested-images) figcaption,.wp-block-gallery:not(.has-nested-images) figcaption{flex-grow:1}.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item img{flex:1;height:100%;object-fit:cover;width:100%}.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item{margin-left:0;width:100%}@media (min-width:600px){.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item{margin-left:1em;width:calc(33.33333% - .66667em)}.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item{margin-left:1em;width:calc(25% - .75em)}.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item{margin-left:1em;width:calc(20% - .8em)}.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item{margin-left:1em;width:calc(16.66667% - .83333em)}.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item{margin-left:1em;width:calc(14.28571% - .85714em)}.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item{margin-left:1em;width:calc(12.5% - .875em)}.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n){margin-left:0}}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:last-child,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:last-child{margin-left:0}.blocks-gallery-grid:not(.has-nested-images).alignleft,.blocks-gallery-grid:not(.has-nested-images).alignright,.wp-block-gallery:not(.has-nested-images).alignleft,.wp-block-gallery:not(.has-nested-images).alignright{max-width:420px;width:100%}.blocks-gallery-grid:not(.has-nested-images).aligncenter .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images).aligncenter .blocks-gallery-item figure{justify-content:center}.wp-block-gallery:not(.is-cropped) .blocks-gallery-item{align-self:flex-start}figure.wp-block-gallery.has-nested-images{align-items:normal}.wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image){margin:0;width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)/2)}.wp-block-gallery.has-nested-images figure.wp-block-image{box-sizing:border-box;display:flex;flex-direction:column;flex-grow:1;justify-content:center;max-width:100%;position:relative}.wp-block-gallery.has-nested-images figure.wp-block-image>a,.wp-block-gallery.has-nested-images figure.wp-block-image>div{flex-direction:column;flex-grow:1;margin:0}.wp-block-gallery.has-nested-images figure.wp-block-image img{display:block;height:auto;max-width:100%!important;width:auto}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{bottom:0;left:0;max-height:100%;position:absolute;right:0}.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);content:"";height:100%;-webkit-mask-image:linear-gradient(0deg,#000 20%,#0000);mask-image:linear-gradient(0deg,#000 20%,#0000);max-height:40%}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption{background:linear-gradient(0deg,#0006,#0000);box-sizing:border-box;color:#fff;font-size:13px;margin:0;overflow:auto;padding:1em;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-width:thin;text-align:center;text-shadow:0 0 1.5px #000;will-change:transform}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar{height:12px;width:12px}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-track{background-color:initial}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover::-webkit-scrollbar-thumb{background-color:#fffc}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover{scrollbar-color:#fffc #0000}@media (hover:none){.wp-block-gallery.has-nested-images figure.wp-block-image figcaption{scrollbar-color:#fffc #0000}}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption img{display:inline}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption a{color:inherit}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border img{box-sizing:border-box}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>a,.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>div,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>a,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>div{flex:1 1 auto}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded figcaption{background:none;color:inherit;flex:initial;margin:0;padding:10px 10px 9px;position:relative;text-shadow:none}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border:before,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded:before{content:none}.wp-block-gallery.has-nested-images figcaption{flex-basis:100%;flex-grow:1;text-align:center}.wp-block-gallery.has-nested-images:not(.is-cropped) figure.wp-block-image:not(#individual-image){margin-bottom:auto;margin-top:0}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image){align-self:inherit}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>div:not(.components-drop-zone){display:flex}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) img{flex:1 0 0%;height:100%;object-fit:cover;width:100%}.wp-block-gallery.has-nested-images.columns-1 figure.wp-block-image:not(#individual-image){width:100%}@media (min-width:600px){.wp-block-gallery.has-nested-images.columns-3 figure.wp-block-image:not(#individual-image){width:calc(33.33333% - var(--wp--style--unstable-gallery-gap, 16px)*.66667)}.wp-block-gallery.has-nested-images.columns-4 figure.wp-block-image:not(#individual-image){width:calc(25% - var(--wp--style--unstable-gallery-gap, 16px)*.75)}.wp-block-gallery.has-nested-images.columns-5 figure.wp-block-image:not(#individual-image){width:calc(20% - var(--wp--style--unstable-gallery-gap, 16px)*.8)}.wp-block-gallery.has-nested-images.columns-6 figure.wp-block-image:not(#individual-image){width:calc(16.66667% - var(--wp--style--unstable-gallery-gap, 16px)*.83333)}.wp-block-gallery.has-nested-images.columns-7 figure.wp-block-image:not(#individual-image){width:calc(14.28571% - var(--wp--style--unstable-gallery-gap, 16px)*.85714)}.wp-block-gallery.has-nested-images.columns-8 figure.wp-block-image:not(#individual-image){width:calc(12.5% - var(--wp--style--unstable-gallery-gap, 16px)*.875)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image){width:calc(33.33% - var(--wp--style--unstable-gallery-gap, 16px)*.66667)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2),.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2)~figure.wp-block-image:not(#individual-image){width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)*.5)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:last-child{width:100%}}.wp-block-gallery.has-nested-images.alignleft,.wp-block-gallery.has-nested-images.alignright{max-width:420px;width:100%}.wp-block-gallery.has-nested-images.aligncenter{justify-content:center}.wp-block-group{box-sizing:border-box}:where(.wp-block-group.wp-block-group-is-layout-constrained){position:relative}h1.has-background,h2.has-background,h3.has-background,h4.has-background,h5.has-background,h6.has-background{padding:1.25em 2.375em}h1.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h1.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h2.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h2.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h3.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h3.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h4.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h4.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h5.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h5.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h6.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h6.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]){rotate:180deg}.wp-block-image>a,.wp-block-image>figure>a{display:inline-block}.wp-block-image img{box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom}@media not (prefers-reduced-motion){.wp-block-image img.hide{visibility:hidden}.wp-block-image img.show{animation:show-content-image .4s}}.wp-block-image[style*=border-radius] img,.wp-block-image[style*=border-radius]>a{border-radius:inherit}.wp-block-image.has-custom-border img{box-sizing:border-box}.wp-block-image.aligncenter{text-align:center}.wp-block-image.alignfull>a,.wp-block-image.alignwide>a{width:100%}.wp-block-image.alignfull img,.wp-block-image.alignwide img{height:auto;width:100%}.wp-block-image .aligncenter,.wp-block-image .alignleft,.wp-block-image .alignright,.wp-block-image.aligncenter,.wp-block-image.alignleft,.wp-block-image.alignright{display:table}.wp-block-image .aligncenter>figcaption,.wp-block-image .alignleft>figcaption,.wp-block-image .alignright>figcaption,.wp-block-image.aligncenter>figcaption,.wp-block-image.alignleft>figcaption,.wp-block-image.alignright>figcaption{caption-side:bottom;display:table-caption}.wp-block-image .alignleft{float:left;margin:.5em 1em .5em 0}.wp-block-image .alignright{float:right;margin:.5em 0 .5em 1em}.wp-block-image .aligncenter{margin-left:auto;margin-right:auto}.wp-block-image :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-image.is-style-circle-mask img{border-radius:9999px}@supports ((-webkit-mask-image:none) or (mask-image:none)) or (-webkit-mask-image:none){.wp-block-image.is-style-circle-mask img{border-radius:0;-webkit-mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>');mask-mode:alpha;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}}:root :where(.wp-block-image.is-style-rounded img,.wp-block-image .is-style-rounded img){border-radius:9999px}.wp-block-image figure{margin:0}.wp-lightbox-container{display:flex;flex-direction:column;position:relative}.wp-lightbox-container img{cursor:zoom-in}.wp-lightbox-container img:hover+button{opacity:1}.wp-lightbox-container button{align-items:center;-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background-color:#5a5a5a40;border:none;border-radius:4px;cursor:zoom-in;display:flex;height:20px;justify-content:center;left:16px;opacity:0;padding:0;position:absolute;text-align:center;top:16px;width:20px;z-index:100}@media not (prefers-reduced-motion){.wp-lightbox-container button{transition:opacity .2s ease}}.wp-lightbox-container button:focus-visible{outline:3px auto #5a5a5a40;outline:3px auto -webkit-focus-ring-color;outline-offset:3px}.wp-lightbox-container button:hover{cursor:pointer;opacity:1}.wp-lightbox-container button:focus{opacity:1}.wp-lightbox-container button:focus,.wp-lightbox-container button:hover,.wp-lightbox-container button:not(:hover):not(:active):not(.has-background){background-color:#5a5a5a40;border:none}.wp-lightbox-overlay{box-sizing:border-box;cursor:zoom-out;height:100vh;overflow:hidden;position:fixed;right:0;top:0;visibility:hidden;width:100%;z-index:100000}.wp-lightbox-overlay .close-button{align-items:center;cursor:pointer;display:flex;justify-content:center;left:calc(env(safe-area-inset-left) + 16px);min-height:40px;min-width:40px;padding:0;position:absolute;top:calc(env(safe-area-inset-top) + 16px);z-index:5000000}.wp-lightbox-overlay .close-button:focus,.wp-lightbox-overlay .close-button:hover,.wp-lightbox-overlay .close-button:not(:hover):not(:active):not(.has-background){background:none;border:none}.wp-lightbox-overlay .lightbox-image-container{height:var(--wp--lightbox-container-height);overflow:hidden;position:absolute;right:50%;top:50%;transform:translate(50%,-50%);transform-origin:top right;width:var(--wp--lightbox-container-width);z-index:9999999999}.wp-lightbox-overlay .wp-block-image{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;margin:0;position:relative;transform-origin:100% 0;width:100%;z-index:3000000}.wp-lightbox-overlay .wp-block-image img{height:var(--wp--lightbox-image-height);min-height:var(--wp--lightbox-image-height);min-width:var(--wp--lightbox-image-width);width:var(--wp--lightbox-image-width)}.wp-lightbox-overlay .wp-block-image figcaption{display:none}.wp-lightbox-overlay button{background:none;border:none}.wp-lightbox-overlay .scrim{background-color:#fff;height:100%;opacity:.9;position:absolute;width:100%;z-index:2000000}.wp-lightbox-overlay.active{visibility:visible}@media not (prefers-reduced-motion){.wp-lightbox-overlay.active{animation:turn-on-visibility .25s both}.wp-lightbox-overlay.active img{animation:turn-on-visibility .35s both}.wp-lightbox-overlay.show-closing-animation:not(.active){animation:turn-off-visibility .35s both}.wp-lightbox-overlay.show-closing-animation:not(.active) img{animation:turn-off-visibility .25s both}.wp-lightbox-overlay.zoom.active{animation:none;opacity:1;visibility:visible}.wp-lightbox-overlay.zoom.active .lightbox-image-container{animation:lightbox-zoom-in .4s}.wp-lightbox-overlay.zoom.active .lightbox-image-container img{animation:none}.wp-lightbox-overlay.zoom.active .scrim{animation:turn-on-visibility .4s forwards}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active){animation:none}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container{animation:lightbox-zoom-out .4s}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container img{animation:none}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .scrim{animation:turn-off-visibility .4s forwards}}@keyframes show-content-image{0%{visibility:hidden}99%{visibility:hidden}to{visibility:visible}}@keyframes turn-on-visibility{0%{opacity:0}to{opacity:1}}@keyframes turn-off-visibility{0%{opacity:1;visibility:visible}99%{opacity:0;visibility:visible}to{opacity:0;visibility:hidden}}@keyframes lightbox-zoom-in{0%{transform:translate(calc(((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position))*-1),calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale))}to{transform:translate(50%,-50%) scale(1)}}@keyframes lightbox-zoom-out{0%{transform:translate(50%,-50%) scale(1);visibility:visible}99%{visibility:visible}to{transform:translate(calc(((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position))*-1),calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale));visibility:hidden}}ol.wp-block-latest-comments{box-sizing:border-box;margin-right:0}:where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment)){line-height:1.1}:where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment-excerpt p)){line-height:1.8}.has-dates :where(.wp-block-latest-comments:not([style*=line-height])),.has-excerpts :where(.wp-block-latest-comments:not([style*=line-height])){line-height:1.5}.wp-block-latest-comments .wp-block-latest-comments{padding-right:0}.wp-block-latest-comments__comment{list-style:none;margin-bottom:1em}.has-avatars .wp-block-latest-comments__comment{list-style:none;min-height:2.25em}.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-excerpt,.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-meta{margin-right:3.25em}.wp-block-latest-comments__comment-excerpt p{font-size:.875em;margin:.36em 0 1.4em}.wp-block-latest-comments__comment-date{display:block;font-size:.75em}.wp-block-latest-comments .avatar,.wp-block-latest-comments__comment-avatar{border-radius:1.5em;display:block;float:right;height:2.5em;margin-left:.75em;width:2.5em}.wp-block-latest-comments[class*=-font-size] a,.wp-block-latest-comments[style*=font-size] a{font-size:inherit}.wp-block-latest-posts{box-sizing:border-box}.wp-block-latest-posts.alignleft{margin-right:2em}.wp-block-latest-posts.alignright{margin-left:2em}.wp-block-latest-posts.wp-block-latest-posts__list{list-style:none}.wp-block-latest-posts.wp-block-latest-posts__list li{clear:both;overflow-wrap:break-word}.wp-block-latest-posts.is-grid{display:flex;flex-wrap:wrap}.wp-block-latest-posts.is-grid li{margin:0 0 1.25em 1.25em;width:100%}@media (min-width:600px){.wp-block-latest-posts.columns-2 li{width:calc(50% - .625em)}.wp-block-latest-posts.columns-2 li:nth-child(2n){margin-left:0}.wp-block-latest-posts.columns-3 li{width:calc(33.33333% - .83333em)}.wp-block-latest-posts.columns-3 li:nth-child(3n){margin-left:0}.wp-block-latest-posts.columns-4 li{width:calc(25% - .9375em)}.wp-block-latest-posts.columns-4 li:nth-child(4n){margin-left:0}.wp-block-latest-posts.columns-5 li{width:calc(20% - 1em)}.wp-block-latest-posts.columns-5 li:nth-child(5n){margin-left:0}.wp-block-latest-posts.columns-6 li{width:calc(16.66667% - 1.04167em)}.wp-block-latest-posts.columns-6 li:nth-child(6n){margin-left:0}}:root :where(.wp-block-latest-posts.is-grid){padding:0}:root :where(.wp-block-latest-posts.wp-block-latest-posts__list){padding-right:0}.wp-block-latest-posts__post-author,.wp-block-latest-posts__post-date{display:block;font-size:.8125em}.wp-block-latest-posts__post-excerpt,.wp-block-latest-posts__post-full-content{margin-bottom:1em;margin-top:.5em}.wp-block-latest-posts__featured-image a{display:inline-block}.wp-block-latest-posts__featured-image img{height:auto;max-width:100%;width:auto}.wp-block-latest-posts__featured-image.alignleft{float:left;margin-right:1em}.wp-block-latest-posts__featured-image.alignright{float:right;margin-left:1em}.wp-block-latest-posts__featured-image.aligncenter{margin-bottom:1em;text-align:center}ol,ul{box-sizing:border-box}:root :where(.wp-block-list.has-background){padding:1.25em 2.375em}.wp-block-loginout,.wp-block-media-text{box-sizing:border-box}.wp-block-media-text{direction:ltr;display:grid;grid-template-columns:50% 1fr;grid-template-rows:auto}.wp-block-media-text.has-media-on-the-right{grid-template-columns:1fr 50%}.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__media{align-self:start}.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__media,.wp-block-media-text>.wp-block-media-text__content,.wp-block-media-text>.wp-block-media-text__media{align-self:center}.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__media{align-self:end}.wp-block-media-text>.wp-block-media-text__media{grid-column:1;grid-row:1;margin:0}.wp-block-media-text>.wp-block-media-text__content{direction:rtl;grid-column:2;grid-row:1;padding:0 8%;word-break:break-word}.wp-block-media-text.has-media-on-the-right>.wp-block-media-text__media{grid-column:2;grid-row:1}.wp-block-media-text.has-media-on-the-right>.wp-block-media-text__content{grid-column:1;grid-row:1}.wp-block-media-text__media a{display:block}.wp-block-media-text__media img,.wp-block-media-text__media video{height:auto;max-width:unset;vertical-align:middle;width:100%}.wp-block-media-text.is-image-fill>.wp-block-media-text__media{background-size:cover;height:100%;min-height:250px}.wp-block-media-text.is-image-fill>.wp-block-media-text__media>a{display:block;height:100%}.wp-block-media-text.is-image-fill>.wp-block-media-text__media img{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media{height:100%;min-height:250px;position:relative}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media>a{display:block;height:100%}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media img{height:100%;object-fit:cover;position:absolute;width:100%}@media (max-width:600px){.wp-block-media-text.is-stacked-on-mobile{grid-template-columns:100%!important}.wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__media{grid-column:1;grid-row:1}.wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__content{grid-column:1;grid-row:2}}.wp-block-navigation{position:relative;--navigation-layout-justification-setting:flex-start;--navigation-layout-direction:row;--navigation-layout-wrap:wrap;--navigation-layout-justify:flex-start;--navigation-layout-align:center}.wp-block-navigation ul{margin-bottom:0;margin-right:0;margin-top:0;padding-right:0}.wp-block-navigation ul,.wp-block-navigation ul li{list-style:none;padding:0}.wp-block-navigation .wp-block-navigation-item{align-items:center;display:flex;position:relative}.wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty{display:none}.wp-block-navigation .wp-block-navigation-item__content{display:block}.wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content{color:inherit}.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:focus{text-decoration:underline}.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:focus{text-decoration:line-through}.wp-block-navigation :where(a),.wp-block-navigation :where(a:active),.wp-block-navigation :where(a:focus){text-decoration:none}.wp-block-navigation .wp-block-navigation__submenu-icon{align-self:center;background-color:inherit;border:none;color:currentColor;display:inline-block;font-size:inherit;height:.6em;line-height:0;margin-right:.25em;padding:0;width:.6em}.wp-block-navigation .wp-block-navigation__submenu-icon svg{display:inline-block;stroke:currentColor;height:inherit;margin-top:.075em;width:inherit}.wp-block-navigation.is-vertical{--navigation-layout-direction:column;--navigation-layout-justify:initial;--navigation-layout-align:flex-start}.wp-block-navigation.no-wrap{--navigation-layout-wrap:nowrap}.wp-block-navigation.items-justified-center{--navigation-layout-justification-setting:center;--navigation-layout-justify:center}.wp-block-navigation.items-justified-center.is-vertical{--navigation-layout-align:center}.wp-block-navigation.items-justified-right{--navigation-layout-justification-setting:flex-end;--navigation-layout-justify:flex-end}.wp-block-navigation.items-justified-right.is-vertical{--navigation-layout-align:flex-end}.wp-block-navigation.items-justified-space-between{--navigation-layout-justification-setting:space-between;--navigation-layout-justify:space-between}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{align-items:normal;background-color:inherit;color:inherit;display:flex;flex-direction:column;height:0;opacity:0;overflow:hidden;position:absolute;right:-1px;top:100%;visibility:hidden;width:0;z-index:2}@media not (prefers-reduced-motion){.wp-block-navigation .has-child .wp-block-navigation__submenu-container{transition:opacity .1s linear}}.wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content{display:flex;flex-grow:1}.wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content .wp-block-navigation__submenu-icon{margin-left:0;margin-right:auto}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content{margin:0}@media (min-width:782px){.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{right:100%;top:-1px}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{background:#0000;content:"";display:block;height:100%;left:100%;position:absolute;width:.5em}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon{margin-left:.25em}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon svg{transform:rotate(90deg)}}.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true]~.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):hover>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):not(.open-on-hover-click):focus-within>.wp-block-navigation__submenu-container{height:auto;min-width:200px;opacity:1;overflow:visible;visibility:visible;width:auto}.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container{right:0;top:100%}@media (min-width:782px){.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{right:100%;top:0}}.wp-block-navigation-submenu{display:flex;position:relative}.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{stroke:currentColor}button.wp-block-navigation-item__content{background-color:initial;border:none;color:currentColor;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-align:right;text-transform:inherit}.wp-block-navigation-submenu__toggle{cursor:pointer}.wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle{padding-left:.85em;padding-right:0}.wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle+.wp-block-navigation__submenu-icon{margin-right:-.6em;pointer-events:none}.wp-block-navigation-item.open-on-click button.wp-block-navigation-item__content:not(.wp-block-navigation-submenu__toggle){padding:0}.wp-block-navigation .wp-block-page-list,.wp-block-navigation__container,.wp-block-navigation__responsive-close,.wp-block-navigation__responsive-container,.wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-dialog{gap:inherit}:where(.wp-block-navigation.has-background .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation.has-background .wp-block-navigation-submenu a:not(.wp-element-button)){padding:.5em 1em}:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu button.wp-block-navigation-item__content),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-pages-list__item button.wp-block-navigation-item__content){padding:.5em 1em}.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container{left:0;right:auto}.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:-1px;right:-1px}@media (min-width:782px){.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:100%;right:auto}}.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container{background-color:#fff;border:1px solid #00000026}.wp-block-navigation.has-background .wp-block-navigation__submenu-container{background-color:inherit}.wp-block-navigation:not(.has-text-color) .wp-block-navigation__submenu-container{color:#000}.wp-block-navigation__container{align-items:var(--navigation-layout-align,initial);display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial);list-style:none;margin:0;padding-right:0}.wp-block-navigation__container .is-responsive{display:none}.wp-block-navigation__container:only-child,.wp-block-page-list:only-child{flex-grow:1}@keyframes overlay-menu__fade-in-animation{0%{opacity:0;transform:translateY(.5em)}to{opacity:1;transform:translateY(0)}}.wp-block-navigation__responsive-container{bottom:0;display:none;left:0;position:fixed;right:0;top:0}.wp-block-navigation__responsive-container :where(.wp-block-navigation-item a){color:inherit}.wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content{align-items:var(--navigation-layout-align,initial);display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial)}.wp-block-navigation__responsive-container:not(.is-menu-open.is-menu-open){background-color:inherit!important;color:inherit!important}.wp-block-navigation__responsive-container.is-menu-open{background-color:inherit;display:flex;flex-direction:column;overflow:auto;padding:clamp(1rem,var(--wp--style--root--padding-top),20rem) clamp(1rem,var(--wp--style--root--padding-left),20rem) clamp(1rem,var(--wp--style--root--padding-bottom),20rem) clamp(1rem,var(--wp--style--root--padding-right),20rem);z-index:100000}@media not (prefers-reduced-motion){.wp-block-navigation__responsive-container.is-menu-open{animation:overlay-menu__fade-in-animation .1s ease-out;animation-fill-mode:forwards}}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content{align-items:var(--navigation-layout-justification-setting,inherit);display:flex;flex-direction:column;flex-wrap:nowrap;overflow:visible;padding-top:calc(2rem + 24px)}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{justify-content:flex-start}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon{display:none}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container{border:none;height:auto;min-width:200px;opacity:1;overflow:initial;padding-left:2rem;padding-right:2rem;position:static;visibility:visible;width:auto}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{gap:inherit}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{padding-top:var(--wp--style--block-gap,2em)}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content{padding:0}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{align-items:var(--navigation-layout-justification-setting,initial);display:flex;flex-direction:column}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list{background:#0000!important;color:inherit!important}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{left:auto;right:auto}@media (min-width:600px){.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){background-color:inherit;display:block;position:relative;width:100%;z-index:auto}.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close{display:none}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{right:0}}.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open{background-color:#fff}.wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open{color:#000}.wp-block-navigation__toggle_button_label{font-size:1rem;font-weight:700}.wp-block-navigation__responsive-container-close,.wp-block-navigation__responsive-container-open{background:#0000;border:none;color:currentColor;cursor:pointer;margin:0;padding:0;text-transform:inherit;vertical-align:middle}.wp-block-navigation__responsive-container-close svg,.wp-block-navigation__responsive-container-open svg{fill:currentColor;display:block;height:24px;pointer-events:none;width:24px}.wp-block-navigation__responsive-container-open{display:flex}.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{font-family:inherit;font-size:inherit;font-weight:inherit}@media (min-width:600px){.wp-block-navigation__responsive-container-open:not(.always-shown){display:none}}.wp-block-navigation__responsive-container-close{left:0;position:absolute;top:0;z-index:2}.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close{font-family:inherit;font-size:inherit;font-weight:inherit}.wp-block-navigation__responsive-close{width:100%}.has-modal-open .wp-block-navigation__responsive-close{margin-left:auto;margin-right:auto;max-width:var(--wp--style--global--wide-size,100%)}.wp-block-navigation__responsive-close:focus{outline:none}.is-menu-open .wp-block-navigation__responsive-close,.is-menu-open .wp-block-navigation__responsive-container-content,.is-menu-open .wp-block-navigation__responsive-dialog{box-sizing:border-box}.wp-block-navigation__responsive-dialog{position:relative}.has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{margin-top:46px}@media (min-width:782px){.has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{margin-top:32px}}html.has-modal-open{overflow:hidden}.wp-block-navigation .wp-block-navigation-item__label{overflow-wrap:break-word}.wp-block-navigation .wp-block-navigation-item__description{display:none}.link-ui-tools{border-top:1px solid #f0f0f0;padding:8px}.link-ui-block-inserter{padding-top:8px}.link-ui-block-inserter__back{margin-right:8px;text-transform:uppercase}.wp-block-navigation .wp-block-page-list{align-items:var(--navigation-layout-align,initial);background-color:inherit;display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial)}.wp-block-navigation .wp-block-navigation-item{background-color:inherit}.wp-block-page-list{box-sizing:border-box}.is-small-text{font-size:.875em}.is-regular-text{font-size:1em}.is-large-text{font-size:2.25em}.is-larger-text{font-size:3em}.has-drop-cap:not(:focus):first-letter{float:right;font-size:8.4em;font-style:normal;font-weight:100;line-height:.68;margin:.05em 0 0 .1em;text-transform:uppercase}body.rtl .has-drop-cap:not(:focus):first-letter{float:none;margin-right:.1em}p.has-drop-cap.has-background{overflow:hidden}:root :where(p.has-background){padding:1.25em 2.375em}:where(p.has-text-color:not(.has-link-color)) a{color:inherit}p.has-text-align-left[style*="writing-mode:vertical-lr"],p.has-text-align-right[style*="writing-mode:vertical-rl"]{rotate:180deg}.wp-block-post-author{box-sizing:border-box;display:flex;flex-wrap:wrap}.wp-block-post-author__byline{font-size:.5em;margin-bottom:0;margin-top:0;width:100%}.wp-block-post-author__avatar{margin-left:1em}.wp-block-post-author__bio{font-size:.7em;margin-bottom:.7em}.wp-block-post-author__content{flex-basis:0;flex-grow:1}.wp-block-post-author__name{margin:0}.wp-block-post-author-biography{box-sizing:border-box}:where(.wp-block-post-comments-form) input:not([type=submit]),:where(.wp-block-post-comments-form) textarea{border:1px solid #949494;font-family:inherit;font-size:1em}:where(.wp-block-post-comments-form) input:where(:not([type=submit]):not([type=checkbox])),:where(.wp-block-post-comments-form) textarea{padding:calc(.667em + 2px)}.wp-block-post-comments-form{box-sizing:border-box}.wp-block-post-comments-form[style*=font-weight] :where(.comment-reply-title){font-weight:inherit}.wp-block-post-comments-form[style*=font-family] :where(.comment-reply-title){font-family:inherit}.wp-block-post-comments-form[class*=-font-size] :where(.comment-reply-title),.wp-block-post-comments-form[style*=font-size] :where(.comment-reply-title){font-size:inherit}.wp-block-post-comments-form[style*=line-height] :where(.comment-reply-title){line-height:inherit}.wp-block-post-comments-form[style*=font-style] :where(.comment-reply-title){font-style:inherit}.wp-block-post-comments-form[style*=letter-spacing] :where(.comment-reply-title){letter-spacing:inherit}.wp-block-post-comments-form :where(input[type=submit]){box-shadow:none;cursor:pointer;display:inline-block;overflow-wrap:break-word;text-align:center}.wp-block-post-comments-form .comment-form input:not([type=submit]):not([type=checkbox]):not([type=hidden]),.wp-block-post-comments-form .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-post-comments-form .comment-form-author label,.wp-block-post-comments-form .comment-form-email label,.wp-block-post-comments-form .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments-form .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments-form .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments-form .comment-reply-title{margin-bottom:0}.wp-block-post-comments-form .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-right:.5em}.wp-block-post-comments-count{box-sizing:border-box}.wp-block-post-content{display:flow-root}.wp-block-post-comments-link,.wp-block-post-date{box-sizing:border-box}:where(.wp-block-post-excerpt){box-sizing:border-box;margin-bottom:var(--wp--style--block-gap);margin-top:var(--wp--style--block-gap)}.wp-block-post-excerpt__excerpt{margin-bottom:0;margin-top:0}.wp-block-post-excerpt__more-text{margin-bottom:0;margin-top:var(--wp--style--block-gap)}.wp-block-post-excerpt__more-link{display:inline-block}.wp-block-post-featured-image{margin-left:0;margin-right:0}.wp-block-post-featured-image a{display:block;height:100%}.wp-block-post-featured-image :where(img){box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom;width:100%}.wp-block-post-featured-image.alignfull img,.wp-block-post-featured-image.alignwide img{width:100%}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim{background-color:#000;inset:0;position:absolute}.wp-block-post-featured-image{position:relative}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-gradient{background-color:initial}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-0{opacity:0}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-10{opacity:.1}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-20{opacity:.2}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-30{opacity:.3}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-40{opacity:.4}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-50{opacity:.5}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-60{opacity:.6}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-70{opacity:.7}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-80{opacity:.8}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-90{opacity:.9}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-100{opacity:1}.wp-block-post-featured-image:where(.alignleft,.alignright){width:100%}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous{display:inline-block;margin-left:1ch}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next{display:inline-block;margin-right:1ch}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-post-navigation-link.has-text-align-left[style*="writing-mode: vertical-lr"],.wp-block-post-navigation-link.has-text-align-right[style*="writing-mode: vertical-rl"]{rotate:180deg}.wp-block-post-terms{box-sizing:border-box}.wp-block-post-terms .wp-block-post-terms__separator{white-space:pre-wrap}.wp-block-post-time-to-read,.wp-block-post-title{box-sizing:border-box}.wp-block-post-title{word-break:break-word}.wp-block-post-title :where(a){display:inline-block;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit}.wp-block-post-author-name{box-sizing:border-box}.wp-block-preformatted{box-sizing:border-box;white-space:pre-wrap}:where(.wp-block-preformatted.has-background){padding:1.25em 2.375em}.wp-block-pullquote{box-sizing:border-box;margin:0 0 1em;overflow-wrap:break-word;padding:4em 0;text-align:center}.wp-block-pullquote blockquote,.wp-block-pullquote cite,.wp-block-pullquote p{color:inherit}.wp-block-pullquote blockquote{margin:0}.wp-block-pullquote p{margin-top:0}.wp-block-pullquote p:last-child{margin-bottom:0}.wp-block-pullquote.alignleft,.wp-block-pullquote.alignright{max-width:420px}.wp-block-pullquote cite,.wp-block-pullquote footer{position:relative}.wp-block-pullquote .has-text-color a{color:inherit}.wp-block-pullquote.has-text-align-left blockquote{text-align:right}.wp-block-pullquote.has-text-align-right blockquote{text-align:left}.wp-block-pullquote.has-text-align-center blockquote{text-align:center}.wp-block-pullquote.is-style-solid-color{border:none}.wp-block-pullquote.is-style-solid-color blockquote{margin-left:auto;margin-right:auto;max-width:60%}.wp-block-pullquote.is-style-solid-color blockquote p{font-size:2em;margin-bottom:0;margin-top:0}.wp-block-pullquote.is-style-solid-color blockquote cite{font-style:normal;text-transform:none}.wp-block-pullquote cite{color:inherit;display:block}.wp-block-post-template{box-sizing:border-box;list-style:none;margin-bottom:0;margin-top:0;max-width:100%;padding:0}.wp-block-post-template.is-flex-container{display:flex;flex-direction:row;flex-wrap:wrap;gap:1.25em}.wp-block-post-template.is-flex-container>li{margin:0;width:100%}@media (min-width:600px){.wp-block-post-template.is-flex-container.is-flex-container.columns-2>li{width:calc(50% - .625em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-3>li{width:calc(33.33333% - .83333em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-4>li{width:calc(25% - .9375em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-5>li{width:calc(20% - 1em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-6>li{width:calc(16.66667% - 1.04167em)}}@media (max-width:600px){.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid{grid-template-columns:1fr}}.wp-block-post-template-is-layout-constrained>li>.alignright,.wp-block-post-template-is-layout-flow>li>.alignright{float:left;margin-inline-end:0;margin-inline-start:2em}.wp-block-post-template-is-layout-constrained>li>.alignleft,.wp-block-post-template-is-layout-flow>li>.alignleft{float:right;margin-inline-end:2em;margin-inline-start:0}.wp-block-post-template-is-layout-constrained>li>.aligncenter,.wp-block-post-template-is-layout-flow>li>.aligncenter{margin-inline-end:auto;margin-inline-start:auto}.wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-next:last-of-type{margin-inline-start:auto}.wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-previous:first-child{margin-inline-end:auto}.wp-block-query-pagination .wp-block-query-pagination-previous-arrow{display:inline-block;margin-left:1ch}.wp-block-query-pagination .wp-block-query-pagination-previous-arrow:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-query-pagination .wp-block-query-pagination-next-arrow{display:inline-block;margin-right:1ch}.wp-block-query-pagination .wp-block-query-pagination-next-arrow:not(.is-arrow-chevron){transform:scaleX(-1)}.wp-block-query-pagination.aligncenter{justify-content:center}.wp-block-query-title,.wp-block-query-total,.wp-block-quote{box-sizing:border-box}.wp-block-quote{overflow-wrap:break-word}.wp-block-quote.is-large:where(:not(.is-style-plain)),.wp-block-quote.is-style-large:where(:not(.is-style-plain)){margin-bottom:1em;padding:0 1em}.wp-block-quote.is-large:where(:not(.is-style-plain)) p,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) p{font-size:1.5em;font-style:italic;line-height:1.6}.wp-block-quote.is-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-large:where(:not(.is-style-plain)) footer,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) footer{font-size:1.125em;text-align:left}.wp-block-quote>cite{display:block}.wp-block-read-more{display:block;width:fit-content}.wp-block-read-more:where(:not([style*=text-decoration])){text-decoration:none}.wp-block-read-more:where(:not([style*=text-decoration])):active,.wp-block-read-more:where(:not([style*=text-decoration])):focus{text-decoration:none}ul.wp-block-rss.alignleft{margin-right:2em}ul.wp-block-rss.alignright{margin-left:2em}ul.wp-block-rss.is-grid{display:flex;flex-wrap:wrap;padding:0}ul.wp-block-rss.is-grid li{margin:0 0 1em 1em;width:100%}@media (min-width:600px){ul.wp-block-rss.columns-2 li{width:calc(50% - 1em)}ul.wp-block-rss.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-rss.columns-4 li{width:calc(25% - 1em)}ul.wp-block-rss.columns-5 li{width:calc(20% - 1em)}ul.wp-block-rss.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-rss__item-author,.wp-block-rss__item-publish-date{display:block;font-size:.8125em}.wp-block-rss{box-sizing:border-box;list-style:none;padding:0}.wp-block-search__button{margin-right:10px;word-break:normal}.wp-block-search__button.has-icon{line-height:0}.wp-block-search__button svg{height:1.25em;min-height:24px;min-width:24px;width:1.25em;fill:currentColor;vertical-align:text-bottom}:where(.wp-block-search__button){border:1px solid #ccc;padding:6px 10px}.wp-block-search__inside-wrapper{display:flex;flex:auto;flex-wrap:nowrap;max-width:100%}.wp-block-search__label{width:100%}.wp-block-search__input{appearance:none;border:1px solid #949494;flex-grow:1;margin-left:0;margin-right:0;min-width:3rem;padding:8px;text-decoration:unset!important}.wp-block-search.wp-block-search__button-only .wp-block-search__button{box-sizing:border-box;display:flex;flex-shrink:0;justify-content:center;margin-right:0;max-width:100%}.wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{min-width:0!important;transition-property:width}.wp-block-search.wp-block-search__button-only .wp-block-search__input{flex-basis:100%;transition-duration:.3s}.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden,.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__inside-wrapper{overflow:hidden}.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__input{border-left-width:0!important;border-right-width:0!important;flex-basis:0;flex-grow:0;margin:0;min-width:0!important;padding-left:0!important;padding-right:0!important;width:0!important}:where(.wp-block-search__input){font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-transform:inherit}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper){border:1px solid #949494;box-sizing:border-box;padding:4px}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input{border:none;border-radius:0;padding:0 4px}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input:focus{outline:none}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) :where(.wp-block-search__button){padding:4px 8px}.wp-block-search.aligncenter .wp-block-search__inside-wrapper{margin:auto}.wp-block[data-align=right] .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{float:left}.wp-block-separator{border:none;border-top:2px solid}:root :where(.wp-block-separator.is-style-dots){height:auto;line-height:1;text-align:center}:root :where(.wp-block-separator.is-style-dots):before{color:currentColor;content:"···";font-family:serif;font-size:1.5em;letter-spacing:2em;padding-left:2em}.wp-block-separator.is-style-dots{background:none!important;border:none!important}.wp-block-site-logo{box-sizing:border-box;line-height:0}.wp-block-site-logo a{display:inline-block;line-height:0}.wp-block-site-logo.is-default-size img{height:auto;width:120px}.wp-block-site-logo img{height:auto;max-width:100%}.wp-block-site-logo a,.wp-block-site-logo img{border-radius:inherit}.wp-block-site-logo.aligncenter{margin-left:auto;margin-right:auto;text-align:center}:root :where(.wp-block-site-logo.is-style-rounded){border-radius:9999px}.wp-block-site-tagline,.wp-block-site-title{box-sizing:border-box}.wp-block-site-title :where(a){color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit}.wp-block-social-links{background:none;box-sizing:border-box;margin-right:0;padding-left:0;padding-right:0;text-indent:0}.wp-block-social-links .wp-social-link a,.wp-block-social-links .wp-social-link a:hover{border-bottom:0;box-shadow:none;text-decoration:none}.wp-block-social-links .wp-social-link svg{height:1em;width:1em}.wp-block-social-links .wp-social-link span:not(.screen-reader-text){font-size:.65em;margin-left:.5em;margin-right:.5em}.wp-block-social-links.has-small-icon-size{font-size:16px}.wp-block-social-links,.wp-block-social-links.has-normal-icon-size{font-size:24px}.wp-block-social-links.has-large-icon-size{font-size:36px}.wp-block-social-links.has-huge-icon-size{font-size:48px}.wp-block-social-links.aligncenter{display:flex;justify-content:center}.wp-block-social-links.alignright{justify-content:flex-end}.wp-block-social-link{border-radius:9999px;display:block;height:auto}@media not (prefers-reduced-motion){.wp-block-social-link{transition:transform .1s ease}}.wp-block-social-link a{align-items:center;display:flex;line-height:0}.wp-block-social-link:hover{transform:scale(1.1)}.wp-block-social-links .wp-block-social-link.wp-social-link{display:inline-block;margin:0;padding:0}.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor svg,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:active,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:hover,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:visited{color:currentColor;fill:currentColor}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link{background-color:#f0f0f0;color:#444}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-amazon{background-color:#f90;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bandcamp{background-color:#1ea0c3;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-behance{background-color:#0757fe;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bluesky{background-color:#0a7aff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-codepen{background-color:#1e1f26;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-deviantart{background-color:#02e49b;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-discord{background-color:#5865f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dribbble{background-color:#e94c89;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dropbox{background-color:#4280ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-etsy{background-color:#f45800;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-facebook{background-color:#0866ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-fivehundredpx{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-flickr{background-color:#0461dd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-foursquare{background-color:#e65678;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-github{background-color:#24292d;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-goodreads{background-color:#eceadd;color:#382110}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-google{background-color:#ea4434;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-gravatar{background-color:#1d4fc4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-instagram{background-color:#f00075;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-lastfm{background-color:#e21b24;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-linkedin{background-color:#0d66c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-mastodon{background-color:#3288d4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-medium{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-meetup{background-color:#f6405f;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-patreon{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pinterest{background-color:#e60122;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pocket{background-color:#ef4155;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-reddit{background-color:#ff4500;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-skype{background-color:#0478d7;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-snapchat{background-color:#fefc00;color:#fff;stroke:#000}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-soundcloud{background-color:#ff5600;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-spotify{background-color:#1bd760;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-telegram{background-color:#2aabee;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-threads{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tiktok{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tumblr{background-color:#011835;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitch{background-color:#6440a4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitter{background-color:#1da1f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vimeo{background-color:#1eb7ea;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vk{background-color:#4680c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-wordpress{background-color:#3499cd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-whatsapp{background-color:#25d366;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-x{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-yelp{background-color:#d32422;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-youtube{background-color:red;color:#fff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link{background:none}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link svg{height:1.25em;width:1.25em}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-amazon{color:#f90}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bandcamp{color:#1ea0c3}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-behance{color:#0757fe}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bluesky{color:#0a7aff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-codepen{color:#1e1f26}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-deviantart{color:#02e49b}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-discord{color:#5865f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dribbble{color:#e94c89}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dropbox{color:#4280ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-etsy{color:#f45800}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-facebook{color:#0866ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-fivehundredpx{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-flickr{color:#0461dd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-foursquare{color:#e65678}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-github{color:#24292d}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-goodreads{color:#382110}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-google{color:#ea4434}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-gravatar{color:#1d4fc4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-instagram{color:#f00075}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-lastfm{color:#e21b24}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-linkedin{color:#0d66c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-mastodon{color:#3288d4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-medium{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-meetup{color:#f6405f}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-patreon{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pinterest{color:#e60122}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pocket{color:#ef4155}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-reddit{color:#ff4500}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-skype{color:#0478d7}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-snapchat{color:#fff;stroke:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-soundcloud{color:#ff5600}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-spotify{color:#1bd760}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-telegram{color:#2aabee}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-threads{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tiktok{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tumblr{color:#011835}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitch{color:#6440a4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitter{color:#1da1f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vimeo{color:#1eb7ea}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vk{color:#4680c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-whatsapp{color:#25d366}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-wordpress{color:#3499cd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-x{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-yelp{color:#d32422}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-youtube{color:red}.wp-block-social-links.is-style-pill-shape .wp-social-link{width:auto}:root :where(.wp-block-social-links .wp-social-link a){padding:.25em}:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a){padding:0}:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a){padding-left:.6666666667em;padding-right:.6666666667em}.wp-block-social-links:not(.has-icon-color):not(.has-icon-background-color) .wp-social-link-snapchat .wp-block-social-link-label{color:#000}.wp-block-spacer{clear:both}.wp-block-tag-cloud{box-sizing:border-box}.wp-block-tag-cloud.aligncenter{justify-content:center;text-align:center}.wp-block-tag-cloud.alignfull{padding-left:1em;padding-right:1em}.wp-block-tag-cloud a{display:inline-block;margin-left:5px}.wp-block-tag-cloud span{display:inline-block;margin-right:5px;text-decoration:none}:root :where(.wp-block-tag-cloud.is-style-outline){display:flex;flex-wrap:wrap;gap:1ch}:root :where(.wp-block-tag-cloud.is-style-outline a){border:1px solid;font-size:unset!important;margin-left:0;padding:1ch 2ch;text-decoration:none!important}.wp-block-table{overflow-x:auto}.wp-block-table table{border-collapse:collapse;width:100%}.wp-block-table thead{border-bottom:3px solid}.wp-block-table tfoot{border-top:3px solid}.wp-block-table td,.wp-block-table th{border:1px solid;padding:.5em}.wp-block-table .has-fixed-layout{table-layout:fixed;width:100%}.wp-block-table .has-fixed-layout td,.wp-block-table .has-fixed-layout th{word-break:break-word}.wp-block-table.aligncenter,.wp-block-table.alignleft,.wp-block-table.alignright{display:table;width:auto}.wp-block-table.aligncenter td,.wp-block-table.aligncenter th,.wp-block-table.alignleft td,.wp-block-table.alignleft th,.wp-block-table.alignright td,.wp-block-table.alignright th{word-break:break-word}.wp-block-table .has-subtle-light-gray-background-color{background-color:#f3f4f5}.wp-block-table .has-subtle-pale-green-background-color{background-color:#e9fbe5}.wp-block-table .has-subtle-pale-blue-background-color{background-color:#e7f5fe}.wp-block-table .has-subtle-pale-pink-background-color{background-color:#fcf0ef}.wp-block-table.is-style-stripes{background-color:initial;border-bottom:1px solid #f0f0f0;border-collapse:inherit;border-spacing:0}.wp-block-table.is-style-stripes tbody tr:nth-child(odd){background-color:#f0f0f0}.wp-block-table.is-style-stripes.has-subtle-light-gray-background-color tbody tr:nth-child(odd){background-color:#f3f4f5}.wp-block-table.is-style-stripes.has-subtle-pale-green-background-color tbody tr:nth-child(odd){background-color:#e9fbe5}.wp-block-table.is-style-stripes.has-subtle-pale-blue-background-color tbody tr:nth-child(odd){background-color:#e7f5fe}.wp-block-table.is-style-stripes.has-subtle-pale-pink-background-color tbody tr:nth-child(odd){background-color:#fcf0ef}.wp-block-table.is-style-stripes td,.wp-block-table.is-style-stripes th{border-color:#0000}.wp-block-table .has-border-color td,.wp-block-table .has-border-color th,.wp-block-table .has-border-color tr,.wp-block-table .has-border-color>*{border-color:inherit}.wp-block-table table[style*=border-top-color] tr:first-child,.wp-block-table table[style*=border-top-color] tr:first-child td,.wp-block-table table[style*=border-top-color] tr:first-child th,.wp-block-table table[style*=border-top-color]>*,.wp-block-table table[style*=border-top-color]>* td,.wp-block-table table[style*=border-top-color]>* th{border-top-color:inherit}.wp-block-table table[style*=border-top-color] tr:not(:first-child){border-top-color:initial}.wp-block-table table[style*=border-right-color] td:last-child,.wp-block-table table[style*=border-right-color] th,.wp-block-table table[style*=border-right-color] tr,.wp-block-table table[style*=border-right-color]>*{border-left-color:inherit}.wp-block-table table[style*=border-bottom-color] tr:last-child,.wp-block-table table[style*=border-bottom-color] tr:last-child td,.wp-block-table table[style*=border-bottom-color] tr:last-child th,.wp-block-table table[style*=border-bottom-color]>*,.wp-block-table table[style*=border-bottom-color]>* td,.wp-block-table table[style*=border-bottom-color]>* th{border-bottom-color:inherit}.wp-block-table table[style*=border-bottom-color] tr:not(:last-child){border-bottom-color:initial}.wp-block-table table[style*=border-left-color] td:first-child,.wp-block-table table[style*=border-left-color] th,.wp-block-table table[style*=border-left-color] tr,.wp-block-table table[style*=border-left-color]>*{border-right-color:inherit}.wp-block-table table[style*=border-style] td,.wp-block-table table[style*=border-style] th,.wp-block-table table[style*=border-style] tr,.wp-block-table table[style*=border-style]>*{border-style:inherit}.wp-block-table table[style*=border-width] td,.wp-block-table table[style*=border-width] th,.wp-block-table table[style*=border-width] tr,.wp-block-table table[style*=border-width]>*{border-style:inherit;border-width:inherit}:root :where(.wp-block-table-of-contents){box-sizing:border-box}:where(.wp-block-term-description){box-sizing:border-box;margin-bottom:var(--wp--style--block-gap);margin-top:var(--wp--style--block-gap)}.wp-block-term-description p{margin-bottom:0;margin-top:0}.wp-block-text-columns,.wp-block-text-columns.aligncenter{display:flex}.wp-block-text-columns .wp-block-column{margin:0 1em;padding:0}.wp-block-text-columns .wp-block-column:first-child{margin-right:0}.wp-block-text-columns .wp-block-column:last-child{margin-left:0}.wp-block-text-columns.columns-2 .wp-block-column{width:50%}.wp-block-text-columns.columns-3 .wp-block-column{width:33.3333333333%}.wp-block-text-columns.columns-4 .wp-block-column{width:25%}pre.wp-block-verse{overflow:auto;white-space:pre-wrap}:where(pre.wp-block-verse){font-family:inherit}.wp-block-video{box-sizing:border-box}.wp-block-video video{vertical-align:middle;width:100%}@supports (position:sticky){.wp-block-video [poster]{object-fit:cover}}.wp-block-video.aligncenter{text-align:center}.wp-block-video :where(figcaption){margin-bottom:1em;margin-top:.5em}.editor-styles-wrapper,.entry-content{counter-reset:footnotes}a[data-fn].fn{counter-increment:footnotes;display:inline-flex;font-size:smaller;text-decoration:none;text-indent:-9999999px;vertical-align:super}a[data-fn].fn:after{content:"[" counter(footnotes) "]";float:right;text-indent:0}.wp-element-button{cursor:pointer}:root{--wp--preset--font-size--normal:16px;--wp--preset--font-size--huge:42px}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(-135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(-135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(-135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(-135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(-135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(-135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(-135deg,#020381,#2874fc)}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}.has-text-align-center{text-align:center}.has-text-align-left{text-align:left}.has-text-align-right{text-align:right}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;line-height:normal;padding:15px 23px 14px;right:5px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-left-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-right-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-left-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-right-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}ul.wp-block-archives{ padding-right:2.5em; } .wp-block-archives .wp-block-archives{ border:0; margin:0; } .wp-block-audio{ margin-left:0; margin-right:0; position:relative; } .wp-block-audio.is-transient audio{ opacity:.3; } .wp-block-audio .components-spinner{ margin-right:-9px; margin-top:-9px; position:absolute; right:50%; top:50%; } .wp-block-avatar__image img{ width:100%; } .wp-block-avatar.aligncenter .components-resizable-box__container{ margin:0 auto; } .wp-block[data-align=center]>.wp-block-button{ margin-left:auto; margin-right:auto; text-align:center; } .wp-block[data-align=right]>.wp-block-button{ text-align:right; } .wp-block-button{ cursor:text; position:relative; } .wp-block-button:focus{ box-shadow:0 0 0 1px #fff, 0 0 0 3px var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:-2px; } .wp-block-button[data-rich-text-placeholder]:after{ opacity:.8; } div[data-type="core/button"]{ display:table; } .wp-block-buttons>.wp-block,.wp-block-buttons>.wp-block-button.wp-block-button.wp-block-button.wp-block-button.wp-block-button{ margin:0; } .wp-block-buttons>.block-list-appender{ align-items:center; display:inline-flex; } .wp-block-buttons.is-vertical>.block-list-appender .block-list-appender__toggle{ justify-content:flex-start; } .wp-block-buttons>.wp-block-button:focus{ box-shadow:none; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center]{ margin-left:auto; margin-right:auto; margin-top:0; width:100%; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center] .wp-block-button{ margin-bottom:0; } .wp-block[data-align=center]>.wp-block-buttons{ align-items:center; justify-content:center; } .wp-block[data-align=right]>.wp-block-buttons{ justify-content:flex-end; } .wp-block-categories ul{ padding-right:2.5em; } .wp-block-categories ul ul{ margin-top:6px; } [data-align=center] .wp-block-categories{ text-align:center; } .wp-block-categories__indentation{ padding-right:16px; } .wp-block-code code{ background:none; } .wp-block-columns :where(.wp-block){ margin-left:0; margin-right:0; max-width:none; } html :where(.wp-block-column){ margin-bottom:0; margin-top:0; } .wp-block-comments__legacy-placeholder,.wp-block-post-comments{ box-sizing:border-box; } .wp-block-comments__legacy-placeholder .alignleft,.wp-block-post-comments .alignleft{ float:right; } .wp-block-comments__legacy-placeholder .alignright,.wp-block-post-comments .alignright{ float:left; } .wp-block-comments__legacy-placeholder .navigation:after,.wp-block-post-comments .navigation:after{ clear:both; content:""; display:table; } .wp-block-comments__legacy-placeholder .commentlist,.wp-block-post-comments .commentlist{ clear:both; list-style:none; margin:0; padding:0; } .wp-block-comments__legacy-placeholder .commentlist .comment,.wp-block-post-comments .commentlist .comment{ min-height:2.25em; padding-right:3.25em; } .wp-block-comments__legacy-placeholder .commentlist .comment p,.wp-block-post-comments .commentlist .comment p{ font-size:1em; line-height:1.8; margin:1em 0; } .wp-block-comments__legacy-placeholder .commentlist .children,.wp-block-post-comments .commentlist .children{ list-style:none; margin:0; padding:0; } .wp-block-comments__legacy-placeholder .comment-author,.wp-block-post-comments .comment-author{ line-height:1.5; } .wp-block-comments__legacy-placeholder .comment-author .avatar,.wp-block-post-comments .comment-author .avatar{ border-radius:1.5em; display:block; float:right; height:2.5em; margin-left:.75em; margin-top:.5em; width:2.5em; } .wp-block-comments__legacy-placeholder .comment-author cite,.wp-block-post-comments .comment-author cite{ font-style:normal; } .wp-block-comments__legacy-placeholder .comment-meta,.wp-block-post-comments .comment-meta{ font-size:.875em; line-height:1.5; } .wp-block-comments__legacy-placeholder .comment-meta b,.wp-block-post-comments .comment-meta b{ font-weight:400; } .wp-block-comments__legacy-placeholder .comment-meta .comment-awaiting-moderation,.wp-block-post-comments .comment-meta .comment-awaiting-moderation{ display:block; margin-bottom:1em; margin-top:1em; } .wp-block-comments__legacy-placeholder .comment-body .commentmetadata,.wp-block-post-comments .comment-body .commentmetadata{ font-size:.875em; } .wp-block-comments__legacy-placeholder .comment-form-author label,.wp-block-comments__legacy-placeholder .comment-form-comment label,.wp-block-comments__legacy-placeholder .comment-form-email label,.wp-block-comments__legacy-placeholder .comment-form-url label,.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-comments__legacy-placeholder .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder .comment-form textarea,.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-comments__legacy-placeholder .comment-form-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-comments__legacy-placeholder .comment-form-cookies-consent #wp-comment-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-comments__legacy-placeholder .comment-reply-title,.wp-block-post-comments .comment-reply-title{ margin-bottom:0; } .wp-block-comments__legacy-placeholder .comment-reply-title :where(small),.wp-block-post-comments .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-right:.5em; } .wp-block-comments__legacy-placeholder .reply,.wp-block-post-comments .reply{ font-size:.875em; margin-bottom:1.4em; } .wp-block-comments__legacy-placeholder input:not([type=submit]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } .wp-block-comments__legacy-placeholder input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{ padding:calc(.667em + 2px); } :where(.wp-block-post-comments input[type=submit],.wp-block-comments__legacy-placeholder input[type=submit]){ border:none; } .wp-block-comments{ box-sizing:border-box; } .block-library-comments-toolbar__popover .components-popover__content{ min-width:230px; } .wp-block-comments__legacy-placeholder *{ pointer-events:none; } .wp-block-comment-author-avatar__placeholder{ border:1px dashed; height:100%; width:100%; stroke:currentColor; stroke-dasharray:3; } .wp-block[data-align=center]>.wp-block-comments-pagination{ justify-content:center; } :where(.editor-styles-wrapper) .wp-block-comments-pagination{ max-width:100%; } :where(.editor-styles-wrapper) .wp-block-comments-pagination.block-editor-block-list__layout{ margin:0; } .wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{ font-size:inherit; margin-bottom:.5em; margin-right:.5em; margin-top:.5em; } .wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{ margin-right:0; } .wp-block-comments-pagination-numbers a{ text-decoration:underline; } .wp-block-comments-pagination-numbers .page-numbers{ margin-left:2px; } .wp-block-comments-pagination-numbers .page-numbers:last-child{ margin-right:0; } .wp-block-comments-title.has-background{ padding:inherit; } .wp-block-cover.is-placeholder{ align-items:stretch; display:flex; min-height:240px; padding:0 !important; } .wp-block-cover.is-placeholder .components-placeholder.is-large{ justify-content:flex-start; z-index:1; } .wp-block-cover.is-placeholder:focus:after{ min-height:auto; } .wp-block-cover.components-placeholder h2{ color:inherit; } .wp-block-cover.is-transient{ position:relative; } .wp-block-cover.is-transient:before{ background-color:#fff; content:""; height:100%; opacity:.3; position:absolute; width:100%; z-index:1; } .wp-block-cover.is-transient .wp-block-cover__inner-container{ z-index:2; } .wp-block-cover .components-spinner{ margin:0; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); } .wp-block-cover .wp-block-cover__inner-container{ margin-left:0; margin-right:0; text-align:right; } .wp-block-cover .wp-block-cover__placeholder-background-options{ width:100%; } .wp-block-cover .wp-block-cover__image--placeholder-image{ bottom:0; left:0; position:absolute; right:0; top:0; } [data-align=left]>.wp-block-cover,[data-align=right]>.wp-block-cover{ max-width:420px; width:100%; } .block-library-cover__reset-button{ margin-right:auto; } .block-library-cover__resize-container{ bottom:0; left:0; min-height:50px; position:absolute !important; right:0; top:0; } .components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .block-library-cover__resize-container,.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .components-popover__content>div{ overflow:visible; pointer-events:none; } .block-editor-block-patterns-list__list-item .has-parallax.wp-block-cover{ background-attachment:scroll; } .color-block-support-panel__inner-wrapper>:not(.block-editor-tools-panel-color-gradient-settings__item){ margin-top:24px; } .wp-block-details summary div{ display:inline; } .wp-block-embed{ clear:both; margin-left:0; margin-right:0; } .wp-block-embed.is-loading{ display:flex; justify-content:center; } .wp-block-embed .wp-block-embed__placeholder-input{ flex:1 1 auto; } .wp-block-embed .components-placeholder__error{ word-break:break-word; } .wp-block-post-content .wp-block-embed__learn-more a{ color:var(--wp-admin-theme-color); } .block-library-embed__interactive-overlay{ bottom:0; left:0; opacity:0; position:absolute; right:0; top:0; } .wp-block[data-align=left]>.wp-block-embed,.wp-block[data-align=right]>.wp-block-embed{ max-width:360px; width:100%; } .wp-block[data-align=left]>.wp-block-embed .wp-block-embed__wrapper,.wp-block[data-align=right]>.wp-block-embed .wp-block-embed__wrapper{ min-width:280px; } .wp-block-file{ align-items:center; display:flex; flex-wrap:wrap; justify-content:space-between; margin-bottom:0; } .wp-block[data-align=left]>.wp-block-file,.wp-block[data-align=right]>.wp-block-file{ height:auto; } .wp-block[data-align=center]>.wp-block-file{ text-align:center; } .wp-block-file .components-resizable-box__container{ margin-bottom:1em; } .wp-block-file .wp-block-file__preview{ height:100%; margin-bottom:1em; width:100%; } .wp-block-file .wp-block-file__preview-overlay{ bottom:0; left:0; position:absolute; right:0; top:0; } .wp-block-file .wp-block-file__content-wrapper{ flex-grow:1; } .wp-block-file a{ min-width:1em; } .wp-block-file a:not(.wp-block-file__button){ display:inline-block; } .wp-block-file .wp-block-file__button-richtext-wrapper{ display:inline-block; margin-right:.75em; } .wp-block-form-input .is-input-hidden{ background:repeating-linear-gradient(-45deg, #0000, #0000 5px, currentColor 0, currentColor 6px); border:1px dashed; box-sizing:border-box; font-size:.85em; opacity:.3; padding:.5em; } .wp-block-form-input .is-input-hidden input[type=text]{ background:#0000; } .wp-block-form-input.is-selected .is-input-hidden{ background:none; opacity:1; } .wp-block-form-input.is-selected .is-input-hidden input[type=text]{ background:unset; } .wp-block-form-submission-notification>*{ background:repeating-linear-gradient(-45deg, #0000, #0000 5px, currentColor 0, currentColor 6px); border:1px dashed; box-sizing:border-box; opacity:.25; } .wp-block-form-submission-notification.is-selected>*,.wp-block-form-submission-notification:has(.is-selected)>*{ background:none; opacity:1; } .wp-block-form-submission-notification.is-selected:after,.wp-block-form-submission-notification:has(.is-selected):after{ display:none !important; } .wp-block-form-submission-notification:after{ align-items:center; display:flex; font-size:1.1em; height:100%; justify-content:center; position:absolute; right:0; top:0; width:100%; } .wp-block-form-submission-notification.form-notification-type-success:after{ content:attr(data-message-success); } .wp-block-form-submission-notification.form-notification-type-error:after{ content:attr(data-message-error); } .wp-block-freeform.block-library-rich-text__tinymce{ height:auto; } .wp-block-freeform.block-library-rich-text__tinymce li,.wp-block-freeform.block-library-rich-text__tinymce p{ line-height:1.8; } .wp-block-freeform.block-library-rich-text__tinymce ol,.wp-block-freeform.block-library-rich-text__tinymce ul{ margin-right:0; padding-right:2.5em; } .wp-block-freeform.block-library-rich-text__tinymce blockquote{ border-right:4px solid #000; box-shadow:inset 0 0 0 0 #ddd; margin:0; padding-right:1em; } .wp-block-freeform.block-library-rich-text__tinymce pre{ color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:15px; white-space:pre-wrap; } .wp-block-freeform.block-library-rich-text__tinymce>:first-child{ margin-top:0; } .wp-block-freeform.block-library-rich-text__tinymce>:last-child{ margin-bottom:0; } .wp-block-freeform.block-library-rich-text__tinymce.mce-edit-focus{ outline:none; } .wp-block-freeform.block-library-rich-text__tinymce a{ color:var(--wp-admin-theme-color); } .wp-block-freeform.block-library-rich-text__tinymce:focus a[data-mce-selected]{ background:#e5f5fa; border-radius:2px; box-shadow:0 0 0 1px #e5f5fa; margin:0 -2px; padding:0 2px; } .wp-block-freeform.block-library-rich-text__tinymce code{ background:#f0f0f0; border-radius:2px; color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:14px; padding:2px; } .wp-block-freeform.block-library-rich-text__tinymce:focus code[data-mce-selected]{ background:#ddd; } .wp-block-freeform.block-library-rich-text__tinymce .alignright{ float:right; margin:.5em 0 .5em 1em; } .wp-block-freeform.block-library-rich-text__tinymce .alignleft{ float:left; margin:.5em 1em .5em 0; } .wp-block-freeform.block-library-rich-text__tinymce .aligncenter{ display:block; margin-left:auto; margin-right:auto; } .wp-block-freeform.block-library-rich-text__tinymce .wp-more-tag{ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADtgAAAAoBAMAAAA86gLBAAAAJFBMVEVMaXG7u7vBwcHDw8POzs68vLzGxsbMzMy+vr7AwMDQ0NDGxsYKLGzpAAAADHRSTlMA///zWf+/f///TMxNVGuqAAABwklEQVR4Ae3dMXLaQBTH4bfj8UCpx8hq0vgKvgFNemhT6Qo6gg6R+0ZahM2QLmyBJ99XWP9V5+o3jIUcLQEAAAAAAAAAAAAAAAAAAAAAAABQ8j0WL9lfTtlt18uNXAUA8O/KVtfa1tdcrOdSh9gCQAMlh1hMNbZZ1bsrsQWABsrhLRbz7z5in/32UbfUMUbkMQCAh5RfGYv82UdMdZ6HS2wjT2ILAI8r3XmM2B3WvM59vfO2xXYW2yYAENuPU8S+X/N67mKxzy225yaxBQCxLV392UdcvwV0jPVUj98ntkBWT7C7+9u2/V/vGtvXIWJ6/4rtbottWa6Ri0NUT/u72LYttrb97LHdvUXMxxrb8TO2W2TF1rYbbLG1bbGNjMi4+2Sbi1FsbbvNFlvbFtt5fDnE3d9sP1/XeIyV2Nr2U2/guZUuptNrH/dPI9eLB6SaAEBs6wPJf3/PNk9tYgsAYrv/8TFuzx/fvkFqGtrEFgDEdpcZUb7ejXy6ntrEFgDENvL6gsas4vbdyKt4DACI7TxElJv/Z7udpqFNbAFAbKduy2uU2trttM/x28UWAAAAAAAAAAAAAAAAAAAAAAAAAADgDyPwGmGTCZp7AAAAAElFTkSuQmCC); background-position:50%; background-repeat:no-repeat; background-size:1900px 20px; cursor:default; display:block; height:20px; margin:15px auto; outline:0; width:96%; } .wp-block-freeform.block-library-rich-text__tinymce img::selection{ background-color:initial; } .wp-block-freeform.block-library-rich-text__tinymce div.mceTemp{ -ms-user-select:element; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption{ margin:0; max-width:100%; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption a,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption img{ display:block; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption *{ -webkit-user-drag:none; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption .wp-caption-dd{ margin:0; padding-top:.5em; } .wp-block-freeform.block-library-rich-text__tinymce .wpview{ border:1px solid #0000; clear:both; margin-bottom:16px; position:relative; width:99.99%; } .wp-block-freeform.block-library-rich-text__tinymce .wpview iframe{ background:#0000; display:block; max-width:100%; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .mce-shim{ bottom:0; left:0; position:absolute; right:0; top:0; } .wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected="2"] .mce-shim{ display:none; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .loading-placeholder{ border:1px dashed #ddd; padding:10px; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error{ border:1px solid #ddd; margin:0; padding:1em 0; word-wrap:break-word; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error p{ margin:0; text-align:center; } .wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .loading-placeholder,.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .wpview-error{ border-color:#0000; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .dashicons{ display:block; font-size:32px; height:32px; margin:0 auto; width:32px; } .wp-block-freeform.block-library-rich-text__tinymce .wpview.wpview-type-gallery:after{ clear:both; content:""; display:table; } .wp-block-freeform.block-library-rich-text__tinymce .gallery img[data-mce-selected]:focus{ outline:none; } .wp-block-freeform.block-library-rich-text__tinymce .gallery a{ cursor:default; } .wp-block-freeform.block-library-rich-text__tinymce .gallery{ line-height:1; margin:auto -6px; overflow-x:hidden; padding:6px 0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-item{ box-sizing:border-box; float:right; margin:0; padding:6px; text-align:center; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption,.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-icon{ margin:0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption{ font-size:13px; margin:4px 0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-1 .gallery-item{ width:100%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-2 .gallery-item{ width:50%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-3 .gallery-item{ width:33.3333333333%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-4 .gallery-item{ width:25%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-5 .gallery-item{ width:20%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-6 .gallery-item{ width:16.6666666667%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-7 .gallery-item{ width:14.2857142857%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-8 .gallery-item{ width:12.5%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-9 .gallery-item{ width:11.1111111111%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery img{ border:none; height:auto; max-width:100%; padding:0; } div[data-type="core/freeform"]:before{ border:1px solid #ddd; outline:1px solid #0000; } @media not (prefers-reduced-motion){ div[data-type="core/freeform"]:before{ transition:border-color .1s linear,box-shadow .1s linear; } } div[data-type="core/freeform"].is-selected:before{ border-color:#1e1e1e; } div[data-type="core/freeform"] .block-editor-block-contextual-toolbar+div{ margin-top:0; padding-top:0; } div[data-type="core/freeform"].is-selected .block-library-rich-text__tinymce:after{ clear:both; content:""; display:table; } .mce-toolbar-grp .mce-btn.mce-active button,.mce-toolbar-grp .mce-btn.mce-active i,.mce-toolbar-grp .mce-btn.mce-active:hover button,.mce-toolbar-grp .mce-btn.mce-active:hover i{ color:#1e1e1e; } .mce-toolbar-grp .mce-rtl .mce-flow-layout-item.mce-last{ margin-left:0; margin-right:8px; } .mce-toolbar-grp .mce-btn i{ font-style:normal; } .block-library-classic__toolbar{ border:1px solid #ddd; border-bottom:none; border-radius:2px; display:none; margin:0 0 8px; padding:0; position:sticky; top:0; width:auto; z-index:31; } div[data-type="core/freeform"].is-selected .block-library-classic__toolbar{ border-color:#1e1e1e; display:block; } .block-library-classic__toolbar .mce-tinymce{ box-shadow:none; } @media (min-width:600px){ .block-library-classic__toolbar{ padding:0; } } .block-library-classic__toolbar:empty{ background:#f5f5f5; border-bottom:1px solid #e2e4e7; display:block; } .block-library-classic__toolbar:empty:before{ color:#555d66; content:attr(data-placeholder); font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:37px; padding:14px; } .block-library-classic__toolbar div.mce-toolbar-grp{ border-bottom:1px solid #1e1e1e; } .block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar .mce-menubar>div,.block-library-classic__toolbar .mce-tinymce-inline,.block-library-classic__toolbar .mce-tinymce-inline>div,.block-library-classic__toolbar div.mce-toolbar-grp,.block-library-classic__toolbar div.mce-toolbar-grp>div{ height:auto !important; width:100% !important; } .block-library-classic__toolbar .mce-container-body.mce-abs-layout{ overflow:visible; } .block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar div.mce-toolbar-grp{ position:static; } .block-library-classic__toolbar .mce-toolbar-grp>div{ padding:1px 3px; } .block-library-classic__toolbar .mce-toolbar-grp .mce-toolbar:not(:first-child){ display:none; } .block-library-classic__toolbar.has-advanced-toolbar .mce-toolbar-grp .mce-toolbar{ display:block; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{ height:50vh !important; } @media (min-width:960px){ .block-editor-freeform-modal .block-editor-freeform-modal__content:not(.is-full-screen){ height:9999rem; } .block-editor-freeform-modal .block-editor-freeform-modal__content .components-modal__header+div{ height:100%; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-tinymce{ height:calc(100% - 52px); } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-container-body{ display:flex; flex-direction:column; height:100%; min-width:50vw; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area{ display:flex; flex-direction:column; flex-grow:1; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{ flex-grow:1; height:10px !important; } } .block-editor-freeform-modal__actions{ margin-top:16px; } :root :where(figure.wp-block-gallery){ display:block; } :root :where(figure.wp-block-gallery)>.blocks-gallery-caption{ flex:0 0 100%; } :root :where(figure.wp-block-gallery)>.blocks-gallery-media-placeholder-wrapper{ flex-basis:100%; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice.is-error{ display:block; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice__content{ margin:4px 0; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice__dismiss{ left:5px; position:absolute; top:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .components-placeholder__label{ display:none; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .block-editor-media-placeholder__button{ margin-bottom:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder{ margin:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder .components-placeholder__label{ display:flex; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder figcaption{ z-index:2; } :root :where(figure.wp-block-gallery) .components-spinner{ margin-right:-9px; margin-top:-9px; position:absolute; right:50%; top:50%; } .gallery-settings-buttons .components-button:first-child{ margin-left:8px; } .gallery-image-sizes .components-base-control__label{ margin-bottom:4px; } .gallery-image-sizes .gallery-image-sizes__loading{ align-items:center; color:#757575; display:flex; font-size:12px; } .gallery-image-sizes .components-spinner{ margin:0 4px 0 8px; } .blocks-gallery-item figure:not(.is-selected):focus,.blocks-gallery-item img:focus{ outline:none; } .blocks-gallery-item figure.is-selected:before{ bottom:0; box-shadow:0 0 0 1px #fff inset, 0 0 0 3px var(--wp-admin-theme-color) inset; content:""; left:0; outline:2px solid #0000; pointer-events:none; position:absolute; right:0; top:0; z-index:1; } .blocks-gallery-item figure.is-transient img{ opacity:.3; } .blocks-gallery-item .block-editor-media-placeholder{ height:100%; margin:0; } .blocks-gallery-item .block-editor-media-placeholder .components-placeholder__label{ display:flex; } .wp-block-gallery ul.blocks-gallery-grid{ margin:0; padding:0; } @media (min-width:600px){ .wp-block-update-gallery-modal{ max-width:480px; } } .wp-block-update-gallery-modal-buttons{ display:flex; gap:12px; justify-content:flex-end; } .wp-block-group .block-editor-block-list__insertion-point{ left:0; right:0; } [data-type="core/group"].is-selected .block-list-appender{ margin-left:0; margin-right:0; } [data-type="core/group"].is-selected .has-background .block-list-appender{ margin-bottom:18px; margin-top:18px; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child{ gap:inherit; pointer-events:none; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-default-block-appender__content,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{ display:inherit; flex:1; flex-direction:inherit; width:100%; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child:after{ border:1px dashed; content:""; display:flex; flex:1 0 40px; min-height:38px; pointer-events:none; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-button-block-appender,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{ pointer-events:all; } .block-library-html__edit .block-library-html__preview-overlay{ height:100%; position:absolute; right:0; top:0; width:100%; } .block-library-html__edit .block-editor-plain-text{ background:#fff !important; border:1px solid #1e1e1e !important; border-radius:2px !important; box-shadow:none !important; box-sizing:border-box; color:#1e1e1e !important; direction:ltr; font-family:Menlo,Consolas,monaco,monospace !important; font-size:16px !important; max-height:250px; padding:12px !important; } @media (min-width:600px){ .block-library-html__edit .block-editor-plain-text{ font-size:13px !important; } } .block-library-html__edit .block-editor-plain-text:focus{ border-color:var(--wp-admin-theme-color) !important; box-shadow:0 0 0 1px var(--wp-admin-theme-color) !important; outline:2px solid #0000 !important; } .wp-block-image.wp-block-image .block-editor-media-placeholder.is-small{ min-height:60px; } figure.wp-block-image:not(.wp-block){ margin:0; } .wp-block-image{ position:relative; } .wp-block-image .is-applying img,.wp-block-image.is-transient img{ opacity:.3; } .wp-block-image figcaption img{ display:inline; } .wp-block-image .components-spinner{ margin:0; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); } .wp-block-image__placeholder{ aspect-ratio:4/3; } .wp-block-image__placeholder.has-illustration:before{ background:#fff; opacity:.8; } .wp-block-image__placeholder .components-placeholder__illustration{ opacity:.1; } .wp-block-image .components-resizable-box__container{ display:table; } .wp-block-image .components-resizable-box__container img{ display:block; height:inherit; width:inherit; } .block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{ left:0; margin:-1px 0; position:absolute; right:0; } @media (min-width:600px){ .block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{ margin:-1px; } } [data-align=full]>.wp-block-image img,[data-align=wide]>.wp-block-image img{ height:auto; width:100%; } .wp-block[data-align=center]>.wp-block-image,.wp-block[data-align=left]>.wp-block-image,.wp-block[data-align=right]>.wp-block-image{ display:table; } .wp-block[data-align=center]>.wp-block-image>figcaption,.wp-block[data-align=left]>.wp-block-image>figcaption,.wp-block[data-align=right]>.wp-block-image>figcaption{ caption-side:bottom; display:table-caption; } .wp-block[data-align=left]>.wp-block-image{ margin:.5em 0 .5em 1em; } .wp-block[data-align=right]>.wp-block-image{ margin:.5em 1em .5em 0; } .wp-block[data-align=center]>.wp-block-image{ margin-left:auto; margin-right:auto; text-align:center; } .wp-block[data-align]:has(>.wp-block-image){ position:relative; } .wp-block-image__crop-area{ max-width:100%; overflow:hidden; position:relative; width:100%; } .wp-block-image__crop-area .reactEasyCrop_Container{ pointer-events:auto; } .wp-block-image__crop-area .reactEasyCrop_Container .reactEasyCrop_Image{ border:none; border-radius:0; } .wp-block-image__crop-icon{ align-items:center; display:flex; justify-content:center; min-width:48px; padding:0 8px; } .wp-block-image__crop-icon svg{ fill:currentColor; } .wp-block-image__zoom .components-popover__content{ min-width:260px; overflow:visible !important; } .wp-block-image__toolbar_content_textarea__container{ padding:8px; } .wp-block-image__toolbar_content_textarea{ width:250px; } .wp-block-latest-posts>li{ overflow:hidden; } .wp-block-latest-posts li a>div{ display:inline; } :root :where(.wp-block-latest-posts){ padding-right:2.5em; } :root :where(.wp-block-latest-posts.is-grid),:root :where(.wp-block-latest-posts__list){ padding-right:0; } .wp-block-media-text__media{ position:relative; } .wp-block-media-text__media.is-transient img{ opacity:.3; } .wp-block-media-text__media .components-spinner{ margin-right:-9px; margin-top:-9px; position:absolute; right:50%; top:50%; } .wp-block-media-text .__resizable_base__{ grid-column:1 / span 2; grid-row:2; } .wp-block-media-text .editor-media-container__resizer{ width:100% !important; } .wp-block-media-text.is-image-fill .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill .editor-media-container__resizer,.wp-block-media-text.is-image-fill-element .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill-element .editor-media-container__resizer{ height:100% !important; } .wp-block-media-text>.block-editor-block-list__layout>.block-editor-block-list__block{ max-width:unset; } .wp-block-media-text--placeholder-image{ min-height:205px; } .block-editor-block-list__block[data-type="core/more"]{ margin-bottom:28px; margin-top:28px; max-width:100%; text-align:center; } .wp-block-more{ display:block; text-align:center; white-space:nowrap; } .wp-block-more input[type=text]{ background:#fff; border:none; border-radius:4px; box-shadow:none; color:#757575; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; height:24px; margin:0; max-width:100%; padding:6px 8px; position:relative; text-align:center; text-transform:uppercase; white-space:nowrap; } .wp-block-more input[type=text]:focus{ box-shadow:none; } .wp-block-more:before{ border-top:3px dashed #ccc; content:""; left:0; position:absolute; right:0; top:50%; } .editor-styles-wrapper .wp-block-navigation ul{ margin-bottom:0; margin-right:0; margin-top:0; padding-right:0; } .editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block{ margin:revert; } .wp-block-navigation-item__label{ display:inline; } .wp-block-navigation-item,.wp-block-navigation__container{ background-color:inherit; } .wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover>.wp-block-navigation__submenu-container{ opacity:0; visibility:hidden; } .has-child.has-child-selected>.wp-block-navigation__submenu-container,.has-child.is-selected>.wp-block-navigation__submenu-container{ display:flex; opacity:1; visibility:visible; } .is-dragging-components-draggable .has-child.is-dragging-within>.wp-block-navigation__submenu-container{ opacity:1; visibility:visible; } .is-editing>.wp-block-navigation__container{ display:flex; flex-direction:column; opacity:1; visibility:visible; } .is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container{ opacity:1; visibility:hidden; } .is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container .block-editor-block-draggable-chip-wrapper{ visibility:visible; } .is-editing>.wp-block-navigation__submenu-container>.block-list-appender{ display:block; position:static; width:100%; } .is-editing>.wp-block-navigation__submenu-container>.block-list-appender .block-editor-button-block-appender{ background:#1e1e1e; color:#fff; margin-left:0; margin-right:auto; padding:0; width:24px; } .wp-block-navigation__submenu-container .block-list-appender{ display:none; } .block-library-colors-selector{ width:auto; } .block-library-colors-selector .block-library-colors-selector__toggle{ display:block; margin:0 auto; padding:3px; width:auto; } .block-library-colors-selector .block-library-colors-selector__icon-container{ align-items:center; border-radius:4px; display:flex; height:30px; margin:0 auto; padding:3px; position:relative; } .block-library-colors-selector .block-library-colors-selector__state-selection{ border-radius:11px; box-shadow:inset 0 0 0 1px #0003; height:22px; line-height:20px; margin-left:auto; margin-right:auto; min-height:22px; min-width:22px; padding:2px; width:22px; } .block-library-colors-selector .block-library-colors-selector__state-selection>svg{ min-width:auto !important; } .block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg,.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg path{ color:inherit; } .block-library-colors-selector__popover .color-palette-controller-container{ padding:16px; } .block-library-colors-selector__popover .components-base-control__label{ height:20px; line-height:20px; } .block-library-colors-selector__popover .component-color-indicator{ float:left; margin-top:2px; } .block-library-colors-selector__popover .components-panel__body-title{ display:none; } .wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender{ background-color:#1e1e1e; color:#fff; height:24px; } .wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender.block-editor-button-block-appender.block-editor-button-block-appender{ padding:0; } .wp-block-navigation .wp-block .wp-block .block-editor-button-block-appender{ background-color:initial; color:#1e1e1e; } @keyframes loadingpulse{ 0%{ opacity:1; } 50%{ opacity:.5; } to{ opacity:1; } } .components-placeholder.wp-block-navigation-placeholder{ background:none; box-shadow:none; color:inherit; min-height:0; outline:none; padding:0; } .components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset{ font-size:inherit; } .components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button{ margin-bottom:0; } .wp-block-navigation.is-selected .components-placeholder.wp-block-navigation-placeholder{ color:#1e1e1e; } .wp-block-navigation-placeholder__preview{ align-items:center; background:#0000; color:currentColor; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; min-width:96px; } .wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview{ display:none; } .wp-block-navigation-placeholder__preview:before{ border:1px dashed; border-radius:inherit; bottom:0; content:""; display:block; left:0; pointer-events:none; position:absolute; right:0; top:0; } .wp-block-navigation-placeholder__preview>svg{ fill:currentColor; } .wp-block-navigation.is-vertical .is-medium .components-placeholder__fieldset,.wp-block-navigation.is-vertical .is-small .components-placeholder__fieldset{ min-height:90px; } .wp-block-navigation.is-vertical .is-large .components-placeholder__fieldset{ min-height:132px; } .wp-block-navigation-placeholder__controls,.wp-block-navigation-placeholder__preview{ align-items:flex-start; flex-direction:row; padding:6px 8px; } .wp-block-navigation-placeholder__controls{ background-color:#fff; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; display:none; float:right; position:relative; width:100%; z-index:1; } .wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls{ display:flex; } .is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr{ display:none; } .is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions{ align-items:flex-start; flex-direction:column; } .is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr{ display:none; } .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon{ height:36px; margin-left:12px; } .wp-block-navigation-placeholder__actions__indicator{ align-items:center; display:flex; height:36px; justify-content:flex-start; line-height:0; margin-right:4px; padding:0 0 0 6px; } .wp-block-navigation-placeholder__actions__indicator svg{ margin-left:4px; fill:currentColor; } .wp-block-navigation .components-placeholder.is-medium .components-placeholder__fieldset{ flex-direction:row !important; } .wp-block-navigation-placeholder__actions{ align-items:center; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; gap:6px; height:100%; } .wp-block-navigation-placeholder__actions .components-dropdown,.wp-block-navigation-placeholder__actions>.components-button{ margin-left:0; } .wp-block-navigation-placeholder__actions.wp-block-navigation-placeholder__actions hr{ background-color:#1e1e1e; border:0; height:100%; margin:auto 0; max-height:16px; min-height:1px; min-width:1px; } @media (min-width:600px){ .wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close{ display:none; } } .wp-block-navigation__responsive-container.is-menu-open{ position:fixed; top:155px; } @media (min-width:782px){ .wp-block-navigation__responsive-container.is-menu-open{ right:36px; top:93px; } } @media (min-width:960px){ .wp-block-navigation__responsive-container.is-menu-open{ right:160px; } } .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{ top:141px; } .is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{ right:0; top:155px; } @media (min-width:782px){ .is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{ top:61px; } } .is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{ top:109px; } body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open{ bottom:0; left:0; right:0; top:0; } .components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close,.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{ color:inherit; height:auto; padding:0; } .components-heading.wp-block-navigation-off-canvas-editor__title{ margin:0; } .wp-block-navigation-off-canvas-editor__header{ margin-bottom:8px; } .is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender{ margin-top:16px; } @keyframes fadein{ 0%{ opacity:0; } to{ opacity:1; } } .wp-block-navigation__loading-indicator-container{ padding:8px 12px; } .wp-block-navigation .wp-block-navigation__uncontrolled-inner-blocks-loading-indicator{ margin-top:0; } @keyframes fadeouthalf{ 0%{ opacity:1; } to{ opacity:.5; } } .wp-block-navigation-delete-menu-button{ justify-content:center; margin-bottom:16px; width:100%; } .components-button.is-link.wp-block-navigation-manage-menus-button{ margin-bottom:16px; } .wp-block-navigation__overlay-menu-preview{ align-items:center; background-color:#f0f0f0; display:flex; height:64px !important; justify-content:space-between; margin-bottom:12px; padding:0 24px; width:100%; } .wp-block-navigation__overlay-menu-preview.open{ background-color:#fff; box-shadow:inset 0 0 0 1px #e0e0e0; outline:1px solid #0000; } .wp-block-navigation-placeholder__actions hr+hr,.wp-block-navigation__toolbar-menu-selector.components-toolbar-group:empty{ display:none; } .wp-block-navigation__navigation-selector{ margin-bottom:16px; width:100%; } .wp-block-navigation__navigation-selector-button{ border:1px solid; justify-content:space-between; width:100%; } .wp-block-navigation__navigation-selector-button__icon{ flex:0 0 auto; } .wp-block-navigation__navigation-selector-button__label{ flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .wp-block-navigation__navigation-selector-button--createnew{ border:1px solid; margin-bottom:16px; width:100%; } .wp-block-navigation__responsive-container-open.components-button{ opacity:1; } .wp-block-navigation__menu-inspector-controls{ overflow-x:auto; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-width:thin; will-change:transform; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar{ height:12px; width:12px; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-track{ background-color:initial; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .wp-block-navigation__menu-inspector-controls:focus-within::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:focus::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .wp-block-navigation__menu-inspector-controls:focus,.wp-block-navigation__menu-inspector-controls:focus-within,.wp-block-navigation__menu-inspector-controls:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .wp-block-navigation__menu-inspector-controls{ scrollbar-color:#949494 #0000; } } .wp-block-navigation__menu-inspector-controls__empty-message{ margin-right:24px; } .wp-block-navigation__overlay-menu-icon-toggle-group{ margin-bottom:16px; } .wp-block-navigation .block-list-appender{ position:relative; } .wp-block-navigation .has-child{ cursor:pointer; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ z-index:28; } .wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{ z-index:29; } .wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{ height:auto !important; min-width:200px !important; opacity:1 !important; overflow:visible !important; visibility:visible !important; width:auto !important; } .wp-block-navigation-item .wp-block-navigation-item__content{ cursor:text; } .wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{ min-width:20px; } .wp-block-navigation-item .block-list-appender{ margin:16px 16px 16px auto; } .wp-block-navigation-link__invalid-item{ color:#000; } .wp-block-navigation-link__placeholder{ background-image:none !important; box-shadow:none !important; position:relative; text-decoration:none !important; } .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{ -webkit-text-decoration:wavy underline; text-decoration:wavy underline; -webkit-text-decoration-skip-ink:none; text-decoration-skip-ink:none; text-underline-offset:.25rem; } .wp-block-navigation-link__placeholder.wp-block-navigation-item__content{ cursor:pointer; } .link-control-transform{ border-top:1px solid #ccc; padding:0 16px 8px; } .link-control-transform__subheading{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .link-control-transform__items{ display:flex; justify-content:space-between; } .link-control-transform__item{ flex-basis:33%; flex-direction:column; gap:8px; height:auto; } .wp-block-navigation-submenu{ display:block; } .wp-block-navigation-submenu .wp-block-navigation__submenu-container{ z-index:28; } .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{ height:auto !important; min-width:200px !important; opacity:1 !important; position:absolute; right:-1px; top:100%; visibility:visible !important; width:auto !important; } @media (min-width:782px){ .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ right:100%; top:-1px; } .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{ background:#0000; content:""; display:block; height:100%; left:100%; position:absolute; width:.5em; } } .block-editor-block-list__block[data-type="core/nextpage"]{ margin-bottom:28px; margin-top:28px; max-width:100%; text-align:center; } .wp-block-nextpage{ display:block; text-align:center; white-space:nowrap; } .wp-block-nextpage>span{ background:#fff; border-radius:4px; color:#757575; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; height:24px; padding:6px 8px; position:relative; text-transform:uppercase; } .wp-block-nextpage:before{ border-top:3px dashed #ccc; content:""; left:0; position:absolute; right:0; top:50%; } .wp-block-navigation .wp-block-page-list,.wp-block-navigation .wp-block-page-list>div{ background-color:inherit; } .wp-block-navigation.items-justified-space-between .wp-block-page-list,.wp-block-navigation.items-justified-space-between .wp-block-page-list>div{ display:contents; flex:1; } .wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list>div,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list>div{ flex:inherit; } .wp-block-navigation .wp-block-navigation__submenu-container>.wp-block-page-list{ display:block; } .wp-block-pages-list__item__link{ pointer-events:none; } @media (min-width:600px){ .wp-block-page-list-modal{ max-width:480px; } } .wp-block-page-list-modal-buttons{ display:flex; gap:12px; justify-content:flex-end; } .wp-block-page-list .open-on-click:focus-within>.wp-block-navigation__submenu-container{ height:auto; min-width:200px; opacity:1; visibility:visible; width:auto; } .wp-block-page-list__loading-indicator-container{ padding:8px 12px; } .block-editor-block-list__block[data-type="core/paragraph"].has-drop-cap:focus{ min-height:auto !important; } .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{ opacity:1; } .block-editor-block-list__block[data-empty=true]+.block-editor-block-list__block[data-empty=true]:not([data-custom-placeholder=true]) [data-rich-text-placeholder]{ opacity:0; } .block-editor-block-list__block[data-type="core/paragraph"].has-text-align-left[style*="writing-mode: vertical-lr"],.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-right[style*="writing-mode: vertical-rl"]{ rotate:180deg; } .is-zoomed-out .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{ opacity:0; } .wp-block-post-author__inspector-settings .components-base-control,.wp-block-post-author__inspector-settings .components-base-control:last-child{ margin-bottom:0; } .wp-block-post-excerpt .wp-block-post-excerpt__excerpt.is-inline{ display:inline; } .wp-block-pullquote.is-style-solid-color blockquote p{ font-size:32px; } .wp-block-pullquote.is-style-solid-color .wp-block-pullquote__citation{ font-style:normal; text-transform:none; } .wp-block-pullquote .wp-block-pullquote__citation{ color:inherit; } .wp-block-rss li a>div{ display:inline; } .wp-block-rss__placeholder-form .wp-block-rss__placeholder-input{ flex:1 1 auto; } .wp-block-rss .wp-block-rss{ all:inherit; margin:0; padding:0; } .wp-block[data-align=center] .wp-block-search .wp-block-search__inside-wrapper{ margin:auto; } .wp-block-search :where(.wp-block-search__button){ align-items:center; border-radius:initial; display:flex; height:auto; justify-content:center; text-align:center; } .wp-block-search__inspector-controls .components-base-control{ margin-bottom:0; } .block-editor-block-list__block[data-type="core/separator"]{ padding-bottom:.1px; padding-top:.1px; } .blocks-shortcode__textarea{ background:#fff !important; border:1px solid #1e1e1e !important; border-radius:2px !important; box-shadow:none !important; box-sizing:border-box; color:#1e1e1e !important; font-family:Menlo,Consolas,monaco,monospace !important; font-size:16px !important; max-height:250px; padding:12px !important; resize:none; } @media (min-width:600px){ .blocks-shortcode__textarea{ font-size:13px !important; } } .blocks-shortcode__textarea:focus{ border-color:var(--wp-admin-theme-color) !important; box-shadow:0 0 0 1px var(--wp-admin-theme-color) !important; outline:2px solid #0000 !important; } .wp-block-site-logo.aligncenter>div,.wp-block[data-align=center]>.wp-block-site-logo{ display:table; margin-left:auto; margin-right:auto; } .wp-block-site-logo a{ pointer-events:none; } .wp-block-site-logo .custom-logo-link{ cursor:inherit; } .wp-block-site-logo .custom-logo-link:focus{ box-shadow:none; } .wp-block-site-logo img{ display:block; height:auto; max-width:100%; } .wp-block-site-logo.is-transient{ position:relative; } .wp-block-site-logo.is-transient img{ opacity:.3; } .wp-block-site-logo.is-transient .components-spinner{ margin:0; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); } .wp-block-site-logo.wp-block-site-logo.is-default-size .components-placeholder{ height:60px; width:60px; } .wp-block-site-logo.wp-block-site-logo .components-resizable-box__container,.wp-block-site-logo.wp-block-site-logo>div{ border-radius:inherit; } .wp-block-site-logo.wp-block-site-logo .components-placeholder{ align-items:center; border-radius:inherit; display:flex; height:100%; justify-content:center; min-height:48px; min-width:48px; padding:0; width:100%; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-drop-zone__content-text,.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-form-file-upload{ display:none; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button{ align-items:center; background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); border-radius:50%; border-style:solid; color:#fff; display:flex; height:48px; justify-content:center; margin:auto; padding:0; position:relative; width:48px; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button>svg{ color:inherit; } .block-library-site-logo__inspector-media-replace-container{ position:relative; } .block-library-site-logo__inspector-media-replace-container .components-drop-zone__content-icon{ display:none; } .block-library-site-logo__inspector-media-replace-container button.components-button{ box-shadow:inset 0 0 0 1px #ccc; color:#1e1e1e; display:block; height:40px; width:100%; } .block-library-site-logo__inspector-media-replace-container button.components-button:hover{ color:var(--wp-admin-theme-color); } .block-library-site-logo__inspector-media-replace-container button.components-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-media-replace-title{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-library-site-logo__inspector-media-replace-container .components-dropdown{ display:block; } .block-library-site-logo__inspector-media-replace-container img{ aspect-ratio:1; border-radius:50% !important; box-shadow:inset 0 0 0 1px #0003; min-width:20px; width:20px; } .block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-readonly-logo-preview{ display:flex; height:40px; padding:6px 12px; } .wp-block-site-tagline__placeholder,.wp-block-site-title__placeholder{ border:1px dashed; padding:1em 0; } .wp-block-social-links .wp-social-link{ line-height:0; } .wp-block-social-link-anchor{ align-items:center; background:none; border:0; box-sizing:border-box; color:currentColor; cursor:pointer; display:inline-flex; font-family:inherit; font-size:inherit; font-weight:inherit; height:auto; margin:0; opacity:1; padding:.25em; } .wp-block-social-link-anchor:hover{ transform:none; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link button){ padding-left:.6666666667em; padding-right:.6666666667em; } :root :where(.wp-block-social-links.is-style-logos-only .wp-social-link button){ padding:0; } .wp-block-social-link__toolbar_content_text{ width:250px; } .wp-block-social-links div.block-editor-url-input{ display:inline-block; margin-right:8px; } .wp-social-link:hover{ transform:none; } :root :where(.wp-block-social-links),:root :where(.wp-block-social-links.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link){ padding:0; } :root :where(.wp-block-social-links__social-placeholder .wp-social-link){ padding:.25em; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-block-social-links__social-placeholder .wp-social-link){ padding-left:.6666666667em; padding-right:.6666666667em; } .wp-block-social-links__social-placeholder{ display:flex; list-style:none; opacity:.8; } .wp-block-social-links__social-placeholder>.wp-social-link{ margin-left:0 !important; margin-right:0 !important; padding-left:0 !important; padding-right:0 !important; visibility:hidden; width:0 !important; } .wp-block-social-links__social-placeholder>.wp-block-social-links__social-placeholder-icons{ display:flex; } .wp-block-social-links__social-placeholder .wp-social-link:before{ border-radius:50%; content:""; display:block; height:1em; width:1em; } .is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link:before{ background:currentColor; } .wp-block-social-links .wp-block-social-links__social-prompt{ cursor:default; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:24px; list-style:none; margin-bottom:auto; margin-top:auto; min-height:24px; padding-left:8px; } .wp-block.wp-block-social-links.aligncenter,.wp-block[data-align=center]>.wp-block-social-links{ justify-content:center; } .block-editor-block-preview__content .components-button:disabled{ opacity:1; } .wp-social-link.wp-social-link__is-incomplete{ opacity:.5; } .wp-block-social-links .is-selected .wp-social-link__is-incomplete,.wp-social-link.wp-social-link__is-incomplete:focus,.wp-social-link.wp-social-link__is-incomplete:hover{ opacity:1; } .wp-block-social-links .block-list-appender{ position:static; } .wp-block-social-links .block-list-appender .block-editor-inserter{ font-size:inherit; } .wp-block-social-links .block-list-appender .block-editor-button-block-appender{ font-size:inherit; height:1.5em; padding:0; width:1.5em; } .block-editor-block-list__block[data-type="core/spacer"]:before{ content:""; display:block; height:100%; min-height:8px; min-width:8px; position:absolute; width:100%; z-index:1; } .block-library-spacer__resize-container.has-show-handle,.wp-block-spacer.is-hovered .block-library-spacer__resize-container,.wp-block-spacer.is-selected.custom-sizes-disabled{ background:#0000001a; } .is-dark-theme .block-library-spacer__resize-container.has-show-handle,.is-dark-theme .wp-block-spacer.is-hovered .block-library-spacer__resize-container,.is-dark-theme .wp-block-spacer.is-selected.custom-sizes-disabled{ background:#ffffff26; } .block-library-spacer__resize-container{ clear:both; } .block-library-spacer__resize-container:not(.is-resizing){ height:100% !important; width:100% !important; } .block-library-spacer__resize-container .components-resizable-box__handle:before{ content:none; } .block-library-spacer__resize-container.resize-horizontal{ height:100% !important; margin-bottom:0; } .wp-block[data-align=center]>.wp-block-table,.wp-block[data-align=left]>.wp-block-table,.wp-block[data-align=right]>.wp-block-table{ height:auto; } .wp-block[data-align=center]>.wp-block-table table,.wp-block[data-align=left]>.wp-block-table table,.wp-block[data-align=right]>.wp-block-table table{ width:auto; } .wp-block[data-align=center]>.wp-block-table td,.wp-block[data-align=center]>.wp-block-table th,.wp-block[data-align=left]>.wp-block-table td,.wp-block[data-align=left]>.wp-block-table th,.wp-block[data-align=right]>.wp-block-table td,.wp-block[data-align=right]>.wp-block-table th{ word-break:break-word; } .wp-block[data-align=center]>.wp-block-table{ text-align:initial; } .wp-block[data-align=center]>.wp-block-table table{ margin:0 auto; } .wp-block-table td,.wp-block-table th{ border:1px solid; padding:.5em; } .wp-block-table td.is-selected,.wp-block-table th.is-selected{ border-color:var(--wp-admin-theme-color); border-style:double; box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .wp-block-table table.has-individual-borders td,.wp-block-table table.has-individual-borders th,.wp-block-table table.has-individual-borders tr,.wp-block-table table.has-individual-borders>*{ border:1px solid; } .blocks-table__placeholder-form.blocks-table__placeholder-form{ align-items:flex-start; display:flex; flex-direction:column; gap:8px; } @media (min-width:782px){ .blocks-table__placeholder-form.blocks-table__placeholder-form{ align-items:flex-end; flex-direction:row; } } .blocks-table__placeholder-input{ width:112px; } .wp-block-tag-cloud .wp-block-tag-cloud{ border:none; border-radius:inherit; margin:0; padding:0; } .block-editor-template-part__selection-modal{ z-index:1000001; } .block-editor-template-part__selection-modal .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:1280px){ .block-editor-template-part__selection-modal .block-editor-block-patterns-list{ column-count:3; } } .block-editor-template-part__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .block-library-template-part__selection-search{ background:#fff; padding:16px 0; position:sticky; top:0; z-index:2; } .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{ outline-color:var(--wp-block-synced-color); } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.has-editable-outline:after{ border:none; } .wp-block-text-columns .block-editor-rich-text__editable:focus{ outline:1px solid #ddd; } .wp-block[data-align=center]>.wp-block-video{ text-align:center; } .wp-block-video{ position:relative; } .wp-block-video.is-transient video{ opacity:.3; } .wp-block-video .components-spinner{ margin-right:-9px; margin-top:-9px; position:absolute; right:50%; top:50%; } .editor-video-poster-control .components-button{ margin-left:8px; } .block-library-video-tracks-editor{ z-index:159990; } .block-library-video-tracks-editor__track-list-track{ padding-right:12px; } .block-library-video-tracks-editor__single-track-editor-kind-select{ max-width:240px; } .block-library-video-tracks-editor__single-track-editor-edit-track-label,.block-library-video-tracks-editor__tracks-informative-message-title{ color:#757575; display:block; font-size:11px; font-weight:500; margin-top:4px; text-transform:uppercase; } .block-library-video-tracks-editor>.components-popover__content{ width:360px; } .block-library-video-tracks-editor__add-tracks-container .components-menu-group__label,.block-library-video-tracks-editor__track-list .components-menu-group__label{ padding:0; } .block-library-video-tracks-editor__tracks-informative-message{ padding:8px; } .block-library-video-tracks-editor__tracks-informative-message-description{ margin-bottom:0; } .block-library-query-pattern__selection-modal .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:1280px){ .block-library-query-pattern__selection-modal .block-editor-block-patterns-list{ column-count:3; } } .block-library-query-pattern__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .block-library-query-pattern__selection-modal .block-library-query-pattern__selection-search{ background:#fff; margin-bottom:-4px; padding:16px 0; position:sticky; top:0; transform:translateY(-4px); z-index:2; } @media (min-width:600px){ .wp-block-query__enhanced-pagination-modal{ max-width:480px; } } .block-editor-block-settings-menu__popover.is-expanded{ overflow-y:scroll; } .block-editor-block-settings-menu__popover .block-library-query-pattern__selection-content{ height:100%; } .block-editor-block-settings-menu__popover .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr; grid-gap:12px; min-width:280px; } @media (min-width:600px){ .block-editor-block-settings-menu__popover .block-editor-block-patterns-list{ grid-template-columns:1fr 1fr; min-width:480px; } } .block-editor-block-settings-menu__popover .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .wp-block[data-align=center]>.wp-block-query-pagination{ justify-content:center; } :where(.editor-styles-wrapper) .wp-block-query-pagination{ max-width:100%; } :where(.editor-styles-wrapper) .wp-block-query-pagination.block-editor-block-list__layout{ margin:0; } .wp-block-query-pagination-numbers a{ text-decoration:underline; } .wp-block-query-pagination-numbers .page-numbers{ margin-left:2px; } .wp-block-query-pagination-numbers .page-numbers:last-child{ margin-right:0; } .wp-block-post-featured-image .block-editor-media-placeholder{ -webkit-backdrop-filter:none; backdrop-filter:none; z-index:1; } .wp-block-post-featured-image .components-placeholder,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder{ align-items:center; display:flex; justify-content:center; min-height:200px; padding:0; } .wp-block-post-featured-image .components-placeholder .components-form-file-upload,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-form-file-upload{ display:none; } .wp-block-post-featured-image .components-placeholder .components-button,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button{ align-items:center; background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); border-radius:50%; border-style:solid; color:#fff; display:flex; height:48px; justify-content:center; margin:auto; padding:0; position:relative; width:48px; } .wp-block-post-featured-image .components-placeholder .components-button>svg,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button>svg{ color:inherit; } .wp-block-post-featured-image .components-placeholder:where(.has-border-color),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where(.has-border-color),.wp-block-post-featured-image img:where(.has-border-color){ border-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-top-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-color]),.wp-block-post-featured-image img:where([style*=border-top-color]){ border-top-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-right-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-color]),.wp-block-post-featured-image img:where([style*=border-right-color]){ border-left-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image img:where([style*=border-bottom-color]){ border-bottom-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-left-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-color]),.wp-block-post-featured-image img:where([style*=border-left-color]){ border-right-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-width]),.wp-block-post-featured-image img:where([style*=border-width]){ border-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-top-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-width]),.wp-block-post-featured-image img:where([style*=border-top-width]){ border-top-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-right-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-width]),.wp-block-post-featured-image img:where([style*=border-right-width]){ border-left-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image img:where([style*=border-bottom-width]){ border-bottom-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-left-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-width]),.wp-block-post-featured-image img:where([style*=border-left-width]){ border-right-style:solid; } .wp-block-post-featured-image[style*=height] .components-placeholder{ height:100%; min-height:48px; min-width:48px; width:100%; } .wp-block-post-featured-image>a{ pointer-events:none; } .wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-button,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__instructions,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__label{ opacity:1; pointer-events:auto; } .wp-block-post-featured-image.is-transient{ position:relative; } .wp-block-post-featured-image.is-transient img{ opacity:.3; } .wp-block-post-featured-image.is-transient .components-spinner{ position:absolute; right:50%; top:50%; transform:translate(50%, -50%); } div[data-type="core/post-featured-image"] img{ display:block; height:auto; max-width:100%; } .wp-block-post-comments-form *{ pointer-events:none; } .wp-block-post-comments-form .block-editor-warning *{ pointer-events:auto; } .wp-element-button{ cursor:revert; } .wp-element-button[role=textbox]{ cursor:text; } :root .editor-styles-wrapper .has-very-light-gray-background-color{ background-color:#eee; } :root .editor-styles-wrapper .has-very-dark-gray-background-color{ background-color:#313131; } :root .editor-styles-wrapper .has-very-light-gray-color{ color:#eee; } :root .editor-styles-wrapper .has-very-dark-gray-color{ color:#313131; } :root .editor-styles-wrapper .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(-135deg, #00d084, #0693e3); } :root .editor-styles-wrapper .has-purple-crush-gradient-background{ background:linear-gradient(-135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .editor-styles-wrapper .has-hazy-dawn-gradient-background{ background:linear-gradient(-135deg, #faaca8, #dad0ec); } :root .editor-styles-wrapper .has-subdued-olive-gradient-background{ background:linear-gradient(-135deg, #fafae1, #67a671); } :root .editor-styles-wrapper .has-atomic-cream-gradient-background{ background:linear-gradient(-135deg, #fdd79a, #004a59); } :root .editor-styles-wrapper .has-nightshade-gradient-background{ background:linear-gradient(-135deg, #330968, #31cdcf); } :root .editor-styles-wrapper .has-midnight-gradient-background{ background:linear-gradient(-135deg, #020381, #2874fc); } :where(.editor-styles-wrapper) .has-regular-font-size{ font-size:16px; } :where(.editor-styles-wrapper) .has-larger-font-size{ font-size:42px; } :where(.editor-styles-wrapper) iframe:not([frameborder]){ border:0; }@charset "UTF-8";.wp-block-archives{box-sizing:border-box}.wp-block-archives-dropdown label{display:block}.wp-block-avatar{line-height:0}.wp-block-avatar,.wp-block-avatar img{box-sizing:border-box}.wp-block-avatar.aligncenter{text-align:center}.wp-block-audio{box-sizing:border-box}.wp-block-audio :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-audio audio{min-width:300px;width:100%}.wp-block-button__link{align-content:center;box-sizing:border-box;cursor:pointer;display:inline-block;height:100%;text-align:center;word-break:break-word}.wp-block-button__link.aligncenter{text-align:center}.wp-block-button__link.alignright{text-align:right}:where(.wp-block-button__link){border-radius:9999px;box-shadow:none;padding:calc(.667em + 2px) calc(1.333em + 2px);text-decoration:none}.wp-block-button[style*=text-decoration] .wp-block-button__link{text-decoration:inherit}.wp-block-buttons>.wp-block-button.has-custom-width{max-width:none}.wp-block-buttons>.wp-block-button.has-custom-width .wp-block-button__link{width:100%}.wp-block-buttons>.wp-block-button.has-custom-font-size .wp-block-button__link{font-size:inherit}.wp-block-buttons>.wp-block-button.wp-block-button__width-25{width:calc(25% - var(--wp--style--block-gap, .5em)*.75)}.wp-block-buttons>.wp-block-button.wp-block-button__width-50{width:calc(50% - var(--wp--style--block-gap, .5em)*.5)}.wp-block-buttons>.wp-block-button.wp-block-button__width-75{width:calc(75% - var(--wp--style--block-gap, .5em)*.25)}.wp-block-buttons>.wp-block-button.wp-block-button__width-100{flex-basis:100%;width:100%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-25{width:25%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-50{width:50%}.wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-75{width:75%}.wp-block-button.is-style-squared,.wp-block-button__link.wp-block-button.is-style-squared{border-radius:0}.wp-block-button.no-border-radius,.wp-block-button__link.no-border-radius{border-radius:0!important}:root :where(.wp-block-button .wp-block-button__link.is-style-outline),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link){border:2px solid;padding:.667em 1.333em}:root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-text-color)){color:currentColor}:root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-background)){background-color:initial;background-image:none}.wp-block-buttons{box-sizing:border-box}.wp-block-buttons.is-vertical{flex-direction:column}.wp-block-buttons.is-vertical>.wp-block-button:last-child{margin-bottom:0}.wp-block-buttons>.wp-block-button{display:inline-block;margin:0}.wp-block-buttons.is-content-justification-left{justify-content:flex-start}.wp-block-buttons.is-content-justification-left.is-vertical{align-items:flex-start}.wp-block-buttons.is-content-justification-center{justify-content:center}.wp-block-buttons.is-content-justification-center.is-vertical{align-items:center}.wp-block-buttons.is-content-justification-right{justify-content:flex-end}.wp-block-buttons.is-content-justification-right.is-vertical{align-items:flex-end}.wp-block-buttons.is-content-justification-space-between{justify-content:space-between}.wp-block-buttons.aligncenter{text-align:center}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block-button.aligncenter{margin-left:auto;margin-right:auto;width:100%}.wp-block-buttons[style*=text-decoration] .wp-block-button,.wp-block-buttons[style*=text-decoration] .wp-block-button__link{text-decoration:inherit}.wp-block-buttons.has-custom-font-size .wp-block-button__link{font-size:inherit}.wp-block-buttons .wp-block-button__link{width:100%}.wp-block-button.aligncenter,.wp-block-calendar{text-align:center}.wp-block-calendar td,.wp-block-calendar th{border:1px solid;padding:.25em}.wp-block-calendar th{font-weight:400}.wp-block-calendar caption{background-color:inherit}.wp-block-calendar table{border-collapse:collapse;width:100%}.wp-block-calendar table:where(:not(.has-text-color)){color:#40464d}.wp-block-calendar table:where(:not(.has-text-color)) td,.wp-block-calendar table:where(:not(.has-text-color)) th{border-color:#ddd}.wp-block-calendar table.has-background th{background-color:inherit}.wp-block-calendar table.has-text-color th{color:inherit}:where(.wp-block-calendar table:not(.has-background) th){background:#ddd}.wp-block-categories{box-sizing:border-box}.wp-block-categories.alignleft{margin-right:2em}.wp-block-categories.alignright{margin-left:2em}.wp-block-categories.wp-block-categories-dropdown.aligncenter{text-align:center}.wp-block-categories .wp-block-categories__label{display:block;width:100%}.wp-block-code{box-sizing:border-box}.wp-block-code code{ /*!rtl:begin:ignore*/direction:ltr;display:block;font-family:inherit;overflow-wrap:break-word;text-align:initial;white-space:pre-wrap /*!rtl:end:ignore*/}.wp-block-columns{align-items:normal!important;box-sizing:border-box;display:flex;flex-wrap:wrap!important}@media (min-width:782px){.wp-block-columns{flex-wrap:nowrap!important}}.wp-block-columns.are-vertically-aligned-top{align-items:flex-start}.wp-block-columns.are-vertically-aligned-center{align-items:center}.wp-block-columns.are-vertically-aligned-bottom{align-items:flex-end}@media (max-width:781px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:100%!important}}@media (min-width:782px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column[style*=flex-basis]{flex-grow:0}}.wp-block-columns.is-not-stacked-on-mobile{flex-wrap:nowrap!important}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column[style*=flex-basis]{flex-grow:0}:where(.wp-block-columns){margin-bottom:1.75em}:where(.wp-block-columns.has-background){padding:1.25em 2.375em}.wp-block-column{flex-grow:1;min-width:0;overflow-wrap:break-word;word-break:break-word}.wp-block-column.is-vertically-aligned-top{align-self:flex-start}.wp-block-column.is-vertically-aligned-center{align-self:center}.wp-block-column.is-vertically-aligned-bottom{align-self:flex-end}.wp-block-column.is-vertically-aligned-stretch{align-self:stretch}.wp-block-column.is-vertically-aligned-bottom,.wp-block-column.is-vertically-aligned-center,.wp-block-column.is-vertically-aligned-top{width:100%}.wp-block-post-comments{box-sizing:border-box}.wp-block-post-comments .alignleft{float:left}.wp-block-post-comments .alignright{float:right}.wp-block-post-comments .navigation:after{clear:both;content:"";display:table}.wp-block-post-comments .commentlist{clear:both;list-style:none;margin:0;padding:0}.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-left:3.25em}.wp-block-post-comments .commentlist .comment p{font-size:1em;line-height:1.8;margin:1em 0}.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-post-comments .comment-author{line-height:1.5}.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:left;height:2.5em;margin-right:.75em;margin-top:.5em;width:2.5em}.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-post-comments .comment-meta{font-size:.875em;line-height:1.5}.wp-block-post-comments .comment-meta b{font-weight:400}.wp-block-post-comments .comment-meta .comment-awaiting-moderation{display:block;margin-bottom:1em;margin-top:1em}.wp-block-post-comments .comment-body .commentmetadata{font-size:.875em}.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments .comment-reply-title{margin-bottom:0}.wp-block-post-comments .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-left:.5em}.wp-block-post-comments .reply{font-size:.875em;margin-bottom:1.4em}.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-family:inherit;font-size:1em}.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}:where(.wp-block-post-comments input[type=submit]){border:none}.wp-block-comments{box-sizing:border-box}.wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{font-size:inherit;margin-bottom:.5em;margin-right:.5em}.wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{margin-right:0}.wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow{display:inline-block;margin-right:1ch}.wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-comments-pagination .wp-block-comments-pagination-next-arrow{display:inline-block;margin-left:1ch}.wp-block-comments-pagination .wp-block-comments-pagination-next-arrow:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-comments-pagination.aligncenter{justify-content:center}.wp-block-comment-template{box-sizing:border-box;list-style:none;margin-bottom:0;max-width:100%;padding:0}.wp-block-comment-template li{clear:both}.wp-block-comment-template ol{list-style:none;margin-bottom:0;max-width:100%;padding-left:2rem}.wp-block-comment-template.alignleft{float:left}.wp-block-comment-template.aligncenter{margin-left:auto;margin-right:auto;width:fit-content}.wp-block-comment-template.alignright{float:right}.wp-block-comment-date{box-sizing:border-box}.comment-awaiting-moderation{display:block;font-size:.875em;line-height:1.5}.wp-block-comment-author-name,.wp-block-comment-content,.wp-block-comment-edit-link,.wp-block-comment-reply-link{box-sizing:border-box}.wp-block-cover,.wp-block-cover-image{align-items:center;background-position:50%;box-sizing:border-box;display:flex;justify-content:center;min-height:430px;overflow:hidden;overflow:clip;padding:1em;position:relative}.wp-block-cover .has-background-dim:not([class*=-background-color]),.wp-block-cover-image .has-background-dim:not([class*=-background-color]),.wp-block-cover-image.has-background-dim:not([class*=-background-color]),.wp-block-cover.has-background-dim:not([class*=-background-color]){background-color:#000}.wp-block-cover .has-background-dim.has-background-gradient,.wp-block-cover-image .has-background-dim.has-background-gradient{background-color:initial}.wp-block-cover-image.has-background-dim:before,.wp-block-cover.has-background-dim:before{background-color:inherit;content:""}.wp-block-cover .wp-block-cover__background,.wp-block-cover .wp-block-cover__gradient-background,.wp-block-cover-image .wp-block-cover__background,.wp-block-cover-image .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim:not(.has-background-gradient):before,.wp-block-cover.has-background-dim:not(.has-background-gradient):before{bottom:0;left:0;opacity:.5;position:absolute;right:0;top:0}.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-10:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-10:not(.has-background-gradient):before{opacity:.1}.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-20:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-20:not(.has-background-gradient):before{opacity:.2}.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-30:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-30:not(.has-background-gradient):before{opacity:.3}.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-40:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-40:not(.has-background-gradient):before{opacity:.4}.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-50:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-50:not(.has-background-gradient):before{opacity:.5}.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-60:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-60:not(.has-background-gradient):before{opacity:.6}.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-70:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-70:not(.has-background-gradient):before{opacity:.7}.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-80:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-80:not(.has-background-gradient):before{opacity:.8}.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-90:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-90:not(.has-background-gradient):before{opacity:.9}.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-100:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-100:not(.has-background-gradient):before{opacity:1}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0{opacity:0}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10{opacity:.1}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20{opacity:.2}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30{opacity:.3}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40{opacity:.4}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50{opacity:.5}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60{opacity:.6}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70{opacity:.7}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80{opacity:.8}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90{opacity:.9}.wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100{opacity:1}.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.alignleft,.wp-block-cover.alignright{max-width:420px;width:100%}.wp-block-cover-image.aligncenter,.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.aligncenter,.wp-block-cover.alignleft,.wp-block-cover.alignright{display:flex}.wp-block-cover .wp-block-cover__inner-container,.wp-block-cover-image .wp-block-cover__inner-container{color:inherit;position:relative;width:100%}.wp-block-cover-image.is-position-top-left,.wp-block-cover.is-position-top-left{align-items:flex-start;justify-content:flex-start}.wp-block-cover-image.is-position-top-center,.wp-block-cover.is-position-top-center{align-items:flex-start;justify-content:center}.wp-block-cover-image.is-position-top-right,.wp-block-cover.is-position-top-right{align-items:flex-start;justify-content:flex-end}.wp-block-cover-image.is-position-center-left,.wp-block-cover.is-position-center-left{align-items:center;justify-content:flex-start}.wp-block-cover-image.is-position-center-center,.wp-block-cover.is-position-center-center{align-items:center;justify-content:center}.wp-block-cover-image.is-position-center-right,.wp-block-cover.is-position-center-right{align-items:center;justify-content:flex-end}.wp-block-cover-image.is-position-bottom-left,.wp-block-cover.is-position-bottom-left{align-items:flex-end;justify-content:flex-start}.wp-block-cover-image.is-position-bottom-center,.wp-block-cover.is-position-bottom-center{align-items:flex-end;justify-content:center}.wp-block-cover-image.is-position-bottom-right,.wp-block-cover.is-position-bottom-right{align-items:flex-end;justify-content:flex-end}.wp-block-cover-image.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container{margin:0}.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container{margin:0;width:auto}.wp-block-cover .wp-block-cover__image-background,.wp-block-cover video.wp-block-cover__video-background,.wp-block-cover-image .wp-block-cover__image-background,.wp-block-cover-image video.wp-block-cover__video-background{border:none;bottom:0;box-shadow:none;height:100%;left:0;margin:0;max-height:none;max-width:none;object-fit:cover;outline:none;padding:0;position:absolute;right:0;top:0;width:100%}.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:fixed;background-repeat:no-repeat;background-size:cover}@supports (-webkit-touch-callout:inherit){.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:scroll}}@media (prefers-reduced-motion:reduce){.wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{background-attachment:scroll}}.wp-block-cover-image.is-repeated,.wp-block-cover.is-repeated,.wp-block-cover__image-background.is-repeated,video.wp-block-cover__video-background.is-repeated{background-repeat:repeat;background-size:auto}.wp-block-cover-image-text,.wp-block-cover-image-text a,.wp-block-cover-image-text a:active,.wp-block-cover-image-text a:focus,.wp-block-cover-image-text a:hover,.wp-block-cover-text,.wp-block-cover-text a,.wp-block-cover-text a:active,.wp-block-cover-text a:focus,.wp-block-cover-text a:hover,section.wp-block-cover-image h2,section.wp-block-cover-image h2 a,section.wp-block-cover-image h2 a:active,section.wp-block-cover-image h2 a:focus,section.wp-block-cover-image h2 a:hover{color:#fff}.wp-block-cover-image .wp-block-cover.has-left-content{justify-content:flex-start}.wp-block-cover-image .wp-block-cover.has-right-content{justify-content:flex-end}.wp-block-cover-image.has-left-content .wp-block-cover-image-text,.wp-block-cover.has-left-content .wp-block-cover-text,section.wp-block-cover-image.has-left-content>h2{margin-left:0;text-align:left}.wp-block-cover-image.has-right-content .wp-block-cover-image-text,.wp-block-cover.has-right-content .wp-block-cover-text,section.wp-block-cover-image.has-right-content>h2{margin-right:0;text-align:right}.wp-block-cover .wp-block-cover-text,.wp-block-cover-image .wp-block-cover-image-text,section.wp-block-cover-image>h2{font-size:2em;line-height:1.25;margin-bottom:0;max-width:840px;padding:.44em;text-align:center;z-index:1}:where(.wp-block-cover-image:not(.has-text-color)),:where(.wp-block-cover:not(.has-text-color)){color:#fff}:where(.wp-block-cover-image.is-light:not(.has-text-color)),:where(.wp-block-cover.is-light:not(.has-text-color)){color:#000}:root :where(.wp-block-cover h1:not(.has-text-color)),:root :where(.wp-block-cover h2:not(.has-text-color)),:root :where(.wp-block-cover h3:not(.has-text-color)),:root :where(.wp-block-cover h4:not(.has-text-color)),:root :where(.wp-block-cover h5:not(.has-text-color)),:root :where(.wp-block-cover h6:not(.has-text-color)),:root :where(.wp-block-cover p:not(.has-text-color)){color:inherit}body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__image-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__video-background{z-index:0}body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__gradient-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)).has-background-dim:not(.has-background-gradient):before{z-index:1}.has-modal-open body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container{z-index:auto}.wp-block-details{box-sizing:border-box}.wp-block-details summary{cursor:pointer}.wp-block-embed.alignleft,.wp-block-embed.alignright,.wp-block[data-align=left]>[data-type="core/embed"],.wp-block[data-align=right]>[data-type="core/embed"]{max-width:360px;width:100%}.wp-block-embed.alignleft .wp-block-embed__wrapper,.wp-block-embed.alignright .wp-block-embed__wrapper,.wp-block[data-align=left]>[data-type="core/embed"] .wp-block-embed__wrapper,.wp-block[data-align=right]>[data-type="core/embed"] .wp-block-embed__wrapper{min-width:280px}.wp-block-cover .wp-block-embed{min-height:240px;min-width:320px}.wp-block-embed{overflow-wrap:break-word}.wp-block-embed :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-embed iframe{max-width:100%}.wp-block-embed__wrapper{position:relative}.wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper:before{content:"";display:block;padding-top:50%}.wp-embed-responsive .wp-has-aspect-ratio iframe{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.wp-embed-responsive .wp-embed-aspect-21-9 .wp-block-embed__wrapper:before{padding-top:42.85%}.wp-embed-responsive .wp-embed-aspect-18-9 .wp-block-embed__wrapper:before{padding-top:50%}.wp-embed-responsive .wp-embed-aspect-16-9 .wp-block-embed__wrapper:before{padding-top:56.25%}.wp-embed-responsive .wp-embed-aspect-4-3 .wp-block-embed__wrapper:before{padding-top:75%}.wp-embed-responsive .wp-embed-aspect-1-1 .wp-block-embed__wrapper:before{padding-top:100%}.wp-embed-responsive .wp-embed-aspect-9-16 .wp-block-embed__wrapper:before{padding-top:177.77%}.wp-embed-responsive .wp-embed-aspect-1-2 .wp-block-embed__wrapper:before{padding-top:200%}.wp-block-file{box-sizing:border-box}.wp-block-file:not(.wp-element-button){font-size:.8em}.wp-block-file.aligncenter{text-align:center}.wp-block-file.alignright{text-align:right}.wp-block-file *+.wp-block-file__button{margin-left:.75em}:where(.wp-block-file){margin-bottom:1.5em}.wp-block-file__embed{margin-bottom:1em}:where(.wp-block-file__button){border-radius:2em;display:inline-block;padding:.5em 1em}:where(.wp-block-file__button):is(a):active,:where(.wp-block-file__button):is(a):focus,:where(.wp-block-file__button):is(a):hover,:where(.wp-block-file__button):is(a):visited{box-shadow:none;color:#fff;opacity:.85;text-decoration:none}.wp-block-form-input__label{display:flex;flex-direction:column;gap:.25em;margin-bottom:.5em;width:100%}.wp-block-form-input__label.is-label-inline{align-items:center;flex-direction:row;gap:.5em}.wp-block-form-input__label.is-label-inline .wp-block-form-input__label-content{margin-bottom:.5em}.wp-block-form-input__label:has(input[type=checkbox]){flex-direction:row;width:fit-content}.wp-block-form-input__label:has(input[type=checkbox]) .wp-block-form-input__label-content{margin:0}.wp-block-form-input__label:has(.wp-block-form-input__label-content+input[type=checkbox]){flex-direction:row-reverse}.wp-block-form-input__label-content{width:fit-content}.wp-block-form-input__input{font-size:1em;margin-bottom:.5em;padding:0 .5em}.wp-block-form-input__input[type=date],.wp-block-form-input__input[type=datetime-local],.wp-block-form-input__input[type=datetime],.wp-block-form-input__input[type=email],.wp-block-form-input__input[type=month],.wp-block-form-input__input[type=number],.wp-block-form-input__input[type=password],.wp-block-form-input__input[type=search],.wp-block-form-input__input[type=tel],.wp-block-form-input__input[type=text],.wp-block-form-input__input[type=time],.wp-block-form-input__input[type=url],.wp-block-form-input__input[type=week]{border:1px solid;line-height:2;min-height:2em}textarea.wp-block-form-input__input{min-height:10em}.blocks-gallery-grid:not(.has-nested-images),.wp-block-gallery:not(.has-nested-images){display:flex;flex-wrap:wrap;list-style-type:none;margin:0;padding:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item{display:flex;flex-direction:column;flex-grow:1;justify-content:center;margin:0 1em 1em 0;position:relative;width:calc(50% - 1em)}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n){margin-right:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figure,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figure{align-items:flex-end;display:flex;height:100%;justify-content:flex-start;margin:0}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item img{display:block;height:auto;max-width:100%;width:auto}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption{background:linear-gradient(0deg,#000000b3,#0000004d 70%,#0000);bottom:0;box-sizing:border-box;color:#fff;font-size:.8em;margin:0;max-height:100%;overflow:auto;padding:3em .77em .7em;position:absolute;text-align:center;width:100%;z-index:2}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption img{display:inline}.blocks-gallery-grid:not(.has-nested-images) figcaption,.wp-block-gallery:not(.has-nested-images) figcaption{flex-grow:1}.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item img{flex:1;height:100%;object-fit:cover;width:100%}.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item{margin-right:0;width:100%}@media (min-width:600px){.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item{margin-right:1em;width:calc(33.33333% - .66667em)}.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item{margin-right:1em;width:calc(25% - .75em)}.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item{margin-right:1em;width:calc(20% - .8em)}.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item{margin-right:1em;width:calc(16.66667% - .83333em)}.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item{margin-right:1em;width:calc(14.28571% - .85714em)}.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item{margin-right:1em;width:calc(12.5% - .875em)}.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n){margin-right:0}}.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:last-child,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:last-child{margin-right:0}.blocks-gallery-grid:not(.has-nested-images).alignleft,.blocks-gallery-grid:not(.has-nested-images).alignright,.wp-block-gallery:not(.has-nested-images).alignleft,.wp-block-gallery:not(.has-nested-images).alignright{max-width:420px;width:100%}.blocks-gallery-grid:not(.has-nested-images).aligncenter .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images).aligncenter .blocks-gallery-item figure{justify-content:center}.wp-block-gallery:not(.is-cropped) .blocks-gallery-item{align-self:flex-start}figure.wp-block-gallery.has-nested-images{align-items:normal}.wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image){margin:0;width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)/2)}.wp-block-gallery.has-nested-images figure.wp-block-image{box-sizing:border-box;display:flex;flex-direction:column;flex-grow:1;justify-content:center;max-width:100%;position:relative}.wp-block-gallery.has-nested-images figure.wp-block-image>a,.wp-block-gallery.has-nested-images figure.wp-block-image>div{flex-direction:column;flex-grow:1;margin:0}.wp-block-gallery.has-nested-images figure.wp-block-image img{display:block;height:auto;max-width:100%!important;width:auto}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{bottom:0;left:0;max-height:100%;position:absolute;right:0}.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);content:"";height:100%;-webkit-mask-image:linear-gradient(0deg,#000 20%,#0000);mask-image:linear-gradient(0deg,#000 20%,#0000);max-height:40%}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption{background:linear-gradient(0deg,#0006,#0000);box-sizing:border-box;color:#fff;font-size:13px;margin:0;overflow:auto;padding:1em;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-width:thin;text-align:center;text-shadow:0 0 1.5px #000;will-change:transform}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar{height:12px;width:12px}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-track{background-color:initial}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover::-webkit-scrollbar-thumb{background-color:#fffc}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover{scrollbar-color:#fffc #0000}@media (hover:none){.wp-block-gallery.has-nested-images figure.wp-block-image figcaption{scrollbar-color:#fffc #0000}}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption img{display:inline}.wp-block-gallery.has-nested-images figure.wp-block-image figcaption a{color:inherit}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border img{box-sizing:border-box}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>a,.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>div,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>a,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>div{flex:1 1 auto}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded figcaption{background:none;color:inherit;flex:initial;margin:0;padding:10px 10px 9px;position:relative;text-shadow:none}.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border:before,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded:before{content:none}.wp-block-gallery.has-nested-images figcaption{flex-basis:100%;flex-grow:1;text-align:center}.wp-block-gallery.has-nested-images:not(.is-cropped) figure.wp-block-image:not(#individual-image){margin-bottom:auto;margin-top:0}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image){align-self:inherit}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>div:not(.components-drop-zone){display:flex}.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) img{flex:1 0 0%;height:100%;object-fit:cover;width:100%}.wp-block-gallery.has-nested-images.columns-1 figure.wp-block-image:not(#individual-image){width:100%}@media (min-width:600px){.wp-block-gallery.has-nested-images.columns-3 figure.wp-block-image:not(#individual-image){width:calc(33.33333% - var(--wp--style--unstable-gallery-gap, 16px)*.66667)}.wp-block-gallery.has-nested-images.columns-4 figure.wp-block-image:not(#individual-image){width:calc(25% - var(--wp--style--unstable-gallery-gap, 16px)*.75)}.wp-block-gallery.has-nested-images.columns-5 figure.wp-block-image:not(#individual-image){width:calc(20% - var(--wp--style--unstable-gallery-gap, 16px)*.8)}.wp-block-gallery.has-nested-images.columns-6 figure.wp-block-image:not(#individual-image){width:calc(16.66667% - var(--wp--style--unstable-gallery-gap, 16px)*.83333)}.wp-block-gallery.has-nested-images.columns-7 figure.wp-block-image:not(#individual-image){width:calc(14.28571% - var(--wp--style--unstable-gallery-gap, 16px)*.85714)}.wp-block-gallery.has-nested-images.columns-8 figure.wp-block-image:not(#individual-image){width:calc(12.5% - var(--wp--style--unstable-gallery-gap, 16px)*.875)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image){width:calc(33.33% - var(--wp--style--unstable-gallery-gap, 16px)*.66667)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2),.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2)~figure.wp-block-image:not(#individual-image){width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)*.5)}.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:last-child{width:100%}}.wp-block-gallery.has-nested-images.alignleft,.wp-block-gallery.has-nested-images.alignright{max-width:420px;width:100%}.wp-block-gallery.has-nested-images.aligncenter{justify-content:center}.wp-block-group{box-sizing:border-box}:where(.wp-block-group.wp-block-group-is-layout-constrained){position:relative}h1.has-background,h2.has-background,h3.has-background,h4.has-background,h5.has-background,h6.has-background{padding:1.25em 2.375em}h1.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h1.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h2.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h2.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h3.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h3.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h4.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h4.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h5.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h5.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h6.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h6.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]){rotate:180deg}.wp-block-image>a,.wp-block-image>figure>a{display:inline-block}.wp-block-image img{box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom}@media not (prefers-reduced-motion){.wp-block-image img.hide{visibility:hidden}.wp-block-image img.show{animation:show-content-image .4s}}.wp-block-image[style*=border-radius] img,.wp-block-image[style*=border-radius]>a{border-radius:inherit}.wp-block-image.has-custom-border img{box-sizing:border-box}.wp-block-image.aligncenter{text-align:center}.wp-block-image.alignfull>a,.wp-block-image.alignwide>a{width:100%}.wp-block-image.alignfull img,.wp-block-image.alignwide img{height:auto;width:100%}.wp-block-image .aligncenter,.wp-block-image .alignleft,.wp-block-image .alignright,.wp-block-image.aligncenter,.wp-block-image.alignleft,.wp-block-image.alignright{display:table}.wp-block-image .aligncenter>figcaption,.wp-block-image .alignleft>figcaption,.wp-block-image .alignright>figcaption,.wp-block-image.aligncenter>figcaption,.wp-block-image.alignleft>figcaption,.wp-block-image.alignright>figcaption{caption-side:bottom;display:table-caption}.wp-block-image .alignleft{float:left;margin:.5em 1em .5em 0}.wp-block-image .alignright{float:right;margin:.5em 0 .5em 1em}.wp-block-image .aligncenter{margin-left:auto;margin-right:auto}.wp-block-image :where(figcaption){margin-bottom:1em;margin-top:.5em}.wp-block-image.is-style-circle-mask img{border-radius:9999px}@supports ((-webkit-mask-image:none) or (mask-image:none)) or (-webkit-mask-image:none){.wp-block-image.is-style-circle-mask img{border-radius:0;-webkit-mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>');mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>');mask-mode:alpha;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain}}:root :where(.wp-block-image.is-style-rounded img,.wp-block-image .is-style-rounded img){border-radius:9999px}.wp-block-image figure{margin:0}.wp-lightbox-container{display:flex;flex-direction:column;position:relative}.wp-lightbox-container img{cursor:zoom-in}.wp-lightbox-container img:hover+button{opacity:1}.wp-lightbox-container button{align-items:center;-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background-color:#5a5a5a40;border:none;border-radius:4px;cursor:zoom-in;display:flex;height:20px;justify-content:center;opacity:0;padding:0;position:absolute;right:16px;text-align:center;top:16px;width:20px;z-index:100}@media not (prefers-reduced-motion){.wp-lightbox-container button{transition:opacity .2s ease}}.wp-lightbox-container button:focus-visible{outline:3px auto #5a5a5a40;outline:3px auto -webkit-focus-ring-color;outline-offset:3px}.wp-lightbox-container button:hover{cursor:pointer;opacity:1}.wp-lightbox-container button:focus{opacity:1}.wp-lightbox-container button:focus,.wp-lightbox-container button:hover,.wp-lightbox-container button:not(:hover):not(:active):not(.has-background){background-color:#5a5a5a40;border:none}.wp-lightbox-overlay{box-sizing:border-box;cursor:zoom-out;height:100vh;left:0;overflow:hidden;position:fixed;top:0;visibility:hidden;width:100%;z-index:100000}.wp-lightbox-overlay .close-button{align-items:center;cursor:pointer;display:flex;justify-content:center;min-height:40px;min-width:40px;padding:0;position:absolute;right:calc(env(safe-area-inset-right) + 16px);top:calc(env(safe-area-inset-top) + 16px);z-index:5000000}.wp-lightbox-overlay .close-button:focus,.wp-lightbox-overlay .close-button:hover,.wp-lightbox-overlay .close-button:not(:hover):not(:active):not(.has-background){background:none;border:none}.wp-lightbox-overlay .lightbox-image-container{height:var(--wp--lightbox-container-height);left:50%;overflow:hidden;position:absolute;top:50%;transform:translate(-50%,-50%);transform-origin:top left;width:var(--wp--lightbox-container-width);z-index:9999999999}.wp-lightbox-overlay .wp-block-image{align-items:center;box-sizing:border-box;display:flex;height:100%;justify-content:center;margin:0;position:relative;transform-origin:0 0;width:100%;z-index:3000000}.wp-lightbox-overlay .wp-block-image img{height:var(--wp--lightbox-image-height);min-height:var(--wp--lightbox-image-height);min-width:var(--wp--lightbox-image-width);width:var(--wp--lightbox-image-width)}.wp-lightbox-overlay .wp-block-image figcaption{display:none}.wp-lightbox-overlay button{background:none;border:none}.wp-lightbox-overlay .scrim{background-color:#fff;height:100%;opacity:.9;position:absolute;width:100%;z-index:2000000}.wp-lightbox-overlay.active{visibility:visible}@media not (prefers-reduced-motion){.wp-lightbox-overlay.active{animation:turn-on-visibility .25s both}.wp-lightbox-overlay.active img{animation:turn-on-visibility .35s both}.wp-lightbox-overlay.show-closing-animation:not(.active){animation:turn-off-visibility .35s both}.wp-lightbox-overlay.show-closing-animation:not(.active) img{animation:turn-off-visibility .25s both}.wp-lightbox-overlay.zoom.active{animation:none;opacity:1;visibility:visible}.wp-lightbox-overlay.zoom.active .lightbox-image-container{animation:lightbox-zoom-in .4s}.wp-lightbox-overlay.zoom.active .lightbox-image-container img{animation:none}.wp-lightbox-overlay.zoom.active .scrim{animation:turn-on-visibility .4s forwards}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active){animation:none}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container{animation:lightbox-zoom-out .4s}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container img{animation:none}.wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .scrim{animation:turn-off-visibility .4s forwards}}@keyframes show-content-image{0%{visibility:hidden}99%{visibility:hidden}to{visibility:visible}}@keyframes turn-on-visibility{0%{opacity:0}to{opacity:1}}@keyframes turn-off-visibility{0%{opacity:1;visibility:visible}99%{opacity:0;visibility:visible}to{opacity:0;visibility:hidden}}@keyframes lightbox-zoom-in{0%{transform:translate(calc((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position)),calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale))}to{transform:translate(-50%,-50%) scale(1)}}@keyframes lightbox-zoom-out{0%{transform:translate(-50%,-50%) scale(1);visibility:visible}99%{visibility:visible}to{transform:translate(calc((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position)),calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale));visibility:hidden}}ol.wp-block-latest-comments{box-sizing:border-box;margin-left:0}:where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment)){line-height:1.1}:where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment-excerpt p)){line-height:1.8}.has-dates :where(.wp-block-latest-comments:not([style*=line-height])),.has-excerpts :where(.wp-block-latest-comments:not([style*=line-height])){line-height:1.5}.wp-block-latest-comments .wp-block-latest-comments{padding-left:0}.wp-block-latest-comments__comment{list-style:none;margin-bottom:1em}.has-avatars .wp-block-latest-comments__comment{list-style:none;min-height:2.25em}.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-excerpt,.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-meta{margin-left:3.25em}.wp-block-latest-comments__comment-excerpt p{font-size:.875em;margin:.36em 0 1.4em}.wp-block-latest-comments__comment-date{display:block;font-size:.75em}.wp-block-latest-comments .avatar,.wp-block-latest-comments__comment-avatar{border-radius:1.5em;display:block;float:left;height:2.5em;margin-right:.75em;width:2.5em}.wp-block-latest-comments[class*=-font-size] a,.wp-block-latest-comments[style*=font-size] a{font-size:inherit}.wp-block-latest-posts{box-sizing:border-box}.wp-block-latest-posts.alignleft{margin-right:2em}.wp-block-latest-posts.alignright{margin-left:2em}.wp-block-latest-posts.wp-block-latest-posts__list{list-style:none}.wp-block-latest-posts.wp-block-latest-posts__list li{clear:both;overflow-wrap:break-word}.wp-block-latest-posts.is-grid{display:flex;flex-wrap:wrap}.wp-block-latest-posts.is-grid li{margin:0 1.25em 1.25em 0;width:100%}@media (min-width:600px){.wp-block-latest-posts.columns-2 li{width:calc(50% - .625em)}.wp-block-latest-posts.columns-2 li:nth-child(2n){margin-right:0}.wp-block-latest-posts.columns-3 li{width:calc(33.33333% - .83333em)}.wp-block-latest-posts.columns-3 li:nth-child(3n){margin-right:0}.wp-block-latest-posts.columns-4 li{width:calc(25% - .9375em)}.wp-block-latest-posts.columns-4 li:nth-child(4n){margin-right:0}.wp-block-latest-posts.columns-5 li{width:calc(20% - 1em)}.wp-block-latest-posts.columns-5 li:nth-child(5n){margin-right:0}.wp-block-latest-posts.columns-6 li{width:calc(16.66667% - 1.04167em)}.wp-block-latest-posts.columns-6 li:nth-child(6n){margin-right:0}}:root :where(.wp-block-latest-posts.is-grid){padding:0}:root :where(.wp-block-latest-posts.wp-block-latest-posts__list){padding-left:0}.wp-block-latest-posts__post-author,.wp-block-latest-posts__post-date{display:block;font-size:.8125em}.wp-block-latest-posts__post-excerpt,.wp-block-latest-posts__post-full-content{margin-bottom:1em;margin-top:.5em}.wp-block-latest-posts__featured-image a{display:inline-block}.wp-block-latest-posts__featured-image img{height:auto;max-width:100%;width:auto}.wp-block-latest-posts__featured-image.alignleft{float:left;margin-right:1em}.wp-block-latest-posts__featured-image.alignright{float:right;margin-left:1em}.wp-block-latest-posts__featured-image.aligncenter{margin-bottom:1em;text-align:center}ol,ul{box-sizing:border-box}:root :where(.wp-block-list.has-background){padding:1.25em 2.375em}.wp-block-loginout,.wp-block-media-text{box-sizing:border-box}.wp-block-media-text{ /*!rtl:begin:ignore*/direction:ltr; /*!rtl:end:ignore*/display:grid;grid-template-columns:50% 1fr;grid-template-rows:auto}.wp-block-media-text.has-media-on-the-right{grid-template-columns:1fr 50%}.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__media{align-self:start}.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__media,.wp-block-media-text>.wp-block-media-text__content,.wp-block-media-text>.wp-block-media-text__media{align-self:center}.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__media{align-self:end}.wp-block-media-text>.wp-block-media-text__media{ /*!rtl:begin:ignore*/grid-column:1;grid-row:1; /*!rtl:end:ignore*/margin:0}.wp-block-media-text>.wp-block-media-text__content{direction:ltr; /*!rtl:begin:ignore*/grid-column:2;grid-row:1; /*!rtl:end:ignore*/padding:0 8%;word-break:break-word}.wp-block-media-text.has-media-on-the-right>.wp-block-media-text__media{ /*!rtl:begin:ignore*/grid-column:2;grid-row:1 /*!rtl:end:ignore*/}.wp-block-media-text.has-media-on-the-right>.wp-block-media-text__content{ /*!rtl:begin:ignore*/grid-column:1;grid-row:1 /*!rtl:end:ignore*/}.wp-block-media-text__media a{display:block}.wp-block-media-text__media img,.wp-block-media-text__media video{height:auto;max-width:unset;vertical-align:middle;width:100%}.wp-block-media-text.is-image-fill>.wp-block-media-text__media{background-size:cover;height:100%;min-height:250px}.wp-block-media-text.is-image-fill>.wp-block-media-text__media>a{display:block;height:100%}.wp-block-media-text.is-image-fill>.wp-block-media-text__media img{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media{height:100%;min-height:250px;position:relative}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media>a{display:block;height:100%}.wp-block-media-text.is-image-fill-element>.wp-block-media-text__media img{height:100%;object-fit:cover;position:absolute;width:100%}@media (max-width:600px){.wp-block-media-text.is-stacked-on-mobile{grid-template-columns:100%!important}.wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__media{grid-column:1;grid-row:1}.wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__content{grid-column:1;grid-row:2}}.wp-block-navigation{position:relative;--navigation-layout-justification-setting:flex-start;--navigation-layout-direction:row;--navigation-layout-wrap:wrap;--navigation-layout-justify:flex-start;--navigation-layout-align:center}.wp-block-navigation ul{margin-bottom:0;margin-left:0;margin-top:0;padding-left:0}.wp-block-navigation ul,.wp-block-navigation ul li{list-style:none;padding:0}.wp-block-navigation .wp-block-navigation-item{align-items:center;display:flex;position:relative}.wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty{display:none}.wp-block-navigation .wp-block-navigation-item__content{display:block}.wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content{color:inherit}.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:focus{text-decoration:underline}.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:focus{text-decoration:line-through}.wp-block-navigation :where(a),.wp-block-navigation :where(a:active),.wp-block-navigation :where(a:focus){text-decoration:none}.wp-block-navigation .wp-block-navigation__submenu-icon{align-self:center;background-color:inherit;border:none;color:currentColor;display:inline-block;font-size:inherit;height:.6em;line-height:0;margin-left:.25em;padding:0;width:.6em}.wp-block-navigation .wp-block-navigation__submenu-icon svg{display:inline-block;stroke:currentColor;height:inherit;margin-top:.075em;width:inherit}.wp-block-navigation.is-vertical{--navigation-layout-direction:column;--navigation-layout-justify:initial;--navigation-layout-align:flex-start}.wp-block-navigation.no-wrap{--navigation-layout-wrap:nowrap}.wp-block-navigation.items-justified-center{--navigation-layout-justification-setting:center;--navigation-layout-justify:center}.wp-block-navigation.items-justified-center.is-vertical{--navigation-layout-align:center}.wp-block-navigation.items-justified-right{--navigation-layout-justification-setting:flex-end;--navigation-layout-justify:flex-end}.wp-block-navigation.items-justified-right.is-vertical{--navigation-layout-align:flex-end}.wp-block-navigation.items-justified-space-between{--navigation-layout-justification-setting:space-between;--navigation-layout-justify:space-between}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{align-items:normal;background-color:inherit;color:inherit;display:flex;flex-direction:column;height:0;left:-1px;opacity:0;overflow:hidden;position:absolute;top:100%;visibility:hidden;width:0;z-index:2}@media not (prefers-reduced-motion){.wp-block-navigation .has-child .wp-block-navigation__submenu-container{transition:opacity .1s linear}}.wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content{display:flex;flex-grow:1}.wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content .wp-block-navigation__submenu-icon{margin-left:auto;margin-right:0}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content{margin:0}@media (min-width:782px){.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:100%;top:-1px}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{background:#0000;content:"";display:block;height:100%;position:absolute;right:100%;width:.5em}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon{margin-right:.25em}.wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon svg{transform:rotate(-90deg)}}.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true]~.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):hover>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):not(.open-on-hover-click):focus-within>.wp-block-navigation__submenu-container{height:auto;min-width:200px;opacity:1;overflow:visible;visibility:visible;width:auto}.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container{left:0;top:100%}@media (min-width:782px){.wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:100%;top:0}}.wp-block-navigation-submenu{display:flex;position:relative}.wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{stroke:currentColor}button.wp-block-navigation-item__content{background-color:initial;border:none;color:currentColor;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-align:left;text-transform:inherit}.wp-block-navigation-submenu__toggle{cursor:pointer}.wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle{padding-left:0;padding-right:.85em}.wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle+.wp-block-navigation__submenu-icon{margin-left:-.6em;pointer-events:none}.wp-block-navigation-item.open-on-click button.wp-block-navigation-item__content:not(.wp-block-navigation-submenu__toggle){padding:0}.wp-block-navigation .wp-block-page-list,.wp-block-navigation__container,.wp-block-navigation__responsive-close,.wp-block-navigation__responsive-container,.wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-dialog{gap:inherit}:where(.wp-block-navigation.has-background .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation.has-background .wp-block-navigation-submenu a:not(.wp-element-button)){padding:.5em 1em}:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu button.wp-block-navigation-item__content),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-pages-list__item button.wp-block-navigation-item__content){padding:.5em 1em}.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container{left:auto;right:0}.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:-1px;right:-1px}@media (min-width:782px){.wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:auto;right:100%}}.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container{background-color:#fff;border:1px solid #00000026}.wp-block-navigation.has-background .wp-block-navigation__submenu-container{background-color:inherit}.wp-block-navigation:not(.has-text-color) .wp-block-navigation__submenu-container{color:#000}.wp-block-navigation__container{align-items:var(--navigation-layout-align,initial);display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial);list-style:none;margin:0;padding-left:0}.wp-block-navigation__container .is-responsive{display:none}.wp-block-navigation__container:only-child,.wp-block-page-list:only-child{flex-grow:1}@keyframes overlay-menu__fade-in-animation{0%{opacity:0;transform:translateY(.5em)}to{opacity:1;transform:translateY(0)}}.wp-block-navigation__responsive-container{bottom:0;display:none;left:0;position:fixed;right:0;top:0}.wp-block-navigation__responsive-container :where(.wp-block-navigation-item a){color:inherit}.wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content{align-items:var(--navigation-layout-align,initial);display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial)}.wp-block-navigation__responsive-container:not(.is-menu-open.is-menu-open){background-color:inherit!important;color:inherit!important}.wp-block-navigation__responsive-container.is-menu-open{background-color:inherit;display:flex;flex-direction:column;overflow:auto;padding:clamp(1rem,var(--wp--style--root--padding-top),20rem) clamp(1rem,var(--wp--style--root--padding-right),20rem) clamp(1rem,var(--wp--style--root--padding-bottom),20rem) clamp(1rem,var(--wp--style--root--padding-left),20rem);z-index:100000}@media not (prefers-reduced-motion){.wp-block-navigation__responsive-container.is-menu-open{animation:overlay-menu__fade-in-animation .1s ease-out;animation-fill-mode:forwards}}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content{align-items:var(--navigation-layout-justification-setting,inherit);display:flex;flex-direction:column;flex-wrap:nowrap;overflow:visible;padding-top:calc(2rem + 24px)}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{justify-content:flex-start}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon{display:none}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container{border:none;height:auto;min-width:200px;opacity:1;overflow:initial;padding-left:2rem;padding-right:2rem;position:static;visibility:visible;width:auto}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{gap:inherit}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{padding-top:var(--wp--style--block-gap,2em)}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content{padding:0}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{align-items:var(--navigation-layout-justification-setting,initial);display:flex;flex-direction:column}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list{background:#0000!important;color:inherit!important}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{left:auto;right:auto}@media (min-width:600px){.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){background-color:inherit;display:block;position:relative;width:100%;z-index:auto}.wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close{display:none}.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{left:0}}.wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open{background-color:#fff}.wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open{color:#000}.wp-block-navigation__toggle_button_label{font-size:1rem;font-weight:700}.wp-block-navigation__responsive-container-close,.wp-block-navigation__responsive-container-open{background:#0000;border:none;color:currentColor;cursor:pointer;margin:0;padding:0;text-transform:inherit;vertical-align:middle}.wp-block-navigation__responsive-container-close svg,.wp-block-navigation__responsive-container-open svg{fill:currentColor;display:block;height:24px;pointer-events:none;width:24px}.wp-block-navigation__responsive-container-open{display:flex}.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{font-family:inherit;font-size:inherit;font-weight:inherit}@media (min-width:600px){.wp-block-navigation__responsive-container-open:not(.always-shown){display:none}}.wp-block-navigation__responsive-container-close{position:absolute;right:0;top:0;z-index:2}.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close{font-family:inherit;font-size:inherit;font-weight:inherit}.wp-block-navigation__responsive-close{width:100%}.has-modal-open .wp-block-navigation__responsive-close{margin-left:auto;margin-right:auto;max-width:var(--wp--style--global--wide-size,100%)}.wp-block-navigation__responsive-close:focus{outline:none}.is-menu-open .wp-block-navigation__responsive-close,.is-menu-open .wp-block-navigation__responsive-container-content,.is-menu-open .wp-block-navigation__responsive-dialog{box-sizing:border-box}.wp-block-navigation__responsive-dialog{position:relative}.has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{margin-top:46px}@media (min-width:782px){.has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{margin-top:32px}}html.has-modal-open{overflow:hidden}.wp-block-navigation .wp-block-navigation-item__label{overflow-wrap:break-word}.wp-block-navigation .wp-block-navigation-item__description{display:none}.link-ui-tools{border-top:1px solid #f0f0f0;padding:8px}.link-ui-block-inserter{padding-top:8px}.link-ui-block-inserter__back{margin-left:8px;text-transform:uppercase}.wp-block-navigation .wp-block-page-list{align-items:var(--navigation-layout-align,initial);background-color:inherit;display:flex;flex-direction:var(--navigation-layout-direction,initial);flex-wrap:var(--navigation-layout-wrap,wrap);justify-content:var(--navigation-layout-justify,initial)}.wp-block-navigation .wp-block-navigation-item{background-color:inherit}.wp-block-page-list{box-sizing:border-box}.is-small-text{font-size:.875em}.is-regular-text{font-size:1em}.is-large-text{font-size:2.25em}.is-larger-text{font-size:3em}.has-drop-cap:not(:focus):first-letter{float:left;font-size:8.4em;font-style:normal;font-weight:100;line-height:.68;margin:.05em .1em 0 0;text-transform:uppercase}body.rtl .has-drop-cap:not(:focus):first-letter{float:none;margin-left:.1em}p.has-drop-cap.has-background{overflow:hidden}:root :where(p.has-background){padding:1.25em 2.375em}:where(p.has-text-color:not(.has-link-color)) a{color:inherit}p.has-text-align-left[style*="writing-mode:vertical-lr"],p.has-text-align-right[style*="writing-mode:vertical-rl"]{rotate:180deg}.wp-block-post-author{box-sizing:border-box;display:flex;flex-wrap:wrap}.wp-block-post-author__byline{font-size:.5em;margin-bottom:0;margin-top:0;width:100%}.wp-block-post-author__avatar{margin-right:1em}.wp-block-post-author__bio{font-size:.7em;margin-bottom:.7em}.wp-block-post-author__content{flex-basis:0;flex-grow:1}.wp-block-post-author__name{margin:0}.wp-block-post-author-biography{box-sizing:border-box}:where(.wp-block-post-comments-form) input:not([type=submit]),:where(.wp-block-post-comments-form) textarea{border:1px solid #949494;font-family:inherit;font-size:1em}:where(.wp-block-post-comments-form) input:where(:not([type=submit]):not([type=checkbox])),:where(.wp-block-post-comments-form) textarea{padding:calc(.667em + 2px)}.wp-block-post-comments-form{box-sizing:border-box}.wp-block-post-comments-form[style*=font-weight] :where(.comment-reply-title){font-weight:inherit}.wp-block-post-comments-form[style*=font-family] :where(.comment-reply-title){font-family:inherit}.wp-block-post-comments-form[class*=-font-size] :where(.comment-reply-title),.wp-block-post-comments-form[style*=font-size] :where(.comment-reply-title){font-size:inherit}.wp-block-post-comments-form[style*=line-height] :where(.comment-reply-title){line-height:inherit}.wp-block-post-comments-form[style*=font-style] :where(.comment-reply-title){font-style:inherit}.wp-block-post-comments-form[style*=letter-spacing] :where(.comment-reply-title){letter-spacing:inherit}.wp-block-post-comments-form :where(input[type=submit]){box-shadow:none;cursor:pointer;display:inline-block;overflow-wrap:break-word;text-align:center}.wp-block-post-comments-form .comment-form input:not([type=submit]):not([type=checkbox]):not([type=hidden]),.wp-block-post-comments-form .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-post-comments-form .comment-form-author label,.wp-block-post-comments-form .comment-form-email label,.wp-block-post-comments-form .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-post-comments-form .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-post-comments-form .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-post-comments-form .comment-reply-title{margin-bottom:0}.wp-block-post-comments-form .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-left:.5em}.wp-block-post-comments-count{box-sizing:border-box}.wp-block-post-content{display:flow-root}.wp-block-post-comments-link,.wp-block-post-date{box-sizing:border-box}:where(.wp-block-post-excerpt){box-sizing:border-box;margin-bottom:var(--wp--style--block-gap);margin-top:var(--wp--style--block-gap)}.wp-block-post-excerpt__excerpt{margin-bottom:0;margin-top:0}.wp-block-post-excerpt__more-text{margin-bottom:0;margin-top:var(--wp--style--block-gap)}.wp-block-post-excerpt__more-link{display:inline-block}.wp-block-post-featured-image{margin-left:0;margin-right:0}.wp-block-post-featured-image a{display:block;height:100%}.wp-block-post-featured-image :where(img){box-sizing:border-box;height:auto;max-width:100%;vertical-align:bottom;width:100%}.wp-block-post-featured-image.alignfull img,.wp-block-post-featured-image.alignwide img{width:100%}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim{background-color:#000;inset:0;position:absolute}.wp-block-post-featured-image{position:relative}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-gradient{background-color:initial}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-0{opacity:0}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-10{opacity:.1}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-20{opacity:.2}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-30{opacity:.3}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-40{opacity:.4}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-50{opacity:.5}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-60{opacity:.6}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-70{opacity:.7}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-80{opacity:.8}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-90{opacity:.9}.wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-100{opacity:1}.wp-block-post-featured-image:where(.alignleft,.alignright){width:100%}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous{display:inline-block;margin-right:1ch}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next{display:inline-block;margin-left:1ch}.wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-post-navigation-link.has-text-align-left[style*="writing-mode: vertical-lr"],.wp-block-post-navigation-link.has-text-align-right[style*="writing-mode: vertical-rl"]{rotate:180deg}.wp-block-post-terms{box-sizing:border-box}.wp-block-post-terms .wp-block-post-terms__separator{white-space:pre-wrap}.wp-block-post-time-to-read,.wp-block-post-title{box-sizing:border-box}.wp-block-post-title{word-break:break-word}.wp-block-post-title :where(a){display:inline-block;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit}.wp-block-post-author-name{box-sizing:border-box}.wp-block-preformatted{box-sizing:border-box;white-space:pre-wrap}:where(.wp-block-preformatted.has-background){padding:1.25em 2.375em}.wp-block-pullquote{box-sizing:border-box;margin:0 0 1em;overflow-wrap:break-word;padding:4em 0;text-align:center}.wp-block-pullquote blockquote,.wp-block-pullquote cite,.wp-block-pullquote p{color:inherit}.wp-block-pullquote blockquote{margin:0}.wp-block-pullquote p{margin-top:0}.wp-block-pullquote p:last-child{margin-bottom:0}.wp-block-pullquote.alignleft,.wp-block-pullquote.alignright{max-width:420px}.wp-block-pullquote cite,.wp-block-pullquote footer{position:relative}.wp-block-pullquote .has-text-color a{color:inherit}.wp-block-pullquote.has-text-align-left blockquote{text-align:left}.wp-block-pullquote.has-text-align-right blockquote{text-align:right}.wp-block-pullquote.has-text-align-center blockquote{text-align:center}.wp-block-pullquote.is-style-solid-color{border:none}.wp-block-pullquote.is-style-solid-color blockquote{margin-left:auto;margin-right:auto;max-width:60%}.wp-block-pullquote.is-style-solid-color blockquote p{font-size:2em;margin-bottom:0;margin-top:0}.wp-block-pullquote.is-style-solid-color blockquote cite{font-style:normal;text-transform:none}.wp-block-pullquote cite{color:inherit;display:block}.wp-block-post-template{box-sizing:border-box;list-style:none;margin-bottom:0;margin-top:0;max-width:100%;padding:0}.wp-block-post-template.is-flex-container{display:flex;flex-direction:row;flex-wrap:wrap;gap:1.25em}.wp-block-post-template.is-flex-container>li{margin:0;width:100%}@media (min-width:600px){.wp-block-post-template.is-flex-container.is-flex-container.columns-2>li{width:calc(50% - .625em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-3>li{width:calc(33.33333% - .83333em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-4>li{width:calc(25% - .9375em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-5>li{width:calc(20% - 1em)}.wp-block-post-template.is-flex-container.is-flex-container.columns-6>li{width:calc(16.66667% - 1.04167em)}}@media (max-width:600px){.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid{grid-template-columns:1fr}}.wp-block-post-template-is-layout-constrained>li>.alignright,.wp-block-post-template-is-layout-flow>li>.alignright{float:right;margin-inline-end:0;margin-inline-start:2em}.wp-block-post-template-is-layout-constrained>li>.alignleft,.wp-block-post-template-is-layout-flow>li>.alignleft{float:left;margin-inline-end:2em;margin-inline-start:0}.wp-block-post-template-is-layout-constrained>li>.aligncenter,.wp-block-post-template-is-layout-flow>li>.aligncenter{margin-inline-end:auto;margin-inline-start:auto}.wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-next:last-of-type{margin-inline-start:auto}.wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-previous:first-child{margin-inline-end:auto}.wp-block-query-pagination .wp-block-query-pagination-previous-arrow{display:inline-block;margin-right:1ch}.wp-block-query-pagination .wp-block-query-pagination-previous-arrow:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-query-pagination .wp-block-query-pagination-next-arrow{display:inline-block;margin-left:1ch}.wp-block-query-pagination .wp-block-query-pagination-next-arrow:not(.is-arrow-chevron){transform:scaleX(1)}.wp-block-query-pagination.aligncenter{justify-content:center}.wp-block-query-title,.wp-block-query-total,.wp-block-quote{box-sizing:border-box}.wp-block-quote{overflow-wrap:break-word}.wp-block-quote.is-large:where(:not(.is-style-plain)),.wp-block-quote.is-style-large:where(:not(.is-style-plain)){margin-bottom:1em;padding:0 1em}.wp-block-quote.is-large:where(:not(.is-style-plain)) p,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) p{font-size:1.5em;font-style:italic;line-height:1.6}.wp-block-quote.is-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-large:where(:not(.is-style-plain)) footer,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) footer{font-size:1.125em;text-align:right}.wp-block-quote>cite{display:block}.wp-block-read-more{display:block;width:fit-content}.wp-block-read-more:where(:not([style*=text-decoration])){text-decoration:none}.wp-block-read-more:where(:not([style*=text-decoration])):active,.wp-block-read-more:where(:not([style*=text-decoration])):focus{text-decoration:none}ul.wp-block-rss.alignleft{margin-right:2em}ul.wp-block-rss.alignright{margin-left:2em}ul.wp-block-rss.is-grid{display:flex;flex-wrap:wrap;padding:0}ul.wp-block-rss.is-grid li{margin:0 1em 1em 0;width:100%}@media (min-width:600px){ul.wp-block-rss.columns-2 li{width:calc(50% - 1em)}ul.wp-block-rss.columns-3 li{width:calc(33.33333% - 1em)}ul.wp-block-rss.columns-4 li{width:calc(25% - 1em)}ul.wp-block-rss.columns-5 li{width:calc(20% - 1em)}ul.wp-block-rss.columns-6 li{width:calc(16.66667% - 1em)}}.wp-block-rss__item-author,.wp-block-rss__item-publish-date{display:block;font-size:.8125em}.wp-block-rss{box-sizing:border-box;list-style:none;padding:0}.wp-block-search__button{margin-left:10px;word-break:normal}.wp-block-search__button.has-icon{line-height:0}.wp-block-search__button svg{height:1.25em;min-height:24px;min-width:24px;width:1.25em;fill:currentColor;vertical-align:text-bottom}:where(.wp-block-search__button){border:1px solid #ccc;padding:6px 10px}.wp-block-search__inside-wrapper{display:flex;flex:auto;flex-wrap:nowrap;max-width:100%}.wp-block-search__label{width:100%}.wp-block-search__input{appearance:none;border:1px solid #949494;flex-grow:1;margin-left:0;margin-right:0;min-width:3rem;padding:8px;text-decoration:unset!important}.wp-block-search.wp-block-search__button-only .wp-block-search__button{box-sizing:border-box;display:flex;flex-shrink:0;justify-content:center;margin-left:0;max-width:100%}.wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{min-width:0!important;transition-property:width}.wp-block-search.wp-block-search__button-only .wp-block-search__input{flex-basis:100%;transition-duration:.3s}.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden,.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__inside-wrapper{overflow:hidden}.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__input{border-left-width:0!important;border-right-width:0!important;flex-basis:0;flex-grow:0;margin:0;min-width:0!important;padding-left:0!important;padding-right:0!important;width:0!important}:where(.wp-block-search__input){font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-transform:inherit}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper){border:1px solid #949494;box-sizing:border-box;padding:4px}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input{border:none;border-radius:0;padding:0 4px}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input:focus{outline:none}:where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) :where(.wp-block-search__button){padding:4px 8px}.wp-block-search.aligncenter .wp-block-search__inside-wrapper{margin:auto}.wp-block[data-align=right] .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{float:right}.wp-block-separator{border:none;border-top:2px solid}:root :where(.wp-block-separator.is-style-dots){height:auto;line-height:1;text-align:center}:root :where(.wp-block-separator.is-style-dots):before{color:currentColor;content:"···";font-family:serif;font-size:1.5em;letter-spacing:2em;padding-left:2em}.wp-block-separator.is-style-dots{background:none!important;border:none!important}.wp-block-site-logo{box-sizing:border-box;line-height:0}.wp-block-site-logo a{display:inline-block;line-height:0}.wp-block-site-logo.is-default-size img{height:auto;width:120px}.wp-block-site-logo img{height:auto;max-width:100%}.wp-block-site-logo a,.wp-block-site-logo img{border-radius:inherit}.wp-block-site-logo.aligncenter{margin-left:auto;margin-right:auto;text-align:center}:root :where(.wp-block-site-logo.is-style-rounded){border-radius:9999px}.wp-block-site-tagline,.wp-block-site-title{box-sizing:border-box}.wp-block-site-title :where(a){color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit}.wp-block-social-links{background:none;box-sizing:border-box;margin-left:0;padding-left:0;padding-right:0;text-indent:0}.wp-block-social-links .wp-social-link a,.wp-block-social-links .wp-social-link a:hover{border-bottom:0;box-shadow:none;text-decoration:none}.wp-block-social-links .wp-social-link svg{height:1em;width:1em}.wp-block-social-links .wp-social-link span:not(.screen-reader-text){font-size:.65em;margin-left:.5em;margin-right:.5em}.wp-block-social-links.has-small-icon-size{font-size:16px}.wp-block-social-links,.wp-block-social-links.has-normal-icon-size{font-size:24px}.wp-block-social-links.has-large-icon-size{font-size:36px}.wp-block-social-links.has-huge-icon-size{font-size:48px}.wp-block-social-links.aligncenter{display:flex;justify-content:center}.wp-block-social-links.alignright{justify-content:flex-end}.wp-block-social-link{border-radius:9999px;display:block;height:auto}@media not (prefers-reduced-motion){.wp-block-social-link{transition:transform .1s ease}}.wp-block-social-link a{align-items:center;display:flex;line-height:0}.wp-block-social-link:hover{transform:scale(1.1)}.wp-block-social-links .wp-block-social-link.wp-social-link{display:inline-block;margin:0;padding:0}.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor svg,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:active,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:hover,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:visited{color:currentColor;fill:currentColor}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link{background-color:#f0f0f0;color:#444}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-amazon{background-color:#f90;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bandcamp{background-color:#1ea0c3;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-behance{background-color:#0757fe;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bluesky{background-color:#0a7aff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-codepen{background-color:#1e1f26;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-deviantart{background-color:#02e49b;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-discord{background-color:#5865f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dribbble{background-color:#e94c89;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dropbox{background-color:#4280ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-etsy{background-color:#f45800;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-facebook{background-color:#0866ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-fivehundredpx{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-flickr{background-color:#0461dd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-foursquare{background-color:#e65678;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-github{background-color:#24292d;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-goodreads{background-color:#eceadd;color:#382110}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-google{background-color:#ea4434;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-gravatar{background-color:#1d4fc4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-instagram{background-color:#f00075;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-lastfm{background-color:#e21b24;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-linkedin{background-color:#0d66c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-mastodon{background-color:#3288d4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-medium{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-meetup{background-color:#f6405f;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-patreon{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pinterest{background-color:#e60122;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pocket{background-color:#ef4155;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-reddit{background-color:#ff4500;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-skype{background-color:#0478d7;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-snapchat{background-color:#fefc00;color:#fff;stroke:#000}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-soundcloud{background-color:#ff5600;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-spotify{background-color:#1bd760;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-telegram{background-color:#2aabee;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-threads{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tiktok{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tumblr{background-color:#011835;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitch{background-color:#6440a4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitter{background-color:#1da1f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vimeo{background-color:#1eb7ea;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vk{background-color:#4680c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-wordpress{background-color:#3499cd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-whatsapp{background-color:#25d366;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-x{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-yelp{background-color:#d32422;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-youtube{background-color:red;color:#fff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link{background:none}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link svg{height:1.25em;width:1.25em}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-amazon{color:#f90}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bandcamp{color:#1ea0c3}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-behance{color:#0757fe}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bluesky{color:#0a7aff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-codepen{color:#1e1f26}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-deviantart{color:#02e49b}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-discord{color:#5865f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dribbble{color:#e94c89}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dropbox{color:#4280ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-etsy{color:#f45800}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-facebook{color:#0866ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-fivehundredpx{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-flickr{color:#0461dd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-foursquare{color:#e65678}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-github{color:#24292d}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-goodreads{color:#382110}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-google{color:#ea4434}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-gravatar{color:#1d4fc4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-instagram{color:#f00075}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-lastfm{color:#e21b24}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-linkedin{color:#0d66c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-mastodon{color:#3288d4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-medium{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-meetup{color:#f6405f}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-patreon{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pinterest{color:#e60122}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pocket{color:#ef4155}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-reddit{color:#ff4500}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-skype{color:#0478d7}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-snapchat{color:#fff;stroke:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-soundcloud{color:#ff5600}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-spotify{color:#1bd760}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-telegram{color:#2aabee}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-threads{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tiktok{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tumblr{color:#011835}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitch{color:#6440a4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitter{color:#1da1f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vimeo{color:#1eb7ea}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vk{color:#4680c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-whatsapp{color:#25d366}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-wordpress{color:#3499cd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-x{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-yelp{color:#d32422}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-youtube{color:red}.wp-block-social-links.is-style-pill-shape .wp-social-link{width:auto}:root :where(.wp-block-social-links .wp-social-link a){padding:.25em}:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a){padding:0}:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a){padding-left:.6666666667em;padding-right:.6666666667em}.wp-block-social-links:not(.has-icon-color):not(.has-icon-background-color) .wp-social-link-snapchat .wp-block-social-link-label{color:#000}.wp-block-spacer{clear:both}.wp-block-tag-cloud{box-sizing:border-box}.wp-block-tag-cloud.aligncenter{justify-content:center;text-align:center}.wp-block-tag-cloud.alignfull{padding-left:1em;padding-right:1em}.wp-block-tag-cloud a{display:inline-block;margin-right:5px}.wp-block-tag-cloud span{display:inline-block;margin-left:5px;text-decoration:none}:root :where(.wp-block-tag-cloud.is-style-outline){display:flex;flex-wrap:wrap;gap:1ch}:root :where(.wp-block-tag-cloud.is-style-outline a){border:1px solid;font-size:unset!important;margin-right:0;padding:1ch 2ch;text-decoration:none!important}.wp-block-table{overflow-x:auto}.wp-block-table table{border-collapse:collapse;width:100%}.wp-block-table thead{border-bottom:3px solid}.wp-block-table tfoot{border-top:3px solid}.wp-block-table td,.wp-block-table th{border:1px solid;padding:.5em}.wp-block-table .has-fixed-layout{table-layout:fixed;width:100%}.wp-block-table .has-fixed-layout td,.wp-block-table .has-fixed-layout th{word-break:break-word}.wp-block-table.aligncenter,.wp-block-table.alignleft,.wp-block-table.alignright{display:table;width:auto}.wp-block-table.aligncenter td,.wp-block-table.aligncenter th,.wp-block-table.alignleft td,.wp-block-table.alignleft th,.wp-block-table.alignright td,.wp-block-table.alignright th{word-break:break-word}.wp-block-table .has-subtle-light-gray-background-color{background-color:#f3f4f5}.wp-block-table .has-subtle-pale-green-background-color{background-color:#e9fbe5}.wp-block-table .has-subtle-pale-blue-background-color{background-color:#e7f5fe}.wp-block-table .has-subtle-pale-pink-background-color{background-color:#fcf0ef}.wp-block-table.is-style-stripes{background-color:initial;border-bottom:1px solid #f0f0f0;border-collapse:inherit;border-spacing:0}.wp-block-table.is-style-stripes tbody tr:nth-child(odd){background-color:#f0f0f0}.wp-block-table.is-style-stripes.has-subtle-light-gray-background-color tbody tr:nth-child(odd){background-color:#f3f4f5}.wp-block-table.is-style-stripes.has-subtle-pale-green-background-color tbody tr:nth-child(odd){background-color:#e9fbe5}.wp-block-table.is-style-stripes.has-subtle-pale-blue-background-color tbody tr:nth-child(odd){background-color:#e7f5fe}.wp-block-table.is-style-stripes.has-subtle-pale-pink-background-color tbody tr:nth-child(odd){background-color:#fcf0ef}.wp-block-table.is-style-stripes td,.wp-block-table.is-style-stripes th{border-color:#0000}.wp-block-table .has-border-color td,.wp-block-table .has-border-color th,.wp-block-table .has-border-color tr,.wp-block-table .has-border-color>*{border-color:inherit}.wp-block-table table[style*=border-top-color] tr:first-child,.wp-block-table table[style*=border-top-color] tr:first-child td,.wp-block-table table[style*=border-top-color] tr:first-child th,.wp-block-table table[style*=border-top-color]>*,.wp-block-table table[style*=border-top-color]>* td,.wp-block-table table[style*=border-top-color]>* th{border-top-color:inherit}.wp-block-table table[style*=border-top-color] tr:not(:first-child){border-top-color:initial}.wp-block-table table[style*=border-right-color] td:last-child,.wp-block-table table[style*=border-right-color] th,.wp-block-table table[style*=border-right-color] tr,.wp-block-table table[style*=border-right-color]>*{border-right-color:inherit}.wp-block-table table[style*=border-bottom-color] tr:last-child,.wp-block-table table[style*=border-bottom-color] tr:last-child td,.wp-block-table table[style*=border-bottom-color] tr:last-child th,.wp-block-table table[style*=border-bottom-color]>*,.wp-block-table table[style*=border-bottom-color]>* td,.wp-block-table table[style*=border-bottom-color]>* th{border-bottom-color:inherit}.wp-block-table table[style*=border-bottom-color] tr:not(:last-child){border-bottom-color:initial}.wp-block-table table[style*=border-left-color] td:first-child,.wp-block-table table[style*=border-left-color] th,.wp-block-table table[style*=border-left-color] tr,.wp-block-table table[style*=border-left-color]>*{border-left-color:inherit}.wp-block-table table[style*=border-style] td,.wp-block-table table[style*=border-style] th,.wp-block-table table[style*=border-style] tr,.wp-block-table table[style*=border-style]>*{border-style:inherit}.wp-block-table table[style*=border-width] td,.wp-block-table table[style*=border-width] th,.wp-block-table table[style*=border-width] tr,.wp-block-table table[style*=border-width]>*{border-style:inherit;border-width:inherit}:root :where(.wp-block-table-of-contents){box-sizing:border-box}:where(.wp-block-term-description){box-sizing:border-box;margin-bottom:var(--wp--style--block-gap);margin-top:var(--wp--style--block-gap)}.wp-block-term-description p{margin-bottom:0;margin-top:0}.wp-block-text-columns,.wp-block-text-columns.aligncenter{display:flex}.wp-block-text-columns .wp-block-column{margin:0 1em;padding:0}.wp-block-text-columns .wp-block-column:first-child{margin-left:0}.wp-block-text-columns .wp-block-column:last-child{margin-right:0}.wp-block-text-columns.columns-2 .wp-block-column{width:50%}.wp-block-text-columns.columns-3 .wp-block-column{width:33.3333333333%}.wp-block-text-columns.columns-4 .wp-block-column{width:25%}pre.wp-block-verse{overflow:auto;white-space:pre-wrap}:where(pre.wp-block-verse){font-family:inherit}.wp-block-video{box-sizing:border-box}.wp-block-video video{vertical-align:middle;width:100%}@supports (position:sticky){.wp-block-video [poster]{object-fit:cover}}.wp-block-video.aligncenter{text-align:center}.wp-block-video :where(figcaption){margin-bottom:1em;margin-top:.5em}.editor-styles-wrapper,.entry-content{counter-reset:footnotes}a[data-fn].fn{counter-increment:footnotes;display:inline-flex;font-size:smaller;text-decoration:none;text-indent:-9999999px;vertical-align:super}a[data-fn].fn:after{content:"[" counter(footnotes) "]";float:left;text-indent:0}.wp-element-button{cursor:pointer}:root{--wp--preset--font-size--normal:16px;--wp--preset--font-size--huge:42px}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}.has-text-align-center{text-align:center}.has-text-align-left{text-align:left}.has-text-align-right{text-align:right}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-right-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-left-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-right-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-left-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}.wp-element-button{cursor:pointer}html :where(.editor-styles-wrapper){background:#fff;color:initial;font-family:serif;font-size:medium;line-height:normal}:where(.editor-styles-wrapper) .wp-align-wrapper{max-width:840px}:where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-full,:where(.editor-styles-wrapper) .wp-align-wrapper>.wp-block{max-width:none}:where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-wide{max-width:840px}:where(.editor-styles-wrapper) a{transition:none}:where(.editor-styles-wrapper) code,:where(.editor-styles-wrapper) kbd{background:inherit;font-family:monospace;font-size:inherit;margin:0;padding:0}:where(.editor-styles-wrapper) p{font-size:revert;line-height:revert;margin:revert}:where(.editor-styles-wrapper) ol,:where(.editor-styles-wrapper) ul{box-sizing:border-box;list-style-type:revert;margin:revert;padding:revert}:where(.editor-styles-wrapper) ol ol,:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ol,:where(.editor-styles-wrapper) ul ul{margin:revert}:where(.editor-styles-wrapper) ol li,:where(.editor-styles-wrapper) ul li{margin:revert}:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ul{list-style-type:revert}:where(.editor-styles-wrapper) h1,:where(.editor-styles-wrapper) h2,:where(.editor-styles-wrapper) h3,:where(.editor-styles-wrapper) h4,:where(.editor-styles-wrapper) h5,:where(.editor-styles-wrapper) h6{color:revert;font-size:revert;font-weight:revert;line-height:revert;margin:revert}:where(.editor-styles-wrapper) select{-webkit-appearance:revert;background:revert;border:revert;border-radius:revert;box-shadow:revert;color:revert;cursor:revert;font-family:system-ui;font-size:revert;font-weight:revert;line-height:revert;margin:revert;max-width:revert;min-height:revert;outline:revert;padding:revert;text-shadow:revert;transform:revert;vertical-align:revert}:where(.editor-styles-wrapper) select:disabled,:where(.editor-styles-wrapper) select:focus{background-color:revert;background-image:revert;border-color:revert;box-shadow:revert;color:revert;cursor:revert;text-shadow:revert;transform:revert}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-element-button{cursor:pointer}:root{--wp--preset--font-size--normal:16px;--wp--preset--font-size--huge:42px}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}.has-text-align-center{text-align:center}.has-text-align-left{text-align:left}.has-text-align-right{text-align:right}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-right-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-left-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-right-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-left-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}ul.wp-block-archives{ padding-left:2.5em; } .wp-block-archives .wp-block-archives{ border:0; margin:0; } .wp-block-audio{ margin-left:0; margin-right:0; position:relative; } .wp-block-audio.is-transient audio{ opacity:.3; } .wp-block-audio .components-spinner{ left:50%; margin-left:-9px; margin-top:-9px; position:absolute; top:50%; } .wp-block-avatar__image img{ width:100%; } .wp-block-avatar.aligncenter .components-resizable-box__container{ margin:0 auto; } .wp-block[data-align=center]>.wp-block-button{ margin-left:auto; margin-right:auto; text-align:center; } .wp-block[data-align=right]>.wp-block-button{ text-align:right; } .wp-block-button{ cursor:text; position:relative; } .wp-block-button:focus{ box-shadow:0 0 0 1px #fff, 0 0 0 3px var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:-2px; } .wp-block-button[data-rich-text-placeholder]:after{ opacity:.8; } div[data-type="core/button"]{ display:table; } .wp-block-buttons>.wp-block,.wp-block-buttons>.wp-block-button.wp-block-button.wp-block-button.wp-block-button.wp-block-button{ margin:0; } .wp-block-buttons>.block-list-appender{ align-items:center; display:inline-flex; } .wp-block-buttons.is-vertical>.block-list-appender .block-list-appender__toggle{ justify-content:flex-start; } .wp-block-buttons>.wp-block-button:focus{ box-shadow:none; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center]{ margin-left:auto; margin-right:auto; margin-top:0; width:100%; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center] .wp-block-button{ margin-bottom:0; } .wp-block[data-align=center]>.wp-block-buttons{ align-items:center; justify-content:center; } .wp-block[data-align=right]>.wp-block-buttons{ justify-content:flex-end; } .wp-block-categories ul{ padding-left:2.5em; } .wp-block-categories ul ul{ margin-top:6px; } [data-align=center] .wp-block-categories{ text-align:center; } .wp-block-categories__indentation{ padding-left:16px; } .wp-block-code code{ background:none; } .wp-block-columns :where(.wp-block){ margin-left:0; margin-right:0; max-width:none; } html :where(.wp-block-column){ margin-bottom:0; margin-top:0; } .wp-block-comments__legacy-placeholder,.wp-block-post-comments{ box-sizing:border-box; } .wp-block-comments__legacy-placeholder .alignleft,.wp-block-post-comments .alignleft{ float:left; } .wp-block-comments__legacy-placeholder .alignright,.wp-block-post-comments .alignright{ float:right; } .wp-block-comments__legacy-placeholder .navigation:after,.wp-block-post-comments .navigation:after{ clear:both; content:""; display:table; } .wp-block-comments__legacy-placeholder .commentlist,.wp-block-post-comments .commentlist{ clear:both; list-style:none; margin:0; padding:0; } .wp-block-comments__legacy-placeholder .commentlist .comment,.wp-block-post-comments .commentlist .comment{ min-height:2.25em; padding-left:3.25em; } .wp-block-comments__legacy-placeholder .commentlist .comment p,.wp-block-post-comments .commentlist .comment p{ font-size:1em; line-height:1.8; margin:1em 0; } .wp-block-comments__legacy-placeholder .commentlist .children,.wp-block-post-comments .commentlist .children{ list-style:none; margin:0; padding:0; } .wp-block-comments__legacy-placeholder .comment-author,.wp-block-post-comments .comment-author{ line-height:1.5; } .wp-block-comments__legacy-placeholder .comment-author .avatar,.wp-block-post-comments .comment-author .avatar{ border-radius:1.5em; display:block; float:left; height:2.5em; margin-right:.75em; margin-top:.5em; width:2.5em; } .wp-block-comments__legacy-placeholder .comment-author cite,.wp-block-post-comments .comment-author cite{ font-style:normal; } .wp-block-comments__legacy-placeholder .comment-meta,.wp-block-post-comments .comment-meta{ font-size:.875em; line-height:1.5; } .wp-block-comments__legacy-placeholder .comment-meta b,.wp-block-post-comments .comment-meta b{ font-weight:400; } .wp-block-comments__legacy-placeholder .comment-meta .comment-awaiting-moderation,.wp-block-post-comments .comment-meta .comment-awaiting-moderation{ display:block; margin-bottom:1em; margin-top:1em; } .wp-block-comments__legacy-placeholder .comment-body .commentmetadata,.wp-block-post-comments .comment-body .commentmetadata{ font-size:.875em; } .wp-block-comments__legacy-placeholder .comment-form-author label,.wp-block-comments__legacy-placeholder .comment-form-comment label,.wp-block-comments__legacy-placeholder .comment-form-email label,.wp-block-comments__legacy-placeholder .comment-form-url label,.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-comments__legacy-placeholder .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder .comment-form textarea,.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-comments__legacy-placeholder .comment-form-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-comments__legacy-placeholder .comment-form-cookies-consent #wp-comment-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-comments__legacy-placeholder .comment-reply-title,.wp-block-post-comments .comment-reply-title{ margin-bottom:0; } .wp-block-comments__legacy-placeholder .comment-reply-title :where(small),.wp-block-post-comments .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-left:.5em; } .wp-block-comments__legacy-placeholder .reply,.wp-block-post-comments .reply{ font-size:.875em; margin-bottom:1.4em; } .wp-block-comments__legacy-placeholder input:not([type=submit]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } .wp-block-comments__legacy-placeholder input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{ padding:calc(.667em + 2px); } :where(.wp-block-post-comments input[type=submit],.wp-block-comments__legacy-placeholder input[type=submit]){ border:none; } .wp-block-comments{ box-sizing:border-box; } .block-library-comments-toolbar__popover .components-popover__content{ min-width:230px; } .wp-block-comments__legacy-placeholder *{ pointer-events:none; } .wp-block-comment-author-avatar__placeholder{ border:1px dashed; height:100%; width:100%; stroke:currentColor; stroke-dasharray:3; } .wp-block[data-align=center]>.wp-block-comments-pagination{ justify-content:center; } :where(.editor-styles-wrapper) .wp-block-comments-pagination{ max-width:100%; } :where(.editor-styles-wrapper) .wp-block-comments-pagination.block-editor-block-list__layout{ margin:0; } .wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{ font-size:inherit; margin:.5em .5em .5em 0; } .wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{ margin-right:0; } .wp-block-comments-pagination-numbers a{ text-decoration:underline; } .wp-block-comments-pagination-numbers .page-numbers{ margin-right:2px; } .wp-block-comments-pagination-numbers .page-numbers:last-child{ margin-right:0; } .wp-block-comments-title.has-background{ padding:inherit; } .wp-block-cover.is-placeholder{ align-items:stretch; display:flex; min-height:240px; padding:0 !important; } .wp-block-cover.is-placeholder .components-placeholder.is-large{ justify-content:flex-start; z-index:1; } .wp-block-cover.is-placeholder:focus:after{ min-height:auto; } .wp-block-cover.components-placeholder h2{ color:inherit; } .wp-block-cover.is-transient{ position:relative; } .wp-block-cover.is-transient:before{ background-color:#fff; content:""; height:100%; opacity:.3; position:absolute; width:100%; z-index:1; } .wp-block-cover.is-transient .wp-block-cover__inner-container{ z-index:2; } .wp-block-cover .components-spinner{ left:50%; margin:0; position:absolute; top:50%; transform:translate(-50%, -50%); } .wp-block-cover .wp-block-cover__inner-container{ margin-left:0; margin-right:0; text-align:left; } .wp-block-cover .wp-block-cover__placeholder-background-options{ width:100%; } .wp-block-cover .wp-block-cover__image--placeholder-image{ bottom:0; left:0; position:absolute; right:0; top:0; } [data-align=left]>.wp-block-cover,[data-align=right]>.wp-block-cover{ max-width:420px; width:100%; } .block-library-cover__reset-button{ margin-left:auto; } .block-library-cover__resize-container{ bottom:0; left:0; min-height:50px; position:absolute !important; right:0; top:0; } .components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .block-library-cover__resize-container,.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .components-popover__content>div{ overflow:visible; pointer-events:none; } .block-editor-block-patterns-list__list-item .has-parallax.wp-block-cover{ background-attachment:scroll; } .color-block-support-panel__inner-wrapper>:not(.block-editor-tools-panel-color-gradient-settings__item){ margin-top:24px; } .wp-block-details summary div{ display:inline; } .wp-block-embed{ clear:both; margin-left:0; margin-right:0; } .wp-block-embed.is-loading{ display:flex; justify-content:center; } .wp-block-embed .wp-block-embed__placeholder-input{ flex:1 1 auto; } .wp-block-embed .components-placeholder__error{ word-break:break-word; } .wp-block-post-content .wp-block-embed__learn-more a{ color:var(--wp-admin-theme-color); } .block-library-embed__interactive-overlay{ bottom:0; left:0; opacity:0; position:absolute; right:0; top:0; } .wp-block[data-align=left]>.wp-block-embed,.wp-block[data-align=right]>.wp-block-embed{ max-width:360px; width:100%; } .wp-block[data-align=left]>.wp-block-embed .wp-block-embed__wrapper,.wp-block[data-align=right]>.wp-block-embed .wp-block-embed__wrapper{ min-width:280px; } .wp-block-file{ align-items:center; display:flex; flex-wrap:wrap; justify-content:space-between; margin-bottom:0; } .wp-block[data-align=left]>.wp-block-file,.wp-block[data-align=right]>.wp-block-file{ height:auto; } .wp-block[data-align=center]>.wp-block-file{ text-align:center; } .wp-block-file .components-resizable-box__container{ margin-bottom:1em; } .wp-block-file .wp-block-file__preview{ height:100%; margin-bottom:1em; width:100%; } .wp-block-file .wp-block-file__preview-overlay{ bottom:0; left:0; position:absolute; right:0; top:0; } .wp-block-file .wp-block-file__content-wrapper{ flex-grow:1; } .wp-block-file a{ min-width:1em; } .wp-block-file a:not(.wp-block-file__button){ display:inline-block; } .wp-block-file .wp-block-file__button-richtext-wrapper{ display:inline-block; margin-left:.75em; } .wp-block-form-input .is-input-hidden{ background:repeating-linear-gradient(45deg, #0000, #0000 5px, currentColor 0, currentColor 6px); border:1px dashed; box-sizing:border-box; font-size:.85em; opacity:.3; padding:.5em; } .wp-block-form-input .is-input-hidden input[type=text]{ background:#0000; } .wp-block-form-input.is-selected .is-input-hidden{ background:none; opacity:1; } .wp-block-form-input.is-selected .is-input-hidden input[type=text]{ background:unset; } .wp-block-form-submission-notification>*{ background:repeating-linear-gradient(45deg, #0000, #0000 5px, currentColor 0, currentColor 6px); border:1px dashed; box-sizing:border-box; opacity:.25; } .wp-block-form-submission-notification.is-selected>*,.wp-block-form-submission-notification:has(.is-selected)>*{ background:none; opacity:1; } .wp-block-form-submission-notification.is-selected:after,.wp-block-form-submission-notification:has(.is-selected):after{ display:none !important; } .wp-block-form-submission-notification:after{ align-items:center; display:flex; font-size:1.1em; height:100%; justify-content:center; left:0; position:absolute; top:0; width:100%; } .wp-block-form-submission-notification.form-notification-type-success:after{ content:attr(data-message-success); } .wp-block-form-submission-notification.form-notification-type-error:after{ content:attr(data-message-error); } .wp-block-freeform.block-library-rich-text__tinymce{ height:auto; } .wp-block-freeform.block-library-rich-text__tinymce li,.wp-block-freeform.block-library-rich-text__tinymce p{ line-height:1.8; } .wp-block-freeform.block-library-rich-text__tinymce ol,.wp-block-freeform.block-library-rich-text__tinymce ul{ margin-left:0; padding-left:2.5em; } .wp-block-freeform.block-library-rich-text__tinymce blockquote{ border-left:4px solid #000; box-shadow:inset 0 0 0 0 #ddd; margin:0; padding-left:1em; } .wp-block-freeform.block-library-rich-text__tinymce pre{ color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:15px; white-space:pre-wrap; } .wp-block-freeform.block-library-rich-text__tinymce>:first-child{ margin-top:0; } .wp-block-freeform.block-library-rich-text__tinymce>:last-child{ margin-bottom:0; } .wp-block-freeform.block-library-rich-text__tinymce.mce-edit-focus{ outline:none; } .wp-block-freeform.block-library-rich-text__tinymce a{ color:var(--wp-admin-theme-color); } .wp-block-freeform.block-library-rich-text__tinymce:focus a[data-mce-selected]{ background:#e5f5fa; border-radius:2px; box-shadow:0 0 0 1px #e5f5fa; margin:0 -2px; padding:0 2px; } .wp-block-freeform.block-library-rich-text__tinymce code{ background:#f0f0f0; border-radius:2px; color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:14px; padding:2px; } .wp-block-freeform.block-library-rich-text__tinymce:focus code[data-mce-selected]{ background:#ddd; } .wp-block-freeform.block-library-rich-text__tinymce .alignright{ float:right; margin:.5em 0 .5em 1em; } .wp-block-freeform.block-library-rich-text__tinymce .alignleft{ float:left; margin:.5em 1em .5em 0; } .wp-block-freeform.block-library-rich-text__tinymce .aligncenter{ display:block; margin-left:auto; margin-right:auto; } .wp-block-freeform.block-library-rich-text__tinymce .wp-more-tag{ background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADtgAAAAoBAMAAAA86gLBAAAAJFBMVEVMaXG7u7vBwcHDw8POzs68vLzGxsbMzMy+vr7AwMDQ0NDGxsYKLGzpAAAADHRSTlMA///zWf+/f///TMxNVGuqAAABwklEQVR4Ae3dMXLaQBTH4bfj8UCpx8hq0vgKvgFNemhT6Qo6gg6R+0ZahM2QLmyBJ99XWP9V5+o3jIUcLQEAAAAAAAAAAAAAAAAAAAAAAABQ8j0WL9lfTtlt18uNXAUA8O/KVtfa1tdcrOdSh9gCQAMlh1hMNbZZ1bsrsQWABsrhLRbz7z5in/32UbfUMUbkMQCAh5RfGYv82UdMdZ6HS2wjT2ILAI8r3XmM2B3WvM59vfO2xXYW2yYAENuPU8S+X/N67mKxzy225yaxBQCxLV392UdcvwV0jPVUj98ntkBWT7C7+9u2/V/vGtvXIWJ6/4rtbottWa6Ri0NUT/u72LYttrb97LHdvUXMxxrb8TO2W2TF1rYbbLG1bbGNjMi4+2Sbi1FsbbvNFlvbFtt5fDnE3d9sP1/XeIyV2Nr2U2/guZUuptNrH/dPI9eLB6SaAEBs6wPJf3/PNk9tYgsAYrv/8TFuzx/fvkFqGtrEFgDEdpcZUb7ejXy6ntrEFgDENvL6gsas4vbdyKt4DACI7TxElJv/Z7udpqFNbAFAbKduy2uU2trttM/x28UWAAAAAAAAAAAAAAAAAAAAAAAAAADgDyPwGmGTCZp7AAAAAElFTkSuQmCC); background-position:50%; background-repeat:no-repeat; background-size:1900px 20px; cursor:default; display:block; height:20px; margin:15px auto; outline:0; width:96%; } .wp-block-freeform.block-library-rich-text__tinymce img::selection{ background-color:initial; } .wp-block-freeform.block-library-rich-text__tinymce div.mceTemp{ -ms-user-select:element; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption{ margin:0; max-width:100%; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption a,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption img{ display:block; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption *{ -webkit-user-drag:none; } .wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption .wp-caption-dd{ margin:0; padding-top:.5em; } .wp-block-freeform.block-library-rich-text__tinymce .wpview{ border:1px solid #0000; clear:both; margin-bottom:16px; position:relative; width:99.99%; } .wp-block-freeform.block-library-rich-text__tinymce .wpview iframe{ background:#0000; display:block; max-width:100%; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .mce-shim{ bottom:0; left:0; position:absolute; right:0; top:0; } .wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected="2"] .mce-shim{ display:none; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .loading-placeholder{ border:1px dashed #ddd; padding:10px; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error{ border:1px solid #ddd; margin:0; padding:1em 0; word-wrap:break-word; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error p{ margin:0; text-align:center; } .wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .loading-placeholder,.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .wpview-error{ border-color:#0000; } .wp-block-freeform.block-library-rich-text__tinymce .wpview .dashicons{ display:block; font-size:32px; height:32px; margin:0 auto; width:32px; } .wp-block-freeform.block-library-rich-text__tinymce .wpview.wpview-type-gallery:after{ clear:both; content:""; display:table; } .wp-block-freeform.block-library-rich-text__tinymce .gallery img[data-mce-selected]:focus{ outline:none; } .wp-block-freeform.block-library-rich-text__tinymce .gallery a{ cursor:default; } .wp-block-freeform.block-library-rich-text__tinymce .gallery{ line-height:1; margin:auto -6px; overflow-x:hidden; padding:6px 0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-item{ box-sizing:border-box; float:left; margin:0; padding:6px; text-align:center; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption,.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-icon{ margin:0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption{ font-size:13px; margin:4px 0; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-1 .gallery-item{ width:100%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-2 .gallery-item{ width:50%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-3 .gallery-item{ width:33.3333333333%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-4 .gallery-item{ width:25%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-5 .gallery-item{ width:20%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-6 .gallery-item{ width:16.6666666667%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-7 .gallery-item{ width:14.2857142857%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-8 .gallery-item{ width:12.5%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-9 .gallery-item{ width:11.1111111111%; } .wp-block-freeform.block-library-rich-text__tinymce .gallery img{ border:none; height:auto; max-width:100%; padding:0; } div[data-type="core/freeform"]:before{ border:1px solid #ddd; outline:1px solid #0000; } @media not (prefers-reduced-motion){ div[data-type="core/freeform"]:before{ transition:border-color .1s linear,box-shadow .1s linear; } } div[data-type="core/freeform"].is-selected:before{ border-color:#1e1e1e; } div[data-type="core/freeform"] .block-editor-block-contextual-toolbar+div{ margin-top:0; padding-top:0; } div[data-type="core/freeform"].is-selected .block-library-rich-text__tinymce:after{ clear:both; content:""; display:table; } .mce-toolbar-grp .mce-btn.mce-active button,.mce-toolbar-grp .mce-btn.mce-active i,.mce-toolbar-grp .mce-btn.mce-active:hover button,.mce-toolbar-grp .mce-btn.mce-active:hover i{ color:#1e1e1e; } .mce-toolbar-grp .mce-rtl .mce-flow-layout-item.mce-last{ margin-left:8px; margin-right:0; } .mce-toolbar-grp .mce-btn i{ font-style:normal; } .block-library-classic__toolbar{ border:1px solid #ddd; border-bottom:none; border-radius:2px; display:none; margin:0 0 8px; padding:0; position:sticky; top:0; width:auto; z-index:31; } div[data-type="core/freeform"].is-selected .block-library-classic__toolbar{ border-color:#1e1e1e; display:block; } .block-library-classic__toolbar .mce-tinymce{ box-shadow:none; } @media (min-width:600px){ .block-library-classic__toolbar{ padding:0; } } .block-library-classic__toolbar:empty{ background:#f5f5f5; border-bottom:1px solid #e2e4e7; display:block; } .block-library-classic__toolbar:empty:before{ color:#555d66; content:attr(data-placeholder); font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:37px; padding:14px; } .block-library-classic__toolbar div.mce-toolbar-grp{ border-bottom:1px solid #1e1e1e; } .block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar .mce-menubar>div,.block-library-classic__toolbar .mce-tinymce-inline,.block-library-classic__toolbar .mce-tinymce-inline>div,.block-library-classic__toolbar div.mce-toolbar-grp,.block-library-classic__toolbar div.mce-toolbar-grp>div{ height:auto !important; width:100% !important; } .block-library-classic__toolbar .mce-container-body.mce-abs-layout{ overflow:visible; } .block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar div.mce-toolbar-grp{ position:static; } .block-library-classic__toolbar .mce-toolbar-grp>div{ padding:1px 3px; } .block-library-classic__toolbar .mce-toolbar-grp .mce-toolbar:not(:first-child){ display:none; } .block-library-classic__toolbar.has-advanced-toolbar .mce-toolbar-grp .mce-toolbar{ display:block; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{ height:50vh !important; } @media (min-width:960px){ .block-editor-freeform-modal .block-editor-freeform-modal__content:not(.is-full-screen){ height:9999rem; } .block-editor-freeform-modal .block-editor-freeform-modal__content .components-modal__header+div{ height:100%; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-tinymce{ height:calc(100% - 52px); } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-container-body{ display:flex; flex-direction:column; height:100%; min-width:50vw; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area{ display:flex; flex-direction:column; flex-grow:1; } .block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{ flex-grow:1; height:10px !important; } } .block-editor-freeform-modal__actions{ margin-top:16px; } :root :where(figure.wp-block-gallery){ display:block; } :root :where(figure.wp-block-gallery)>.blocks-gallery-caption{ flex:0 0 100%; } :root :where(figure.wp-block-gallery)>.blocks-gallery-media-placeholder-wrapper{ flex-basis:100%; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice.is-error{ display:block; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice__content{ margin:4px 0; } :root :where(figure.wp-block-gallery) .wp-block-image .components-notice__dismiss{ position:absolute; right:5px; top:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .components-placeholder__label{ display:none; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .block-editor-media-placeholder__button{ margin-bottom:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder{ margin:0; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder .components-placeholder__label{ display:flex; } :root :where(figure.wp-block-gallery) .block-editor-media-placeholder figcaption{ z-index:2; } :root :where(figure.wp-block-gallery) .components-spinner{ left:50%; margin-left:-9px; margin-top:-9px; position:absolute; top:50%; } .gallery-settings-buttons .components-button:first-child{ margin-right:8px; } .gallery-image-sizes .components-base-control__label{ margin-bottom:4px; } .gallery-image-sizes .gallery-image-sizes__loading{ align-items:center; color:#757575; display:flex; font-size:12px; } .gallery-image-sizes .components-spinner{ margin:0 8px 0 4px; } .blocks-gallery-item figure:not(.is-selected):focus,.blocks-gallery-item img:focus{ outline:none; } .blocks-gallery-item figure.is-selected:before{ bottom:0; box-shadow:0 0 0 1px #fff inset, 0 0 0 3px var(--wp-admin-theme-color) inset; content:""; left:0; outline:2px solid #0000; pointer-events:none; position:absolute; right:0; top:0; z-index:1; } .blocks-gallery-item figure.is-transient img{ opacity:.3; } .blocks-gallery-item .block-editor-media-placeholder{ height:100%; margin:0; } .blocks-gallery-item .block-editor-media-placeholder .components-placeholder__label{ display:flex; } .wp-block-gallery ul.blocks-gallery-grid{ margin:0; padding:0; } @media (min-width:600px){ .wp-block-update-gallery-modal{ max-width:480px; } } .wp-block-update-gallery-modal-buttons{ display:flex; gap:12px; justify-content:flex-end; } .wp-block-group .block-editor-block-list__insertion-point{ left:0; right:0; } [data-type="core/group"].is-selected .block-list-appender{ margin-left:0; margin-right:0; } [data-type="core/group"].is-selected .has-background .block-list-appender{ margin-bottom:18px; margin-top:18px; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child{ gap:inherit; pointer-events:none; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-default-block-appender__content,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{ display:inherit; flex:1; flex-direction:inherit; width:100%; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child:after{ border:1px dashed; content:""; display:flex; flex:1 0 40px; min-height:38px; pointer-events:none; } .wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-button-block-appender,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{ pointer-events:all; } .block-library-html__edit .block-library-html__preview-overlay{ height:100%; left:0; position:absolute; top:0; width:100%; } .block-library-html__edit .block-editor-plain-text{ background:#fff !important; border:1px solid #1e1e1e !important; border-radius:2px !important; box-shadow:none !important; box-sizing:border-box; color:#1e1e1e !important; direction:ltr; font-family:Menlo,Consolas,monaco,monospace !important; font-size:16px !important; max-height:250px; padding:12px !important; } @media (min-width:600px){ .block-library-html__edit .block-editor-plain-text{ font-size:13px !important; } } .block-library-html__edit .block-editor-plain-text:focus{ border-color:var(--wp-admin-theme-color) !important; box-shadow:0 0 0 1px var(--wp-admin-theme-color) !important; outline:2px solid #0000 !important; } .wp-block-image.wp-block-image .block-editor-media-placeholder.is-small{ min-height:60px; } figure.wp-block-image:not(.wp-block){ margin:0; } .wp-block-image{ position:relative; } .wp-block-image .is-applying img,.wp-block-image.is-transient img{ opacity:.3; } .wp-block-image figcaption img{ display:inline; } .wp-block-image .components-spinner{ left:50%; margin:0; position:absolute; top:50%; transform:translate(-50%, -50%); } .wp-block-image__placeholder{ aspect-ratio:4/3; } .wp-block-image__placeholder.has-illustration:before{ background:#fff; opacity:.8; } .wp-block-image__placeholder .components-placeholder__illustration{ opacity:.1; } .wp-block-image .components-resizable-box__container{ display:table; } .wp-block-image .components-resizable-box__container img{ display:block; height:inherit; width:inherit; } .block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{ left:0; margin:-1px 0; position:absolute; right:0; } @media (min-width:600px){ .block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{ margin:-1px; } } [data-align=full]>.wp-block-image img,[data-align=wide]>.wp-block-image img{ height:auto; width:100%; } .wp-block[data-align=center]>.wp-block-image,.wp-block[data-align=left]>.wp-block-image,.wp-block[data-align=right]>.wp-block-image{ display:table; } .wp-block[data-align=center]>.wp-block-image>figcaption,.wp-block[data-align=left]>.wp-block-image>figcaption,.wp-block[data-align=right]>.wp-block-image>figcaption{ caption-side:bottom; display:table-caption; } .wp-block[data-align=left]>.wp-block-image{ margin:.5em 1em .5em 0; } .wp-block[data-align=right]>.wp-block-image{ margin:.5em 0 .5em 1em; } .wp-block[data-align=center]>.wp-block-image{ margin-left:auto; margin-right:auto; text-align:center; } .wp-block[data-align]:has(>.wp-block-image){ position:relative; } .wp-block-image__crop-area{ max-width:100%; overflow:hidden; position:relative; width:100%; } .wp-block-image__crop-area .reactEasyCrop_Container{ pointer-events:auto; } .wp-block-image__crop-area .reactEasyCrop_Container .reactEasyCrop_Image{ border:none; border-radius:0; } .wp-block-image__crop-icon{ align-items:center; display:flex; justify-content:center; min-width:48px; padding:0 8px; } .wp-block-image__crop-icon svg{ fill:currentColor; } .wp-block-image__zoom .components-popover__content{ min-width:260px; overflow:visible !important; } .wp-block-image__toolbar_content_textarea__container{ padding:8px; } .wp-block-image__toolbar_content_textarea{ width:250px; } .wp-block-latest-posts>li{ overflow:hidden; } .wp-block-latest-posts li a>div{ display:inline; } :root :where(.wp-block-latest-posts){ padding-left:2.5em; } :root :where(.wp-block-latest-posts.is-grid),:root :where(.wp-block-latest-posts__list){ padding-left:0; } .wp-block-media-text__media{ position:relative; } .wp-block-media-text__media.is-transient img{ opacity:.3; } .wp-block-media-text__media .components-spinner{ left:50%; margin-left:-9px; margin-top:-9px; position:absolute; top:50%; } .wp-block-media-text .__resizable_base__{ grid-column:1 / span 2; grid-row:2; } .wp-block-media-text .editor-media-container__resizer{ width:100% !important; } .wp-block-media-text.is-image-fill .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill .editor-media-container__resizer,.wp-block-media-text.is-image-fill-element .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill-element .editor-media-container__resizer{ height:100% !important; } .wp-block-media-text>.block-editor-block-list__layout>.block-editor-block-list__block{ max-width:unset; } .wp-block-media-text--placeholder-image{ min-height:205px; } .block-editor-block-list__block[data-type="core/more"]{ margin-bottom:28px; margin-top:28px; max-width:100%; text-align:center; } .wp-block-more{ display:block; text-align:center; white-space:nowrap; } .wp-block-more input[type=text]{ background:#fff; border:none; border-radius:4px; box-shadow:none; color:#757575; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; height:24px; margin:0; max-width:100%; padding:6px 8px; position:relative; text-align:center; text-transform:uppercase; white-space:nowrap; } .wp-block-more input[type=text]:focus{ box-shadow:none; } .wp-block-more:before{ border-top:3px dashed #ccc; content:""; left:0; position:absolute; right:0; top:50%; } .editor-styles-wrapper .wp-block-navigation ul{ margin-bottom:0; margin-left:0; margin-top:0; padding-left:0; } .editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block{ margin:revert; } .wp-block-navigation-item__label{ display:inline; } .wp-block-navigation-item,.wp-block-navigation__container{ background-color:inherit; } .wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover>.wp-block-navigation__submenu-container{ opacity:0; visibility:hidden; } .has-child.has-child-selected>.wp-block-navigation__submenu-container,.has-child.is-selected>.wp-block-navigation__submenu-container{ display:flex; opacity:1; visibility:visible; } .is-dragging-components-draggable .has-child.is-dragging-within>.wp-block-navigation__submenu-container{ opacity:1; visibility:visible; } .is-editing>.wp-block-navigation__container{ display:flex; flex-direction:column; opacity:1; visibility:visible; } .is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container{ opacity:1; visibility:hidden; } .is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container .block-editor-block-draggable-chip-wrapper{ visibility:visible; } .is-editing>.wp-block-navigation__submenu-container>.block-list-appender{ display:block; position:static; width:100%; } .is-editing>.wp-block-navigation__submenu-container>.block-list-appender .block-editor-button-block-appender{ background:#1e1e1e; color:#fff; margin-left:auto; margin-right:0; padding:0; width:24px; } .wp-block-navigation__submenu-container .block-list-appender{ display:none; } .block-library-colors-selector{ width:auto; } .block-library-colors-selector .block-library-colors-selector__toggle{ display:block; margin:0 auto; padding:3px; width:auto; } .block-library-colors-selector .block-library-colors-selector__icon-container{ align-items:center; border-radius:4px; display:flex; height:30px; margin:0 auto; padding:3px; position:relative; } .block-library-colors-selector .block-library-colors-selector__state-selection{ border-radius:11px; box-shadow:inset 0 0 0 1px #0003; height:22px; line-height:20px; margin-left:auto; margin-right:auto; min-height:22px; min-width:22px; padding:2px; width:22px; } .block-library-colors-selector .block-library-colors-selector__state-selection>svg{ min-width:auto !important; } .block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg,.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg path{ color:inherit; } .block-library-colors-selector__popover .color-palette-controller-container{ padding:16px; } .block-library-colors-selector__popover .components-base-control__label{ height:20px; line-height:20px; } .block-library-colors-selector__popover .component-color-indicator{ float:right; margin-top:2px; } .block-library-colors-selector__popover .components-panel__body-title{ display:none; } .wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender{ background-color:#1e1e1e; color:#fff; height:24px; } .wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender.block-editor-button-block-appender.block-editor-button-block-appender{ padding:0; } .wp-block-navigation .wp-block .wp-block .block-editor-button-block-appender{ background-color:initial; color:#1e1e1e; } @keyframes loadingpulse{ 0%{ opacity:1; } 50%{ opacity:.5; } to{ opacity:1; } } .components-placeholder.wp-block-navigation-placeholder{ background:none; box-shadow:none; color:inherit; min-height:0; outline:none; padding:0; } .components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset{ font-size:inherit; } .components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button{ margin-bottom:0; } .wp-block-navigation.is-selected .components-placeholder.wp-block-navigation-placeholder{ color:#1e1e1e; } .wp-block-navigation-placeholder__preview{ align-items:center; background:#0000; color:currentColor; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; min-width:96px; } .wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview{ display:none; } .wp-block-navigation-placeholder__preview:before{ border:1px dashed; border-radius:inherit; bottom:0; content:""; display:block; left:0; pointer-events:none; position:absolute; right:0; top:0; } .wp-block-navigation-placeholder__preview>svg{ fill:currentColor; } .wp-block-navigation.is-vertical .is-medium .components-placeholder__fieldset,.wp-block-navigation.is-vertical .is-small .components-placeholder__fieldset{ min-height:90px; } .wp-block-navigation.is-vertical .is-large .components-placeholder__fieldset{ min-height:132px; } .wp-block-navigation-placeholder__controls,.wp-block-navigation-placeholder__preview{ align-items:flex-start; flex-direction:row; padding:6px 8px; } .wp-block-navigation-placeholder__controls{ background-color:#fff; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; display:none; float:left; position:relative; width:100%; z-index:1; } .wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls{ display:flex; } .is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr{ display:none; } .is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions{ align-items:flex-start; flex-direction:column; } .is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr{ display:none; } .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon{ height:36px; margin-right:12px; } .wp-block-navigation-placeholder__actions__indicator{ align-items:center; display:flex; height:36px; justify-content:flex-start; line-height:0; margin-left:4px; padding:0 6px 0 0; } .wp-block-navigation-placeholder__actions__indicator svg{ margin-right:4px; fill:currentColor; } .wp-block-navigation .components-placeholder.is-medium .components-placeholder__fieldset{ flex-direction:row !important; } .wp-block-navigation-placeholder__actions{ align-items:center; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; gap:6px; height:100%; } .wp-block-navigation-placeholder__actions .components-dropdown,.wp-block-navigation-placeholder__actions>.components-button{ margin-right:0; } .wp-block-navigation-placeholder__actions.wp-block-navigation-placeholder__actions hr{ background-color:#1e1e1e; border:0; height:100%; margin:auto 0; max-height:16px; min-height:1px; min-width:1px; } @media (min-width:600px){ .wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close{ display:none; } } .wp-block-navigation__responsive-container.is-menu-open{ position:fixed; top:155px; } @media (min-width:782px){ .wp-block-navigation__responsive-container.is-menu-open{ left:36px; top:93px; } } @media (min-width:960px){ .wp-block-navigation__responsive-container.is-menu-open{ left:160px; } } .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{ top:141px; } .is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{ left:0; top:155px; } @media (min-width:782px){ .is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{ top:61px; } } .is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{ top:109px; } body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open{ bottom:0; left:0; right:0; top:0; } .components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close,.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{ color:inherit; height:auto; padding:0; } .components-heading.wp-block-navigation-off-canvas-editor__title{ margin:0; } .wp-block-navigation-off-canvas-editor__header{ margin-bottom:8px; } .is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender{ margin-top:16px; } @keyframes fadein{ 0%{ opacity:0; } to{ opacity:1; } } .wp-block-navigation__loading-indicator-container{ padding:8px 12px; } .wp-block-navigation .wp-block-navigation__uncontrolled-inner-blocks-loading-indicator{ margin-top:0; } @keyframes fadeouthalf{ 0%{ opacity:1; } to{ opacity:.5; } } .wp-block-navigation-delete-menu-button{ justify-content:center; margin-bottom:16px; width:100%; } .components-button.is-link.wp-block-navigation-manage-menus-button{ margin-bottom:16px; } .wp-block-navigation__overlay-menu-preview{ align-items:center; background-color:#f0f0f0; display:flex; height:64px !important; justify-content:space-between; margin-bottom:12px; padding:0 24px; width:100%; } .wp-block-navigation__overlay-menu-preview.open{ background-color:#fff; box-shadow:inset 0 0 0 1px #e0e0e0; outline:1px solid #0000; } .wp-block-navigation-placeholder__actions hr+hr,.wp-block-navigation__toolbar-menu-selector.components-toolbar-group:empty{ display:none; } .wp-block-navigation__navigation-selector{ margin-bottom:16px; width:100%; } .wp-block-navigation__navigation-selector-button{ border:1px solid; justify-content:space-between; width:100%; } .wp-block-navigation__navigation-selector-button__icon{ flex:0 0 auto; } .wp-block-navigation__navigation-selector-button__label{ flex:0 1 auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .wp-block-navigation__navigation-selector-button--createnew{ border:1px solid; margin-bottom:16px; width:100%; } .wp-block-navigation__responsive-container-open.components-button{ opacity:1; } .wp-block-navigation__menu-inspector-controls{ overflow-x:auto; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-width:thin; will-change:transform; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar{ height:12px; width:12px; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-track{ background-color:initial; } .wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .wp-block-navigation__menu-inspector-controls:focus-within::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:focus::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .wp-block-navigation__menu-inspector-controls:focus,.wp-block-navigation__menu-inspector-controls:focus-within,.wp-block-navigation__menu-inspector-controls:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .wp-block-navigation__menu-inspector-controls{ scrollbar-color:#949494 #0000; } } .wp-block-navigation__menu-inspector-controls__empty-message{ margin-left:24px; } .wp-block-navigation__overlay-menu-icon-toggle-group{ margin-bottom:16px; } .wp-block-navigation .block-list-appender{ position:relative; } .wp-block-navigation .has-child{ cursor:pointer; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ z-index:28; } .wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{ z-index:29; } .wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{ height:auto !important; min-width:200px !important; opacity:1 !important; overflow:visible !important; visibility:visible !important; width:auto !important; } .wp-block-navigation-item .wp-block-navigation-item__content{ cursor:text; } .wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{ min-width:20px; } .wp-block-navigation-item .block-list-appender{ margin:16px auto 16px 16px; } .wp-block-navigation-link__invalid-item{ color:#000; } .wp-block-navigation-link__placeholder{ background-image:none !important; box-shadow:none !important; position:relative; text-decoration:none !important; } .wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{ -webkit-text-decoration:wavy underline; text-decoration:wavy underline; -webkit-text-decoration-skip-ink:none; text-decoration-skip-ink:none; text-underline-offset:.25rem; } .wp-block-navigation-link__placeholder.wp-block-navigation-item__content{ cursor:pointer; } .link-control-transform{ border-top:1px solid #ccc; padding:0 16px 8px; } .link-control-transform__subheading{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .link-control-transform__items{ display:flex; justify-content:space-between; } .link-control-transform__item{ flex-basis:33%; flex-direction:column; gap:8px; height:auto; } .wp-block-navigation-submenu{ display:block; } .wp-block-navigation-submenu .wp-block-navigation__submenu-container{ z-index:28; } .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{ height:auto !important; left:-1px; min-width:200px !important; opacity:1 !important; position:absolute; top:100%; visibility:visible !important; width:auto !important; } @media (min-width:782px){ .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:100%; top:-1px; } .wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{ background:#0000; content:""; display:block; height:100%; position:absolute; right:100%; width:.5em; } } .block-editor-block-list__block[data-type="core/nextpage"]{ margin-bottom:28px; margin-top:28px; max-width:100%; text-align:center; } .wp-block-nextpage{ display:block; text-align:center; white-space:nowrap; } .wp-block-nextpage>span{ background:#fff; border-radius:4px; color:#757575; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; height:24px; padding:6px 8px; position:relative; text-transform:uppercase; } .wp-block-nextpage:before{ border-top:3px dashed #ccc; content:""; left:0; position:absolute; right:0; top:50%; } .wp-block-navigation .wp-block-page-list,.wp-block-navigation .wp-block-page-list>div{ background-color:inherit; } .wp-block-navigation.items-justified-space-between .wp-block-page-list,.wp-block-navigation.items-justified-space-between .wp-block-page-list>div{ display:contents; flex:1; } .wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list>div,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list>div{ flex:inherit; } .wp-block-navigation .wp-block-navigation__submenu-container>.wp-block-page-list{ display:block; } .wp-block-pages-list__item__link{ pointer-events:none; } @media (min-width:600px){ .wp-block-page-list-modal{ max-width:480px; } } .wp-block-page-list-modal-buttons{ display:flex; gap:12px; justify-content:flex-end; } .wp-block-page-list .open-on-click:focus-within>.wp-block-navigation__submenu-container{ height:auto; min-width:200px; opacity:1; visibility:visible; width:auto; } .wp-block-page-list__loading-indicator-container{ padding:8px 12px; } .block-editor-block-list__block[data-type="core/paragraph"].has-drop-cap:focus{ min-height:auto !important; } .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{ opacity:1; } .block-editor-block-list__block[data-empty=true]+.block-editor-block-list__block[data-empty=true]:not([data-custom-placeholder=true]) [data-rich-text-placeholder]{ opacity:0; } .block-editor-block-list__block[data-type="core/paragraph"].has-text-align-left[style*="writing-mode: vertical-lr"],.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-right[style*="writing-mode: vertical-rl"]{ rotate:180deg; } .is-zoomed-out .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{ opacity:0; } .wp-block-post-author__inspector-settings .components-base-control,.wp-block-post-author__inspector-settings .components-base-control:last-child{ margin-bottom:0; } .wp-block-post-excerpt .wp-block-post-excerpt__excerpt.is-inline{ display:inline; } .wp-block-pullquote.is-style-solid-color blockquote p{ font-size:32px; } .wp-block-pullquote.is-style-solid-color .wp-block-pullquote__citation{ font-style:normal; text-transform:none; } .wp-block-pullquote .wp-block-pullquote__citation{ color:inherit; } .wp-block-rss li a>div{ display:inline; } .wp-block-rss__placeholder-form .wp-block-rss__placeholder-input{ flex:1 1 auto; } .wp-block-rss .wp-block-rss{ all:inherit; margin:0; padding:0; } .wp-block[data-align=center] .wp-block-search .wp-block-search__inside-wrapper{ margin:auto; } .wp-block-search :where(.wp-block-search__button){ align-items:center; border-radius:initial; display:flex; height:auto; justify-content:center; text-align:center; } .wp-block-search__inspector-controls .components-base-control{ margin-bottom:0; } .block-editor-block-list__block[data-type="core/separator"]{ padding-bottom:.1px; padding-top:.1px; } .blocks-shortcode__textarea{ background:#fff !important; border:1px solid #1e1e1e !important; border-radius:2px !important; box-shadow:none !important; box-sizing:border-box; color:#1e1e1e !important; font-family:Menlo,Consolas,monaco,monospace !important; font-size:16px !important; max-height:250px; padding:12px !important; resize:none; } @media (min-width:600px){ .blocks-shortcode__textarea{ font-size:13px !important; } } .blocks-shortcode__textarea:focus{ border-color:var(--wp-admin-theme-color) !important; box-shadow:0 0 0 1px var(--wp-admin-theme-color) !important; outline:2px solid #0000 !important; } .wp-block-site-logo.aligncenter>div,.wp-block[data-align=center]>.wp-block-site-logo{ display:table; margin-left:auto; margin-right:auto; } .wp-block-site-logo a{ pointer-events:none; } .wp-block-site-logo .custom-logo-link{ cursor:inherit; } .wp-block-site-logo .custom-logo-link:focus{ box-shadow:none; } .wp-block-site-logo img{ display:block; height:auto; max-width:100%; } .wp-block-site-logo.is-transient{ position:relative; } .wp-block-site-logo.is-transient img{ opacity:.3; } .wp-block-site-logo.is-transient .components-spinner{ left:50%; margin:0; position:absolute; top:50%; transform:translate(-50%, -50%); } .wp-block-site-logo.wp-block-site-logo.is-default-size .components-placeholder{ height:60px; width:60px; } .wp-block-site-logo.wp-block-site-logo .components-resizable-box__container,.wp-block-site-logo.wp-block-site-logo>div{ border-radius:inherit; } .wp-block-site-logo.wp-block-site-logo .components-placeholder{ align-items:center; border-radius:inherit; display:flex; height:100%; justify-content:center; min-height:48px; min-width:48px; padding:0; width:100%; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-drop-zone__content-text,.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-form-file-upload{ display:none; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button{ align-items:center; background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); border-radius:50%; border-style:solid; color:#fff; display:flex; height:48px; justify-content:center; margin:auto; padding:0; position:relative; width:48px; } .wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button>svg{ color:inherit; } .block-library-site-logo__inspector-media-replace-container{ position:relative; } .block-library-site-logo__inspector-media-replace-container .components-drop-zone__content-icon{ display:none; } .block-library-site-logo__inspector-media-replace-container button.components-button{ box-shadow:inset 0 0 0 1px #ccc; color:#1e1e1e; display:block; height:40px; width:100%; } .block-library-site-logo__inspector-media-replace-container button.components-button:hover{ color:var(--wp-admin-theme-color); } .block-library-site-logo__inspector-media-replace-container button.components-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-media-replace-title{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-library-site-logo__inspector-media-replace-container .components-dropdown{ display:block; } .block-library-site-logo__inspector-media-replace-container img{ aspect-ratio:1; border-radius:50% !important; box-shadow:inset 0 0 0 1px #0003; min-width:20px; width:20px; } .block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-readonly-logo-preview{ display:flex; height:40px; padding:6px 12px; } .wp-block-site-tagline__placeholder,.wp-block-site-title__placeholder{ border:1px dashed; padding:1em 0; } .wp-block-social-links .wp-social-link{ line-height:0; } .wp-block-social-link-anchor{ align-items:center; background:none; border:0; box-sizing:border-box; color:currentColor; cursor:pointer; display:inline-flex; font-family:inherit; font-size:inherit; font-weight:inherit; height:auto; margin:0; opacity:1; padding:.25em; } .wp-block-social-link-anchor:hover{ transform:none; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link button){ padding-left:.6666666667em; padding-right:.6666666667em; } :root :where(.wp-block-social-links.is-style-logos-only .wp-social-link button){ padding:0; } .wp-block-social-link__toolbar_content_text{ width:250px; } .wp-block-social-links div.block-editor-url-input{ display:inline-block; margin-left:8px; } .wp-social-link:hover{ transform:none; } :root :where(.wp-block-social-links),:root :where(.wp-block-social-links.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link){ padding:0; } :root :where(.wp-block-social-links__social-placeholder .wp-social-link){ padding:.25em; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-block-social-links__social-placeholder .wp-social-link){ padding-left:.6666666667em; padding-right:.6666666667em; } .wp-block-social-links__social-placeholder{ display:flex; list-style:none; opacity:.8; } .wp-block-social-links__social-placeholder>.wp-social-link{ margin-left:0 !important; margin-right:0 !important; padding-left:0 !important; padding-right:0 !important; visibility:hidden; width:0 !important; } .wp-block-social-links__social-placeholder>.wp-block-social-links__social-placeholder-icons{ display:flex; } .wp-block-social-links__social-placeholder .wp-social-link:before{ border-radius:50%; content:""; display:block; height:1em; width:1em; } .is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link:before{ background:currentColor; } .wp-block-social-links .wp-block-social-links__social-prompt{ cursor:default; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:24px; list-style:none; margin-bottom:auto; margin-top:auto; min-height:24px; padding-right:8px; } .wp-block.wp-block-social-links.aligncenter,.wp-block[data-align=center]>.wp-block-social-links{ justify-content:center; } .block-editor-block-preview__content .components-button:disabled{ opacity:1; } .wp-social-link.wp-social-link__is-incomplete{ opacity:.5; } .wp-block-social-links .is-selected .wp-social-link__is-incomplete,.wp-social-link.wp-social-link__is-incomplete:focus,.wp-social-link.wp-social-link__is-incomplete:hover{ opacity:1; } .wp-block-social-links .block-list-appender{ position:static; } .wp-block-social-links .block-list-appender .block-editor-inserter{ font-size:inherit; } .wp-block-social-links .block-list-appender .block-editor-button-block-appender{ font-size:inherit; height:1.5em; padding:0; width:1.5em; } .block-editor-block-list__block[data-type="core/spacer"]:before{ content:""; display:block; height:100%; min-height:8px; min-width:8px; position:absolute; width:100%; z-index:1; } .block-library-spacer__resize-container.has-show-handle,.wp-block-spacer.is-hovered .block-library-spacer__resize-container,.wp-block-spacer.is-selected.custom-sizes-disabled{ background:#0000001a; } .is-dark-theme .block-library-spacer__resize-container.has-show-handle,.is-dark-theme .wp-block-spacer.is-hovered .block-library-spacer__resize-container,.is-dark-theme .wp-block-spacer.is-selected.custom-sizes-disabled{ background:#ffffff26; } .block-library-spacer__resize-container{ clear:both; } .block-library-spacer__resize-container:not(.is-resizing){ height:100% !important; width:100% !important; } .block-library-spacer__resize-container .components-resizable-box__handle:before{ content:none; } .block-library-spacer__resize-container.resize-horizontal{ height:100% !important; margin-bottom:0; } .wp-block[data-align=center]>.wp-block-table,.wp-block[data-align=left]>.wp-block-table,.wp-block[data-align=right]>.wp-block-table{ height:auto; } .wp-block[data-align=center]>.wp-block-table table,.wp-block[data-align=left]>.wp-block-table table,.wp-block[data-align=right]>.wp-block-table table{ width:auto; } .wp-block[data-align=center]>.wp-block-table td,.wp-block[data-align=center]>.wp-block-table th,.wp-block[data-align=left]>.wp-block-table td,.wp-block[data-align=left]>.wp-block-table th,.wp-block[data-align=right]>.wp-block-table td,.wp-block[data-align=right]>.wp-block-table th{ word-break:break-word; } .wp-block[data-align=center]>.wp-block-table{ text-align:initial; } .wp-block[data-align=center]>.wp-block-table table{ margin:0 auto; } .wp-block-table td,.wp-block-table th{ border:1px solid; padding:.5em; } .wp-block-table td.is-selected,.wp-block-table th.is-selected{ border-color:var(--wp-admin-theme-color); border-style:double; box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .wp-block-table table.has-individual-borders td,.wp-block-table table.has-individual-borders th,.wp-block-table table.has-individual-borders tr,.wp-block-table table.has-individual-borders>*{ border:1px solid; } .blocks-table__placeholder-form.blocks-table__placeholder-form{ align-items:flex-start; display:flex; flex-direction:column; gap:8px; } @media (min-width:782px){ .blocks-table__placeholder-form.blocks-table__placeholder-form{ align-items:flex-end; flex-direction:row; } } .blocks-table__placeholder-input{ width:112px; } .wp-block-tag-cloud .wp-block-tag-cloud{ border:none; border-radius:inherit; margin:0; padding:0; } .block-editor-template-part__selection-modal{ z-index:1000001; } .block-editor-template-part__selection-modal .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:1280px){ .block-editor-template-part__selection-modal .block-editor-block-patterns-list{ column-count:3; } } .block-editor-template-part__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .block-library-template-part__selection-search{ background:#fff; padding:16px 0; position:sticky; top:0; z-index:2; } .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{ outline-color:var(--wp-block-synced-color); } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.has-editable-outline:after{ border:none; } .wp-block-text-columns .block-editor-rich-text__editable:focus{ outline:1px solid #ddd; } .wp-block[data-align=center]>.wp-block-video{ text-align:center; } .wp-block-video{ position:relative; } .wp-block-video.is-transient video{ opacity:.3; } .wp-block-video .components-spinner{ left:50%; margin-left:-9px; margin-top:-9px; position:absolute; top:50%; } .editor-video-poster-control .components-button{ margin-right:8px; } .block-library-video-tracks-editor{ z-index:159990; } .block-library-video-tracks-editor__track-list-track{ padding-left:12px; } .block-library-video-tracks-editor__single-track-editor-kind-select{ max-width:240px; } .block-library-video-tracks-editor__single-track-editor-edit-track-label,.block-library-video-tracks-editor__tracks-informative-message-title{ color:#757575; display:block; font-size:11px; font-weight:500; margin-top:4px; text-transform:uppercase; } .block-library-video-tracks-editor>.components-popover__content{ width:360px; } .block-library-video-tracks-editor__add-tracks-container .components-menu-group__label,.block-library-video-tracks-editor__track-list .components-menu-group__label{ padding:0; } .block-library-video-tracks-editor__tracks-informative-message{ padding:8px; } .block-library-video-tracks-editor__tracks-informative-message-description{ margin-bottom:0; } .block-library-query-pattern__selection-modal .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:1280px){ .block-library-query-pattern__selection-modal .block-editor-block-patterns-list{ column-count:3; } } .block-library-query-pattern__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .block-library-query-pattern__selection-modal .block-library-query-pattern__selection-search{ background:#fff; margin-bottom:-4px; padding:16px 0; position:sticky; top:0; transform:translateY(-4px); z-index:2; } @media (min-width:600px){ .wp-block-query__enhanced-pagination-modal{ max-width:480px; } } .block-editor-block-settings-menu__popover.is-expanded{ overflow-y:scroll; } .block-editor-block-settings-menu__popover .block-library-query-pattern__selection-content{ height:100%; } .block-editor-block-settings-menu__popover .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr; grid-gap:12px; min-width:280px; } @media (min-width:600px){ .block-editor-block-settings-menu__popover .block-editor-block-patterns-list{ grid-template-columns:1fr 1fr; min-width:480px; } } .block-editor-block-settings-menu__popover .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .wp-block[data-align=center]>.wp-block-query-pagination{ justify-content:center; } :where(.editor-styles-wrapper) .wp-block-query-pagination{ max-width:100%; } :where(.editor-styles-wrapper) .wp-block-query-pagination.block-editor-block-list__layout{ margin:0; } .wp-block-query-pagination-numbers a{ text-decoration:underline; } .wp-block-query-pagination-numbers .page-numbers{ margin-right:2px; } .wp-block-query-pagination-numbers .page-numbers:last-child{ margin-right:0; } .wp-block-post-featured-image .block-editor-media-placeholder{ -webkit-backdrop-filter:none; backdrop-filter:none; z-index:1; } .wp-block-post-featured-image .components-placeholder,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder{ align-items:center; display:flex; justify-content:center; min-height:200px; padding:0; } .wp-block-post-featured-image .components-placeholder .components-form-file-upload,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-form-file-upload{ display:none; } .wp-block-post-featured-image .components-placeholder .components-button,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button{ align-items:center; background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); border-radius:50%; border-style:solid; color:#fff; display:flex; height:48px; justify-content:center; margin:auto; padding:0; position:relative; width:48px; } .wp-block-post-featured-image .components-placeholder .components-button>svg,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button>svg{ color:inherit; } .wp-block-post-featured-image .components-placeholder:where(.has-border-color),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where(.has-border-color),.wp-block-post-featured-image img:where(.has-border-color){ border-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-top-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-color]),.wp-block-post-featured-image img:where([style*=border-top-color]){ border-top-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-right-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-color]),.wp-block-post-featured-image img:where([style*=border-right-color]){ border-right-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image img:where([style*=border-bottom-color]){ border-bottom-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-left-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-color]),.wp-block-post-featured-image img:where([style*=border-left-color]){ border-left-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-width]),.wp-block-post-featured-image img:where([style*=border-width]){ border-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-top-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-width]),.wp-block-post-featured-image img:where([style*=border-top-width]){ border-top-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-right-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-width]),.wp-block-post-featured-image img:where([style*=border-right-width]){ border-right-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image img:where([style*=border-bottom-width]){ border-bottom-style:solid; } .wp-block-post-featured-image .components-placeholder:where([style*=border-left-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-width]),.wp-block-post-featured-image img:where([style*=border-left-width]){ border-left-style:solid; } .wp-block-post-featured-image[style*=height] .components-placeholder{ height:100%; min-height:48px; min-width:48px; width:100%; } .wp-block-post-featured-image>a{ pointer-events:none; } .wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-button,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__instructions,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__label{ opacity:1; pointer-events:auto; } .wp-block-post-featured-image.is-transient{ position:relative; } .wp-block-post-featured-image.is-transient img{ opacity:.3; } .wp-block-post-featured-image.is-transient .components-spinner{ left:50%; position:absolute; top:50%; transform:translate(-50%, -50%); } div[data-type="core/post-featured-image"] img{ display:block; height:auto; max-width:100%; } .wp-block-post-comments-form *{ pointer-events:none; } .wp-block-post-comments-form .block-editor-warning *{ pointer-events:auto; } .wp-element-button{ cursor:revert; } .wp-element-button[role=textbox]{ cursor:text; } :root .editor-styles-wrapper .has-very-light-gray-background-color{ background-color:#eee; } :root .editor-styles-wrapper .has-very-dark-gray-background-color{ background-color:#313131; } :root .editor-styles-wrapper .has-very-light-gray-color{ color:#eee; } :root .editor-styles-wrapper .has-very-dark-gray-color{ color:#313131; } :root .editor-styles-wrapper .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(135deg, #00d084, #0693e3); } :root .editor-styles-wrapper .has-purple-crush-gradient-background{ background:linear-gradient(135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .editor-styles-wrapper .has-hazy-dawn-gradient-background{ background:linear-gradient(135deg, #faaca8, #dad0ec); } :root .editor-styles-wrapper .has-subdued-olive-gradient-background{ background:linear-gradient(135deg, #fafae1, #67a671); } :root .editor-styles-wrapper .has-atomic-cream-gradient-background{ background:linear-gradient(135deg, #fdd79a, #004a59); } :root .editor-styles-wrapper .has-nightshade-gradient-background{ background:linear-gradient(135deg, #330968, #31cdcf); } :root .editor-styles-wrapper .has-midnight-gradient-background{ background:linear-gradient(135deg, #020381, #2874fc); } :where(.editor-styles-wrapper) .has-regular-font-size{ font-size:16px; } :where(.editor-styles-wrapper) .has-larger-font-size{ font-size:42px; } :where(.editor-styles-wrapper) iframe:not([frameborder]){ border:0; }.wp-element-button{ cursor:pointer; }html :where(.editor-styles-wrapper){ background:#fff; color:initial; font-family:serif; font-size:medium; line-height:normal; } :where(.editor-styles-wrapper) .wp-align-wrapper{ max-width:840px; } :where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-full,:where(.editor-styles-wrapper) .wp-align-wrapper>.wp-block{ max-width:none; } :where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-wide{ max-width:840px; } :where(.editor-styles-wrapper) a{ transition:none; } :where(.editor-styles-wrapper) code,:where(.editor-styles-wrapper) kbd{ background:inherit; font-family:monospace; font-size:inherit; margin:0; padding:0; } :where(.editor-styles-wrapper) p{ font-size:revert; line-height:revert; margin:revert; } :where(.editor-styles-wrapper) ol,:where(.editor-styles-wrapper) ul{ box-sizing:border-box; list-style-type:revert; margin:revert; padding:revert; } :where(.editor-styles-wrapper) ol ol,:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ol,:where(.editor-styles-wrapper) ul ul{ margin:revert; } :where(.editor-styles-wrapper) ol li,:where(.editor-styles-wrapper) ul li{ margin:revert; } :where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ul{ list-style-type:revert; } :where(.editor-styles-wrapper) h1,:where(.editor-styles-wrapper) h2,:where(.editor-styles-wrapper) h3,:where(.editor-styles-wrapper) h4,:where(.editor-styles-wrapper) h5,:where(.editor-styles-wrapper) h6{ color:revert; font-size:revert; font-weight:revert; line-height:revert; margin:revert; } :where(.editor-styles-wrapper) select{ -webkit-appearance:revert; background:revert; border:revert; border-radius:revert; box-shadow:revert; color:revert; cursor:revert; font-family:system-ui; font-size:revert; font-weight:revert; line-height:revert; margin:revert; max-width:revert; min-height:revert; outline:revert; padding:revert; text-shadow:revert; transform:revert; vertical-align:revert; } :where(.editor-styles-wrapper) select:disabled,:where(.editor-styles-wrapper) select:focus{ background-color:revert; background-image:revert; border-color:revert; box-shadow:revert; color:revert; cursor:revert; text-shadow:revert; transform:revert; }.wp-block-button__link{background-color:#32373c;border-radius:9999px;box-shadow:none;color:#fff;font-size:1.125em;padding:calc(.667em + 2px) calc(1.333em + 2px);text-decoration:none}.wp-block-file__button{background:#32373c;color:#fff}.wp-element-button{cursor:revert}.wp-element-button[role=textbox]{cursor:text}@charset "UTF-8"; .wp-block-archives{ box-sizing:border-box; } .wp-block-archives-dropdown label{ display:block; } .wp-block-avatar{ line-height:0; } .wp-block-avatar,.wp-block-avatar img{ box-sizing:border-box; } .wp-block-avatar.aligncenter{ text-align:center; } .wp-block-audio{ box-sizing:border-box; } .wp-block-audio :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-audio audio{ min-width:300px; width:100%; } .wp-block-button__link{ align-content:center; box-sizing:border-box; cursor:pointer; display:inline-block; height:100%; text-align:center; word-break:break-word; } .wp-block-button__link.aligncenter{ text-align:center; } .wp-block-button__link.alignright{ text-align:right; } :where(.wp-block-button__link){ border-radius:9999px; box-shadow:none; padding:calc(.667em + 2px) calc(1.333em + 2px); text-decoration:none; } .wp-block-button[style*=text-decoration] .wp-block-button__link{ text-decoration:inherit; } .wp-block-buttons>.wp-block-button.has-custom-width{ max-width:none; } .wp-block-buttons>.wp-block-button.has-custom-width .wp-block-button__link{ width:100%; } .wp-block-buttons>.wp-block-button.has-custom-font-size .wp-block-button__link{ font-size:inherit; } .wp-block-buttons>.wp-block-button.wp-block-button__width-25{ width:calc(25% - var(--wp--style--block-gap, .5em)*.75); } .wp-block-buttons>.wp-block-button.wp-block-button__width-50{ width:calc(50% - var(--wp--style--block-gap, .5em)*.5); } .wp-block-buttons>.wp-block-button.wp-block-button__width-75{ width:calc(75% - var(--wp--style--block-gap, .5em)*.25); } .wp-block-buttons>.wp-block-button.wp-block-button__width-100{ flex-basis:100%; width:100%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-25{ width:25%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-50{ width:50%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-75{ width:75%; } .wp-block-button.is-style-squared,.wp-block-button__link.wp-block-button.is-style-squared{ border-radius:0; } .wp-block-button.no-border-radius,.wp-block-button__link.no-border-radius{ border-radius:0 !important; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link){ border:2px solid; padding:.667em 1.333em; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-text-color)){ color:currentColor; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-background)){ background-color:initial; background-image:none; } .wp-block-buttons{ box-sizing:border-box; } .wp-block-buttons.is-vertical{ flex-direction:column; } .wp-block-buttons.is-vertical>.wp-block-button:last-child{ margin-bottom:0; } .wp-block-buttons>.wp-block-button{ display:inline-block; margin:0; } .wp-block-buttons.is-content-justification-left{ justify-content:flex-start; } .wp-block-buttons.is-content-justification-left.is-vertical{ align-items:flex-start; } .wp-block-buttons.is-content-justification-center{ justify-content:center; } .wp-block-buttons.is-content-justification-center.is-vertical{ align-items:center; } .wp-block-buttons.is-content-justification-right{ justify-content:flex-end; } .wp-block-buttons.is-content-justification-right.is-vertical{ align-items:flex-end; } .wp-block-buttons.is-content-justification-space-between{ justify-content:space-between; } .wp-block-buttons.aligncenter{ text-align:center; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block-button.aligncenter{ margin-left:auto; margin-right:auto; width:100%; } .wp-block-buttons[style*=text-decoration] .wp-block-button,.wp-block-buttons[style*=text-decoration] .wp-block-button__link{ text-decoration:inherit; } .wp-block-buttons.has-custom-font-size .wp-block-button__link{ font-size:inherit; } .wp-block-buttons .wp-block-button__link{ width:100%; } .wp-block-button.aligncenter,.wp-block-calendar{ text-align:center; } .wp-block-calendar td,.wp-block-calendar th{ border:1px solid; padding:.25em; } .wp-block-calendar th{ font-weight:400; } .wp-block-calendar caption{ background-color:inherit; } .wp-block-calendar table{ border-collapse:collapse; width:100%; } .wp-block-calendar table:where(:not(.has-text-color)){ color:#40464d; } .wp-block-calendar table:where(:not(.has-text-color)) td,.wp-block-calendar table:where(:not(.has-text-color)) th{ border-color:#ddd; } .wp-block-calendar table.has-background th{ background-color:inherit; } .wp-block-calendar table.has-text-color th{ color:inherit; } :where(.wp-block-calendar table:not(.has-background) th){ background:#ddd; } .wp-block-categories{ box-sizing:border-box; } .wp-block-categories.alignleft{ margin-right:2em; } .wp-block-categories.alignright{ margin-left:2em; } .wp-block-categories.wp-block-categories-dropdown.aligncenter{ text-align:center; } .wp-block-categories .wp-block-categories__label{ display:block; width:100%; } .wp-block-code{ box-sizing:border-box; } .wp-block-code code{ direction:ltr; display:block; font-family:inherit; overflow-wrap:break-word; text-align:initial; white-space:pre-wrap; } .wp-block-columns{ align-items:normal !important; box-sizing:border-box; display:flex; flex-wrap:wrap !important; } @media (min-width:782px){ .wp-block-columns{ flex-wrap:nowrap !important; } } .wp-block-columns.are-vertically-aligned-top{ align-items:flex-start; } .wp-block-columns.are-vertically-aligned-center{ align-items:center; } .wp-block-columns.are-vertically-aligned-bottom{ align-items:flex-end; } @media (max-width:781px){ .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{ flex-basis:100% !important; } } @media (min-width:782px){ .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{ flex-basis:0; flex-grow:1; } .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column[style*=flex-basis]{ flex-grow:0; } } .wp-block-columns.is-not-stacked-on-mobile{ flex-wrap:nowrap !important; } .wp-block-columns.is-not-stacked-on-mobile>.wp-block-column{ flex-basis:0; flex-grow:1; } .wp-block-columns.is-not-stacked-on-mobile>.wp-block-column[style*=flex-basis]{ flex-grow:0; } :where(.wp-block-columns){ margin-bottom:1.75em; } :where(.wp-block-columns.has-background){ padding:1.25em 2.375em; } .wp-block-column{ flex-grow:1; min-width:0; overflow-wrap:break-word; word-break:break-word; } .wp-block-column.is-vertically-aligned-top{ align-self:flex-start; } .wp-block-column.is-vertically-aligned-center{ align-self:center; } .wp-block-column.is-vertically-aligned-bottom{ align-self:flex-end; } .wp-block-column.is-vertically-aligned-stretch{ align-self:stretch; } .wp-block-column.is-vertically-aligned-bottom,.wp-block-column.is-vertically-aligned-center,.wp-block-column.is-vertically-aligned-top{ width:100%; } .wp-block-post-comments{ box-sizing:border-box; } .wp-block-post-comments .alignleft{ float:right; } .wp-block-post-comments .alignright{ float:left; } .wp-block-post-comments .navigation:after{ clear:both; content:""; display:table; } .wp-block-post-comments .commentlist{ clear:both; list-style:none; margin:0; padding:0; } .wp-block-post-comments .commentlist .comment{ min-height:2.25em; padding-right:3.25em; } .wp-block-post-comments .commentlist .comment p{ font-size:1em; line-height:1.8; margin:1em 0; } .wp-block-post-comments .commentlist .children{ list-style:none; margin:0; padding:0; } .wp-block-post-comments .comment-author{ line-height:1.5; } .wp-block-post-comments .comment-author .avatar{ border-radius:1.5em; display:block; float:right; height:2.5em; margin-left:.75em; margin-top:.5em; width:2.5em; } .wp-block-post-comments .comment-author cite{ font-style:normal; } .wp-block-post-comments .comment-meta{ font-size:.875em; line-height:1.5; } .wp-block-post-comments .comment-meta b{ font-weight:400; } .wp-block-post-comments .comment-meta .comment-awaiting-moderation{ display:block; margin-bottom:1em; margin-top:1em; } .wp-block-post-comments .comment-body .commentmetadata{ font-size:.875em; } .wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-post-comments .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-post-comments .comment-reply-title{ margin-bottom:0; } .wp-block-post-comments .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-right:.5em; } .wp-block-post-comments .reply{ font-size:.875em; margin-bottom:1.4em; } .wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } .wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{ padding:calc(.667em + 2px); } :where(.wp-block-post-comments input[type=submit]){ border:none; } .wp-block-comments{ box-sizing:border-box; } .wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{ font-size:inherit; margin-bottom:.5em; margin-right:.5em; } .wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{ margin-right:0; } .wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow{ display:inline-block; margin-left:1ch; } .wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-comments-pagination .wp-block-comments-pagination-next-arrow{ display:inline-block; margin-right:1ch; } .wp-block-comments-pagination .wp-block-comments-pagination-next-arrow:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-comments-pagination.aligncenter{ justify-content:center; } .wp-block-comment-template{ box-sizing:border-box; list-style:none; margin-bottom:0; max-width:100%; padding:0; } .wp-block-comment-template li{ clear:both; } .wp-block-comment-template ol{ list-style:none; margin-bottom:0; max-width:100%; padding-right:2rem; } .wp-block-comment-template.alignleft{ float:right; } .wp-block-comment-template.aligncenter{ margin-left:auto; margin-right:auto; width:fit-content; } .wp-block-comment-template.alignright{ float:left; } .wp-block-comment-date{ box-sizing:border-box; } .comment-awaiting-moderation{ display:block; font-size:.875em; line-height:1.5; } .wp-block-comment-author-name,.wp-block-comment-content,.wp-block-comment-edit-link,.wp-block-comment-reply-link{ box-sizing:border-box; } .wp-block-cover,.wp-block-cover-image{ align-items:center; background-position:50%; box-sizing:border-box; direction:ltr; display:flex; justify-content:center; min-height:430px; overflow:hidden; overflow:clip; padding:1em; position:relative; } .wp-block-cover .has-background-dim:not([class*=-background-color]),.wp-block-cover-image .has-background-dim:not([class*=-background-color]),.wp-block-cover-image.has-background-dim:not([class*=-background-color]),.wp-block-cover.has-background-dim:not([class*=-background-color]){ background-color:#000; } .wp-block-cover .has-background-dim.has-background-gradient,.wp-block-cover-image .has-background-dim.has-background-gradient{ background-color:initial; } .wp-block-cover-image.has-background-dim:before,.wp-block-cover.has-background-dim:before{ background-color:inherit; content:""; } .wp-block-cover .wp-block-cover__background,.wp-block-cover .wp-block-cover__gradient-background,.wp-block-cover-image .wp-block-cover__background,.wp-block-cover-image .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim:not(.has-background-gradient):before,.wp-block-cover.has-background-dim:not(.has-background-gradient):before{ bottom:0; left:0; opacity:.5; position:absolute; right:0; top:0; } .wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-10:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-10:not(.has-background-gradient):before{ opacity:.1; } .wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-20:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-20:not(.has-background-gradient):before{ opacity:.2; } .wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-30:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-30:not(.has-background-gradient):before{ opacity:.3; } .wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-40:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-40:not(.has-background-gradient):before{ opacity:.4; } .wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-50:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-50:not(.has-background-gradient):before{ opacity:.5; } .wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-60:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-60:not(.has-background-gradient):before{ opacity:.6; } .wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-70:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-70:not(.has-background-gradient):before{ opacity:.7; } .wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-80:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-80:not(.has-background-gradient):before{ opacity:.8; } .wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-90:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-90:not(.has-background-gradient):before{ opacity:.9; } .wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-100:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-100:not(.has-background-gradient):before{ opacity:1; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0{ opacity:0; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10{ opacity:.1; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20{ opacity:.2; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30{ opacity:.3; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40{ opacity:.4; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50{ opacity:.5; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60{ opacity:.6; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70{ opacity:.7; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80{ opacity:.8; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90{ opacity:.9; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100{ opacity:1; } .wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.alignleft,.wp-block-cover.alignright{ max-width:420px; width:100%; } .wp-block-cover-image.aligncenter,.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.aligncenter,.wp-block-cover.alignleft,.wp-block-cover.alignright{ display:flex; } .wp-block-cover .wp-block-cover__inner-container,.wp-block-cover-image .wp-block-cover__inner-container{ color:inherit; direction:rtl; position:relative; width:100%; } .wp-block-cover-image.is-position-top-left,.wp-block-cover.is-position-top-left{ align-items:flex-start; justify-content:flex-start; } .wp-block-cover-image.is-position-top-center,.wp-block-cover.is-position-top-center{ align-items:flex-start; justify-content:center; } .wp-block-cover-image.is-position-top-right,.wp-block-cover.is-position-top-right{ align-items:flex-start; justify-content:flex-end; } .wp-block-cover-image.is-position-center-left,.wp-block-cover.is-position-center-left{ align-items:center; justify-content:flex-start; } .wp-block-cover-image.is-position-center-center,.wp-block-cover.is-position-center-center{ align-items:center; justify-content:center; } .wp-block-cover-image.is-position-center-right,.wp-block-cover.is-position-center-right{ align-items:center; justify-content:flex-end; } .wp-block-cover-image.is-position-bottom-left,.wp-block-cover.is-position-bottom-left{ align-items:flex-end; justify-content:flex-start; } .wp-block-cover-image.is-position-bottom-center,.wp-block-cover.is-position-bottom-center{ align-items:flex-end; justify-content:center; } .wp-block-cover-image.is-position-bottom-right,.wp-block-cover.is-position-bottom-right{ align-items:flex-end; justify-content:flex-end; } .wp-block-cover-image.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container{ margin:0; } .wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container{ margin:0; width:auto; } .wp-block-cover .wp-block-cover__image-background,.wp-block-cover video.wp-block-cover__video-background,.wp-block-cover-image .wp-block-cover__image-background,.wp-block-cover-image video.wp-block-cover__video-background{ border:none; bottom:0; box-shadow:none; height:100%; left:0; margin:0; max-height:none; max-width:none; object-fit:cover; outline:none; padding:0; position:absolute; right:0; top:0; width:100%; } .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:fixed; background-repeat:no-repeat; background-size:cover; } @supports (-webkit-touch-callout:inherit){ .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:scroll; } } @media (prefers-reduced-motion:reduce){ .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:scroll; } } .wp-block-cover-image.is-repeated,.wp-block-cover.is-repeated,.wp-block-cover__image-background.is-repeated,video.wp-block-cover__video-background.is-repeated{ background-repeat:repeat; background-size:auto; } .wp-block-cover-image-text,.wp-block-cover-image-text a,.wp-block-cover-image-text a:active,.wp-block-cover-image-text a:focus,.wp-block-cover-image-text a:hover,.wp-block-cover-text,.wp-block-cover-text a,.wp-block-cover-text a:active,.wp-block-cover-text a:focus,.wp-block-cover-text a:hover,section.wp-block-cover-image h2,section.wp-block-cover-image h2 a,section.wp-block-cover-image h2 a:active,section.wp-block-cover-image h2 a:focus,section.wp-block-cover-image h2 a:hover{ color:#fff; } .wp-block-cover-image .wp-block-cover.has-left-content{ justify-content:flex-start; } .wp-block-cover-image .wp-block-cover.has-right-content{ justify-content:flex-end; } .wp-block-cover-image.has-left-content .wp-block-cover-image-text,.wp-block-cover.has-left-content .wp-block-cover-text,section.wp-block-cover-image.has-left-content>h2{ margin-right:0; text-align:right; } .wp-block-cover-image.has-right-content .wp-block-cover-image-text,.wp-block-cover.has-right-content .wp-block-cover-text,section.wp-block-cover-image.has-right-content>h2{ margin-left:0; text-align:left; } .wp-block-cover .wp-block-cover-text,.wp-block-cover-image .wp-block-cover-image-text,section.wp-block-cover-image>h2{ font-size:2em; line-height:1.25; margin-bottom:0; max-width:840px; padding:.44em; text-align:center; z-index:1; } :where(.wp-block-cover-image:not(.has-text-color)),:where(.wp-block-cover:not(.has-text-color)){ color:#fff; } :where(.wp-block-cover-image.is-light:not(.has-text-color)),:where(.wp-block-cover.is-light:not(.has-text-color)){ color:#000; } :root :where(.wp-block-cover h1:not(.has-text-color)),:root :where(.wp-block-cover h2:not(.has-text-color)),:root :where(.wp-block-cover h3:not(.has-text-color)),:root :where(.wp-block-cover h4:not(.has-text-color)),:root :where(.wp-block-cover h5:not(.has-text-color)),:root :where(.wp-block-cover h6:not(.has-text-color)),:root :where(.wp-block-cover p:not(.has-text-color)){ color:inherit; } body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__image-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__video-background{ z-index:0; } body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__gradient-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)).has-background-dim:not(.has-background-gradient):before{ z-index:1; } .has-modal-open body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container{ z-index:auto; } .wp-block-details{ box-sizing:border-box; } .wp-block-details summary{ cursor:pointer; } .wp-block-embed.alignleft,.wp-block-embed.alignright,.wp-block[data-align=left]>[data-type="core/embed"],.wp-block[data-align=right]>[data-type="core/embed"]{ max-width:360px; width:100%; } .wp-block-embed.alignleft .wp-block-embed__wrapper,.wp-block-embed.alignright .wp-block-embed__wrapper,.wp-block[data-align=left]>[data-type="core/embed"] .wp-block-embed__wrapper,.wp-block[data-align=right]>[data-type="core/embed"] .wp-block-embed__wrapper{ min-width:280px; } .wp-block-cover .wp-block-embed{ min-height:240px; min-width:320px; } .wp-block-embed{ overflow-wrap:break-word; } .wp-block-embed :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-embed iframe{ max-width:100%; } .wp-block-embed__wrapper{ position:relative; } .wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper:before{ content:""; display:block; padding-top:50%; } .wp-embed-responsive .wp-has-aspect-ratio iframe{ bottom:0; height:100%; left:0; position:absolute; right:0; top:0; width:100%; } .wp-embed-responsive .wp-embed-aspect-21-9 .wp-block-embed__wrapper:before{ padding-top:42.85%; } .wp-embed-responsive .wp-embed-aspect-18-9 .wp-block-embed__wrapper:before{ padding-top:50%; } .wp-embed-responsive .wp-embed-aspect-16-9 .wp-block-embed__wrapper:before{ padding-top:56.25%; } .wp-embed-responsive .wp-embed-aspect-4-3 .wp-block-embed__wrapper:before{ padding-top:75%; } .wp-embed-responsive .wp-embed-aspect-1-1 .wp-block-embed__wrapper:before{ padding-top:100%; } .wp-embed-responsive .wp-embed-aspect-9-16 .wp-block-embed__wrapper:before{ padding-top:177.77%; } .wp-embed-responsive .wp-embed-aspect-1-2 .wp-block-embed__wrapper:before{ padding-top:200%; } .wp-block-file{ box-sizing:border-box; } .wp-block-file:not(.wp-element-button){ font-size:.8em; } .wp-block-file.aligncenter{ text-align:center; } .wp-block-file.alignright{ text-align:right; } .wp-block-file *+.wp-block-file__button{ margin-right:.75em; } :where(.wp-block-file){ margin-bottom:1.5em; } .wp-block-file__embed{ margin-bottom:1em; } :where(.wp-block-file__button){ border-radius:2em; display:inline-block; padding:.5em 1em; } :where(.wp-block-file__button):is(a):active,:where(.wp-block-file__button):is(a):focus,:where(.wp-block-file__button):is(a):hover,:where(.wp-block-file__button):is(a):visited{ box-shadow:none; color:#fff; opacity:.85; text-decoration:none; } .wp-block-form-input__label{ display:flex; flex-direction:column; gap:.25em; margin-bottom:.5em; width:100%; } .wp-block-form-input__label.is-label-inline{ align-items:center; flex-direction:row; gap:.5em; } .wp-block-form-input__label.is-label-inline .wp-block-form-input__label-content{ margin-bottom:.5em; } .wp-block-form-input__label:has(input[type=checkbox]){ flex-direction:row; width:fit-content; } .wp-block-form-input__label:has(input[type=checkbox]) .wp-block-form-input__label-content{ margin:0; } .wp-block-form-input__label:has(.wp-block-form-input__label-content+input[type=checkbox]){ flex-direction:row-reverse; } .wp-block-form-input__label-content{ width:fit-content; } .wp-block-form-input__input{ font-size:1em; margin-bottom:.5em; padding:0 .5em; } .wp-block-form-input__input[type=date],.wp-block-form-input__input[type=datetime-local],.wp-block-form-input__input[type=datetime],.wp-block-form-input__input[type=email],.wp-block-form-input__input[type=month],.wp-block-form-input__input[type=number],.wp-block-form-input__input[type=password],.wp-block-form-input__input[type=search],.wp-block-form-input__input[type=tel],.wp-block-form-input__input[type=text],.wp-block-form-input__input[type=time],.wp-block-form-input__input[type=url],.wp-block-form-input__input[type=week]{ border:1px solid; line-height:2; min-height:2em; } textarea.wp-block-form-input__input{ min-height:10em; } .blocks-gallery-grid:not(.has-nested-images),.wp-block-gallery:not(.has-nested-images){ display:flex; flex-wrap:wrap; list-style-type:none; margin:0; padding:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item{ display:flex; flex-direction:column; flex-grow:1; justify-content:center; margin:0 0 1em 1em; position:relative; width:calc(50% - 1em); } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n){ margin-left:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figure,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figure{ align-items:flex-end; display:flex; height:100%; justify-content:flex-start; margin:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item img{ display:block; height:auto; max-width:100%; width:auto; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption{ background:linear-gradient(0deg, #000000b3, #0000004d 70%, #0000); bottom:0; box-sizing:border-box; color:#fff; font-size:.8em; margin:0; max-height:100%; overflow:auto; padding:3em .77em .7em; position:absolute; text-align:center; width:100%; z-index:2; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption img{ display:inline; } .blocks-gallery-grid:not(.has-nested-images) figcaption,.wp-block-gallery:not(.has-nested-images) figcaption{ flex-grow:1; } .blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item img{ flex:1; height:100%; object-fit:cover; width:100%; } .blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item{ margin-left:0; width:100%; } @media (min-width:600px){ .blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item{ margin-left:1em; width:calc(33.33333% - .66667em); } .blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item{ margin-left:1em; width:calc(25% - .75em); } .blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item{ margin-left:1em; width:calc(20% - .8em); } .blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item{ margin-left:1em; width:calc(16.66667% - .83333em); } .blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item{ margin-left:1em; width:calc(14.28571% - .85714em); } .blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item{ margin-left:1em; width:calc(12.5% - .875em); } .blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n){ margin-left:0; } } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:last-child,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:last-child{ margin-left:0; } .blocks-gallery-grid:not(.has-nested-images).alignleft,.blocks-gallery-grid:not(.has-nested-images).alignright,.wp-block-gallery:not(.has-nested-images).alignleft,.wp-block-gallery:not(.has-nested-images).alignright{ max-width:420px; width:100%; } .blocks-gallery-grid:not(.has-nested-images).aligncenter .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images).aligncenter .blocks-gallery-item figure{ justify-content:center; } .wp-block-gallery:not(.is-cropped) .blocks-gallery-item{ align-self:flex-start; } figure.wp-block-gallery.has-nested-images{ align-items:normal; } .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image){ margin:0; width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)/2); } .wp-block-gallery.has-nested-images figure.wp-block-image{ box-sizing:border-box; display:flex; flex-direction:column; flex-grow:1; justify-content:center; max-width:100%; position:relative; } .wp-block-gallery.has-nested-images figure.wp-block-image>a,.wp-block-gallery.has-nested-images figure.wp-block-image>div{ flex-direction:column; flex-grow:1; margin:0; } .wp-block-gallery.has-nested-images figure.wp-block-image img{ display:block; height:auto; max-width:100% !important; width:auto; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{ bottom:0; left:0; max-height:100%; position:absolute; right:0; } .wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{ -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); content:""; height:100%; -webkit-mask-image:linear-gradient(0deg, #000 20%, #0000); mask-image:linear-gradient(0deg, #000 20%, #0000); max-height:40%; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption{ background:linear-gradient(0deg, #0006, #0000); box-sizing:border-box; color:#fff; font-size:13px; margin:0; overflow:auto; padding:1em; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-width:thin; text-align:center; text-shadow:0 0 1.5px #000; will-change:transform; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar{ height:12px; width:12px; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-track{ background-color:initial; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover::-webkit-scrollbar-thumb{ background-color:#fffc; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover{ scrollbar-color:#fffc #0000; } @media (hover:none){ .wp-block-gallery.has-nested-images figure.wp-block-image figcaption{ scrollbar-color:#fffc #0000; } } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption img{ display:inline; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption a{ color:inherit; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border img{ box-sizing:border-box; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>a,.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>div,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>a,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>div{ flex:1 1 auto; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded figcaption{ background:none; color:inherit; flex:initial; margin:0; padding:10px 10px 9px; position:relative; text-shadow:none; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border:before,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded:before{ content:none; } .wp-block-gallery.has-nested-images figcaption{ flex-basis:100%; flex-grow:1; text-align:center; } .wp-block-gallery.has-nested-images:not(.is-cropped) figure.wp-block-image:not(#individual-image){ margin-bottom:auto; margin-top:0; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image){ align-self:inherit; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>div:not(.components-drop-zone){ display:flex; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) img{ flex:1 0 0%; height:100%; object-fit:cover; width:100%; } .wp-block-gallery.has-nested-images.columns-1 figure.wp-block-image:not(#individual-image){ width:100%; } @media (min-width:600px){ .wp-block-gallery.has-nested-images.columns-3 figure.wp-block-image:not(#individual-image){ width:calc(33.33333% - var(--wp--style--unstable-gallery-gap, 16px)*.66667); } .wp-block-gallery.has-nested-images.columns-4 figure.wp-block-image:not(#individual-image){ width:calc(25% - var(--wp--style--unstable-gallery-gap, 16px)*.75); } .wp-block-gallery.has-nested-images.columns-5 figure.wp-block-image:not(#individual-image){ width:calc(20% - var(--wp--style--unstable-gallery-gap, 16px)*.8); } .wp-block-gallery.has-nested-images.columns-6 figure.wp-block-image:not(#individual-image){ width:calc(16.66667% - var(--wp--style--unstable-gallery-gap, 16px)*.83333); } .wp-block-gallery.has-nested-images.columns-7 figure.wp-block-image:not(#individual-image){ width:calc(14.28571% - var(--wp--style--unstable-gallery-gap, 16px)*.85714); } .wp-block-gallery.has-nested-images.columns-8 figure.wp-block-image:not(#individual-image){ width:calc(12.5% - var(--wp--style--unstable-gallery-gap, 16px)*.875); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image){ width:calc(33.33% - var(--wp--style--unstable-gallery-gap, 16px)*.66667); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2),.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2)~figure.wp-block-image:not(#individual-image){ width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)*.5); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:last-child{ width:100%; } } .wp-block-gallery.has-nested-images.alignleft,.wp-block-gallery.has-nested-images.alignright{ max-width:420px; width:100%; } .wp-block-gallery.has-nested-images.aligncenter{ justify-content:center; } .wp-block-group{ box-sizing:border-box; } :where(.wp-block-group.wp-block-group-is-layout-constrained){ position:relative; } h1.has-background,h2.has-background,h3.has-background,h4.has-background,h5.has-background,h6.has-background{ padding:1.25em 2.375em; } h1.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h1.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h2.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h2.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h3.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h3.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h4.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h4.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h5.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h5.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h6.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h6.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]){ rotate:180deg; } .wp-block-image>a,.wp-block-image>figure>a{ display:inline-block; } .wp-block-image img{ box-sizing:border-box; height:auto; max-width:100%; vertical-align:bottom; } @media not (prefers-reduced-motion){ .wp-block-image img.hide{ visibility:hidden; } .wp-block-image img.show{ animation:show-content-image .4s; } } .wp-block-image[style*=border-radius] img,.wp-block-image[style*=border-radius]>a{ border-radius:inherit; } .wp-block-image.has-custom-border img{ box-sizing:border-box; } .wp-block-image.aligncenter{ text-align:center; } .wp-block-image.alignfull>a,.wp-block-image.alignwide>a{ width:100%; } .wp-block-image.alignfull img,.wp-block-image.alignwide img{ height:auto; width:100%; } .wp-block-image .aligncenter,.wp-block-image .alignleft,.wp-block-image .alignright,.wp-block-image.aligncenter,.wp-block-image.alignleft,.wp-block-image.alignright{ display:table; } .wp-block-image .aligncenter>figcaption,.wp-block-image .alignleft>figcaption,.wp-block-image .alignright>figcaption,.wp-block-image.aligncenter>figcaption,.wp-block-image.alignleft>figcaption,.wp-block-image.alignright>figcaption{ caption-side:bottom; display:table-caption; } .wp-block-image .alignleft{ float:left; margin:.5em 1em .5em 0; } .wp-block-image .alignright{ float:right; margin:.5em 0 .5em 1em; } .wp-block-image .aligncenter{ margin-left:auto; margin-right:auto; } .wp-block-image :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-image.is-style-circle-mask img{ border-radius:9999px; } @supports ((-webkit-mask-image:none) or (mask-image:none)) or (-webkit-mask-image:none){ .wp-block-image.is-style-circle-mask img{ border-radius:0; -webkit-mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>'); mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>'); mask-mode:alpha; -webkit-mask-position:center; mask-position:center; -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat; -webkit-mask-size:contain; mask-size:contain; } } :root :where(.wp-block-image.is-style-rounded img,.wp-block-image .is-style-rounded img){ border-radius:9999px; } .wp-block-image figure{ margin:0; } .wp-lightbox-container{ display:flex; flex-direction:column; position:relative; } .wp-lightbox-container img{ cursor:zoom-in; } .wp-lightbox-container img:hover+button{ opacity:1; } .wp-lightbox-container button{ align-items:center; -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background-color:#5a5a5a40; border:none; border-radius:4px; cursor:zoom-in; display:flex; height:20px; justify-content:center; left:16px; opacity:0; padding:0; position:absolute; text-align:center; top:16px; width:20px; z-index:100; } @media not (prefers-reduced-motion){ .wp-lightbox-container button{ transition:opacity .2s ease; } } .wp-lightbox-container button:focus-visible{ outline:3px auto #5a5a5a40; outline:3px auto -webkit-focus-ring-color; outline-offset:3px; } .wp-lightbox-container button:hover{ cursor:pointer; opacity:1; } .wp-lightbox-container button:focus{ opacity:1; } .wp-lightbox-container button:focus,.wp-lightbox-container button:hover,.wp-lightbox-container button:not(:hover):not(:active):not(.has-background){ background-color:#5a5a5a40; border:none; } .wp-lightbox-overlay{ box-sizing:border-box; cursor:zoom-out; height:100vh; overflow:hidden; position:fixed; right:0; top:0; visibility:hidden; width:100%; z-index:100000; } .wp-lightbox-overlay .close-button{ align-items:center; cursor:pointer; display:flex; justify-content:center; left:calc(env(safe-area-inset-left) + 16px); min-height:40px; min-width:40px; padding:0; position:absolute; top:calc(env(safe-area-inset-top) + 16px); z-index:5000000; } .wp-lightbox-overlay .close-button:focus,.wp-lightbox-overlay .close-button:hover,.wp-lightbox-overlay .close-button:not(:hover):not(:active):not(.has-background){ background:none; border:none; } .wp-lightbox-overlay .lightbox-image-container{ height:var(--wp--lightbox-container-height); overflow:hidden; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); transform-origin:top right; width:var(--wp--lightbox-container-width); z-index:9999999999; } .wp-lightbox-overlay .wp-block-image{ align-items:center; box-sizing:border-box; display:flex; height:100%; justify-content:center; margin:0; position:relative; transform-origin:100% 0; width:100%; z-index:3000000; } .wp-lightbox-overlay .wp-block-image img{ height:var(--wp--lightbox-image-height); min-height:var(--wp--lightbox-image-height); min-width:var(--wp--lightbox-image-width); width:var(--wp--lightbox-image-width); } .wp-lightbox-overlay .wp-block-image figcaption{ display:none; } .wp-lightbox-overlay button{ background:none; border:none; } .wp-lightbox-overlay .scrim{ background-color:#fff; height:100%; opacity:.9; position:absolute; width:100%; z-index:2000000; } .wp-lightbox-overlay.active{ visibility:visible; } @media not (prefers-reduced-motion){ .wp-lightbox-overlay.active{ animation:turn-on-visibility .25s both; } .wp-lightbox-overlay.active img{ animation:turn-on-visibility .35s both; } .wp-lightbox-overlay.show-closing-animation:not(.active){ animation:turn-off-visibility .35s both; } .wp-lightbox-overlay.show-closing-animation:not(.active) img{ animation:turn-off-visibility .25s both; } .wp-lightbox-overlay.zoom.active{ animation:none; opacity:1; visibility:visible; } .wp-lightbox-overlay.zoom.active .lightbox-image-container{ animation:lightbox-zoom-in .4s; } .wp-lightbox-overlay.zoom.active .lightbox-image-container img{ animation:none; } .wp-lightbox-overlay.zoom.active .scrim{ animation:turn-on-visibility .4s forwards; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active){ animation:none; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container{ animation:lightbox-zoom-out .4s; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container img{ animation:none; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .scrim{ animation:turn-off-visibility .4s forwards; } } @keyframes show-content-image{ 0%{ visibility:hidden; } 99%{ visibility:hidden; } to{ visibility:visible; } } @keyframes turn-on-visibility{ 0%{ opacity:0; } to{ opacity:1; } } @keyframes turn-off-visibility{ 0%{ opacity:1; visibility:visible; } 99%{ opacity:0; visibility:visible; } to{ opacity:0; visibility:hidden; } } @keyframes lightbox-zoom-in{ 0%{ transform:translate(calc(((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position))*-1), calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale)); } to{ transform:translate(50%, -50%) scale(1); } } @keyframes lightbox-zoom-out{ 0%{ transform:translate(50%, -50%) scale(1); visibility:visible; } 99%{ visibility:visible; } to{ transform:translate(calc(((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position))*-1), calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale)); visibility:hidden; } } ol.wp-block-latest-comments{ box-sizing:border-box; margin-right:0; } :where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment)){ line-height:1.1; } :where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment-excerpt p)){ line-height:1.8; } .has-dates :where(.wp-block-latest-comments:not([style*=line-height])),.has-excerpts :where(.wp-block-latest-comments:not([style*=line-height])){ line-height:1.5; } .wp-block-latest-comments .wp-block-latest-comments{ padding-right:0; } .wp-block-latest-comments__comment{ list-style:none; margin-bottom:1em; } .has-avatars .wp-block-latest-comments__comment{ list-style:none; min-height:2.25em; } .has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-excerpt,.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-meta{ margin-right:3.25em; } .wp-block-latest-comments__comment-excerpt p{ font-size:.875em; margin:.36em 0 1.4em; } .wp-block-latest-comments__comment-date{ display:block; font-size:.75em; } .wp-block-latest-comments .avatar,.wp-block-latest-comments__comment-avatar{ border-radius:1.5em; display:block; float:right; height:2.5em; margin-left:.75em; width:2.5em; } .wp-block-latest-comments[class*=-font-size] a,.wp-block-latest-comments[style*=font-size] a{ font-size:inherit; } .wp-block-latest-posts{ box-sizing:border-box; } .wp-block-latest-posts.alignleft{ margin-right:2em; } .wp-block-latest-posts.alignright{ margin-left:2em; } .wp-block-latest-posts.wp-block-latest-posts__list{ list-style:none; } .wp-block-latest-posts.wp-block-latest-posts__list li{ clear:both; overflow-wrap:break-word; } .wp-block-latest-posts.is-grid{ display:flex; flex-wrap:wrap; } .wp-block-latest-posts.is-grid li{ margin:0 0 1.25em 1.25em; width:100%; } @media (min-width:600px){ .wp-block-latest-posts.columns-2 li{ width:calc(50% - .625em); } .wp-block-latest-posts.columns-2 li:nth-child(2n){ margin-left:0; } .wp-block-latest-posts.columns-3 li{ width:calc(33.33333% - .83333em); } .wp-block-latest-posts.columns-3 li:nth-child(3n){ margin-left:0; } .wp-block-latest-posts.columns-4 li{ width:calc(25% - .9375em); } .wp-block-latest-posts.columns-4 li:nth-child(4n){ margin-left:0; } .wp-block-latest-posts.columns-5 li{ width:calc(20% - 1em); } .wp-block-latest-posts.columns-5 li:nth-child(5n){ margin-left:0; } .wp-block-latest-posts.columns-6 li{ width:calc(16.66667% - 1.04167em); } .wp-block-latest-posts.columns-6 li:nth-child(6n){ margin-left:0; } } :root :where(.wp-block-latest-posts.is-grid){ padding:0; } :root :where(.wp-block-latest-posts.wp-block-latest-posts__list){ padding-right:0; } .wp-block-latest-posts__post-author,.wp-block-latest-posts__post-date{ display:block; font-size:.8125em; } .wp-block-latest-posts__post-excerpt,.wp-block-latest-posts__post-full-content{ margin-bottom:1em; margin-top:.5em; } .wp-block-latest-posts__featured-image a{ display:inline-block; } .wp-block-latest-posts__featured-image img{ height:auto; max-width:100%; width:auto; } .wp-block-latest-posts__featured-image.alignleft{ float:left; margin-right:1em; } .wp-block-latest-posts__featured-image.alignright{ float:right; margin-left:1em; } .wp-block-latest-posts__featured-image.aligncenter{ margin-bottom:1em; text-align:center; } ol,ul{ box-sizing:border-box; } :root :where(.wp-block-list.has-background){ padding:1.25em 2.375em; } .wp-block-loginout,.wp-block-media-text{ box-sizing:border-box; } .wp-block-media-text{ direction:ltr; display:grid; grid-template-columns:50% 1fr; grid-template-rows:auto; } .wp-block-media-text.has-media-on-the-right{ grid-template-columns:1fr 50%; } .wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__media{ align-self:start; } .wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__media,.wp-block-media-text>.wp-block-media-text__content,.wp-block-media-text>.wp-block-media-text__media{ align-self:center; } .wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__media{ align-self:end; } .wp-block-media-text>.wp-block-media-text__media{ grid-column:1; grid-row:1; margin:0; } .wp-block-media-text>.wp-block-media-text__content{ direction:rtl; grid-column:2; grid-row:1; padding:0 8%; word-break:break-word; } .wp-block-media-text.has-media-on-the-right>.wp-block-media-text__media{ grid-column:2; grid-row:1; } .wp-block-media-text.has-media-on-the-right>.wp-block-media-text__content{ grid-column:1; grid-row:1; } .wp-block-media-text__media a{ display:block; } .wp-block-media-text__media img,.wp-block-media-text__media video{ height:auto; max-width:unset; vertical-align:middle; width:100%; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media{ background-size:cover; height:100%; min-height:250px; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media>a{ display:block; height:100%; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media img{ height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; clip:rect(0, 0, 0, 0); border:0; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media{ height:100%; min-height:250px; position:relative; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media>a{ display:block; height:100%; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media img{ height:100%; object-fit:cover; position:absolute; width:100%; } @media (max-width:600px){ .wp-block-media-text.is-stacked-on-mobile{ grid-template-columns:100% !important; } .wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__media{ grid-column:1; grid-row:1; } .wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__content{ grid-column:1; grid-row:2; } } .wp-block-navigation{ position:relative; --navigation-layout-justification-setting:flex-start; --navigation-layout-direction:row; --navigation-layout-wrap:wrap; --navigation-layout-justify:flex-start; --navigation-layout-align:center; } .wp-block-navigation ul{ margin-bottom:0; margin-right:0; margin-top:0; padding-right:0; } .wp-block-navigation ul,.wp-block-navigation ul li{ list-style:none; padding:0; } .wp-block-navigation .wp-block-navigation-item{ align-items:center; display:flex; position:relative; } .wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty{ display:none; } .wp-block-navigation .wp-block-navigation-item__content{ display:block; } .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content{ color:inherit; } .wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:focus{ text-decoration:underline; } .wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:focus{ text-decoration:line-through; } .wp-block-navigation :where(a),.wp-block-navigation :where(a:active),.wp-block-navigation :where(a:focus){ text-decoration:none; } .wp-block-navigation .wp-block-navigation__submenu-icon{ align-self:center; background-color:inherit; border:none; color:currentColor; display:inline-block; font-size:inherit; height:.6em; line-height:0; margin-right:.25em; padding:0; width:.6em; } .wp-block-navigation .wp-block-navigation__submenu-icon svg{ display:inline-block; stroke:currentColor; height:inherit; margin-top:.075em; width:inherit; } .wp-block-navigation.is-vertical{ --navigation-layout-direction:column; --navigation-layout-justify:initial; --navigation-layout-align:flex-start; } .wp-block-navigation.no-wrap{ --navigation-layout-wrap:nowrap; } .wp-block-navigation.items-justified-center{ --navigation-layout-justification-setting:center; --navigation-layout-justify:center; } .wp-block-navigation.items-justified-center.is-vertical{ --navigation-layout-align:center; } .wp-block-navigation.items-justified-right{ --navigation-layout-justification-setting:flex-end; --navigation-layout-justify:flex-end; } .wp-block-navigation.items-justified-right.is-vertical{ --navigation-layout-align:flex-end; } .wp-block-navigation.items-justified-space-between{ --navigation-layout-justification-setting:space-between; --navigation-layout-justify:space-between; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ align-items:normal; background-color:inherit; color:inherit; display:flex; flex-direction:column; height:0; opacity:0; overflow:hidden; position:absolute; right:-1px; top:100%; visibility:hidden; width:0; z-index:2; } @media not (prefers-reduced-motion){ .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ transition:opacity .1s linear; } } .wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content{ display:flex; flex-grow:1; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content .wp-block-navigation__submenu-icon{ margin-left:0; margin-right:auto; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content{ margin:0; } @media (min-width:782px){ .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ right:100%; top:-1px; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{ background:#0000; content:""; display:block; height:100%; left:100%; position:absolute; width:.5em; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon{ margin-left:.25em; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon svg{ transform:rotate(90deg); } } .wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true]~.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):hover>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):not(.open-on-hover-click):focus-within>.wp-block-navigation__submenu-container{ height:auto; min-width:200px; opacity:1; overflow:visible; visibility:visible; width:auto; } .wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container{ right:0; top:100%; } @media (min-width:782px){ .wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ right:100%; top:0; } } .wp-block-navigation-submenu{ display:flex; position:relative; } .wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{ stroke:currentColor; } button.wp-block-navigation-item__content{ background-color:initial; border:none; color:currentColor; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-align:right; text-transform:inherit; } .wp-block-navigation-submenu__toggle{ cursor:pointer; } .wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle{ padding-left:.85em; padding-right:0; } .wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle+.wp-block-navigation__submenu-icon{ margin-right:-.6em; pointer-events:none; } .wp-block-navigation-item.open-on-click button.wp-block-navigation-item__content:not(.wp-block-navigation-submenu__toggle){ padding:0; } .wp-block-navigation .wp-block-page-list,.wp-block-navigation__container,.wp-block-navigation__responsive-close,.wp-block-navigation__responsive-container,.wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-dialog{ gap:inherit; } :where(.wp-block-navigation.has-background .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation.has-background .wp-block-navigation-submenu a:not(.wp-element-button)){ padding:.5em 1em; } :where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu button.wp-block-navigation-item__content),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-pages-list__item button.wp-block-navigation-item__content){ padding:.5em 1em; } .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container{ left:0; right:auto; } .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:-1px; right:-1px; } @media (min-width:782px){ .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:100%; right:auto; } } .wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container{ background-color:#fff; border:1px solid #00000026; } .wp-block-navigation.has-background .wp-block-navigation__submenu-container{ background-color:inherit; } .wp-block-navigation:not(.has-text-color) .wp-block-navigation__submenu-container{ color:#000; } .wp-block-navigation__container{ align-items:var(--navigation-layout-align, initial); display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); list-style:none; margin:0; padding-right:0; } .wp-block-navigation__container .is-responsive{ display:none; } .wp-block-navigation__container:only-child,.wp-block-page-list:only-child{ flex-grow:1; } @keyframes overlay-menu__fade-in-animation{ 0%{ opacity:0; transform:translateY(.5em); } to{ opacity:1; transform:translateY(0); } } .wp-block-navigation__responsive-container{ bottom:0; display:none; left:0; position:fixed; right:0; top:0; } .wp-block-navigation__responsive-container :where(.wp-block-navigation-item a){ color:inherit; } .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content{ align-items:var(--navigation-layout-align, initial); display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); } .wp-block-navigation__responsive-container:not(.is-menu-open.is-menu-open){ background-color:inherit !important; color:inherit !important; } .wp-block-navigation__responsive-container.is-menu-open{ background-color:inherit; display:flex; flex-direction:column; overflow:auto; padding:clamp(1rem, var(--wp--style--root--padding-top), 20rem) clamp(1rem, var(--wp--style--root--padding-left), 20rem) clamp(1rem, var(--wp--style--root--padding-bottom), 20rem) clamp(1rem, var(--wp--style--root--padding-right), 20rem); z-index:100000; } @media not (prefers-reduced-motion){ .wp-block-navigation__responsive-container.is-menu-open{ animation:overlay-menu__fade-in-animation .1s ease-out; animation-fill-mode:forwards; } } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content{ align-items:var(--navigation-layout-justification-setting, inherit); display:flex; flex-direction:column; flex-wrap:nowrap; overflow:visible; padding-top:calc(2rem + 24px); } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{ justify-content:flex-start; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon{ display:none; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container{ border:none; height:auto; min-width:200px; opacity:1; overflow:initial; padding-left:2rem; padding-right:2rem; position:static; visibility:visible; width:auto; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{ gap:inherit; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{ padding-top:var(--wp--style--block-gap, 2em); } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content{ padding:0; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{ align-items:var(--navigation-layout-justification-setting, initial); display:flex; flex-direction:column; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list{ background:#0000 !important; color:inherit !important; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{ left:auto; right:auto; } @media (min-width:600px){ .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){ background-color:inherit; display:block; position:relative; width:100%; z-index:auto; } .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close{ display:none; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{ right:0; } } .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open{ background-color:#fff; } .wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open{ color:#000; } .wp-block-navigation__toggle_button_label{ font-size:1rem; font-weight:700; } .wp-block-navigation__responsive-container-close,.wp-block-navigation__responsive-container-open{ background:#0000; border:none; color:currentColor; cursor:pointer; margin:0; padding:0; text-transform:inherit; vertical-align:middle; } .wp-block-navigation__responsive-container-close svg,.wp-block-navigation__responsive-container-open svg{ fill:currentColor; display:block; height:24px; pointer-events:none; width:24px; } .wp-block-navigation__responsive-container-open{ display:flex; } .wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{ font-family:inherit; font-size:inherit; font-weight:inherit; } @media (min-width:600px){ .wp-block-navigation__responsive-container-open:not(.always-shown){ display:none; } } .wp-block-navigation__responsive-container-close{ left:0; position:absolute; top:0; z-index:2; } .wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close{ font-family:inherit; font-size:inherit; font-weight:inherit; } .wp-block-navigation__responsive-close{ width:100%; } .has-modal-open .wp-block-navigation__responsive-close{ margin-left:auto; margin-right:auto; max-width:var(--wp--style--global--wide-size, 100%); } .wp-block-navigation__responsive-close:focus{ outline:none; } .is-menu-open .wp-block-navigation__responsive-close,.is-menu-open .wp-block-navigation__responsive-container-content,.is-menu-open .wp-block-navigation__responsive-dialog{ box-sizing:border-box; } .wp-block-navigation__responsive-dialog{ position:relative; } .has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{ margin-top:46px; } @media (min-width:782px){ .has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{ margin-top:32px; } } html.has-modal-open{ overflow:hidden; } .wp-block-navigation .wp-block-navigation-item__label{ overflow-wrap:break-word; } .wp-block-navigation .wp-block-navigation-item__description{ display:none; } .link-ui-tools{ border-top:1px solid #f0f0f0; padding:8px; } .link-ui-block-inserter{ padding-top:8px; } .link-ui-block-inserter__back{ margin-right:8px; text-transform:uppercase; } .wp-block-navigation .wp-block-page-list{ align-items:var(--navigation-layout-align, initial); background-color:inherit; display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); } .wp-block-navigation .wp-block-navigation-item{ background-color:inherit; } .wp-block-page-list{ box-sizing:border-box; } .is-small-text{ font-size:.875em; } .is-regular-text{ font-size:1em; } .is-large-text{ font-size:2.25em; } .is-larger-text{ font-size:3em; } .has-drop-cap:not(:focus):first-letter{ float:right; font-size:8.4em; font-style:normal; font-weight:100; line-height:.68; margin:.05em 0 0 .1em; text-transform:uppercase; } body.rtl .has-drop-cap:not(:focus):first-letter{ float:none; margin-right:.1em; } p.has-drop-cap.has-background{ overflow:hidden; } :root :where(p.has-background){ padding:1.25em 2.375em; } :where(p.has-text-color:not(.has-link-color)) a{ color:inherit; } p.has-text-align-left[style*="writing-mode:vertical-lr"],p.has-text-align-right[style*="writing-mode:vertical-rl"]{ rotate:180deg; } .wp-block-post-author{ box-sizing:border-box; display:flex; flex-wrap:wrap; } .wp-block-post-author__byline{ font-size:.5em; margin-bottom:0; margin-top:0; width:100%; } .wp-block-post-author__avatar{ margin-left:1em; } .wp-block-post-author__bio{ font-size:.7em; margin-bottom:.7em; } .wp-block-post-author__content{ flex-basis:0; flex-grow:1; } .wp-block-post-author__name{ margin:0; } .wp-block-post-author-biography{ box-sizing:border-box; } :where(.wp-block-post-comments-form) input:not([type=submit]),:where(.wp-block-post-comments-form) textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } :where(.wp-block-post-comments-form) input:where(:not([type=submit]):not([type=checkbox])),:where(.wp-block-post-comments-form) textarea{ padding:calc(.667em + 2px); } .wp-block-post-comments-form{ box-sizing:border-box; } .wp-block-post-comments-form[style*=font-weight] :where(.comment-reply-title){ font-weight:inherit; } .wp-block-post-comments-form[style*=font-family] :where(.comment-reply-title){ font-family:inherit; } .wp-block-post-comments-form[class*=-font-size] :where(.comment-reply-title),.wp-block-post-comments-form[style*=font-size] :where(.comment-reply-title){ font-size:inherit; } .wp-block-post-comments-form[style*=line-height] :where(.comment-reply-title){ line-height:inherit; } .wp-block-post-comments-form[style*=font-style] :where(.comment-reply-title){ font-style:inherit; } .wp-block-post-comments-form[style*=letter-spacing] :where(.comment-reply-title){ letter-spacing:inherit; } .wp-block-post-comments-form :where(input[type=submit]){ box-shadow:none; cursor:pointer; display:inline-block; overflow-wrap:break-word; text-align:center; } .wp-block-post-comments-form .comment-form input:not([type=submit]):not([type=checkbox]):not([type=hidden]),.wp-block-post-comments-form .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-post-comments-form .comment-form-author label,.wp-block-post-comments-form .comment-form-email label,.wp-block-post-comments-form .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-post-comments-form .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-post-comments-form .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-post-comments-form .comment-reply-title{ margin-bottom:0; } .wp-block-post-comments-form .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-right:.5em; } .wp-block-post-comments-count{ box-sizing:border-box; } .wp-block-post-content{ display:flow-root; } .wp-block-post-comments-link,.wp-block-post-date{ box-sizing:border-box; } :where(.wp-block-post-excerpt){ box-sizing:border-box; margin-bottom:var(--wp--style--block-gap); margin-top:var(--wp--style--block-gap); } .wp-block-post-excerpt__excerpt{ margin-bottom:0; margin-top:0; } .wp-block-post-excerpt__more-text{ margin-bottom:0; margin-top:var(--wp--style--block-gap); } .wp-block-post-excerpt__more-link{ display:inline-block; } .wp-block-post-featured-image{ margin-left:0; margin-right:0; } .wp-block-post-featured-image a{ display:block; height:100%; } .wp-block-post-featured-image :where(img){ box-sizing:border-box; height:auto; max-width:100%; vertical-align:bottom; width:100%; } .wp-block-post-featured-image.alignfull img,.wp-block-post-featured-image.alignwide img{ width:100%; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim{ background-color:#000; inset:0; position:absolute; } .wp-block-post-featured-image{ position:relative; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-gradient{ background-color:initial; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-0{ opacity:0; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-10{ opacity:.1; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-20{ opacity:.2; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-30{ opacity:.3; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-40{ opacity:.4; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-50{ opacity:.5; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-60{ opacity:.6; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-70{ opacity:.7; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-80{ opacity:.8; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-90{ opacity:.9; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-100{ opacity:1; } .wp-block-post-featured-image:where(.alignleft,.alignright){ width:100%; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous{ display:inline-block; margin-left:1ch; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next{ display:inline-block; margin-right:1ch; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-post-navigation-link.has-text-align-left[style*="writing-mode: vertical-lr"],.wp-block-post-navigation-link.has-text-align-right[style*="writing-mode: vertical-rl"]{ rotate:180deg; } .wp-block-post-terms{ box-sizing:border-box; } .wp-block-post-terms .wp-block-post-terms__separator{ white-space:pre-wrap; } .wp-block-post-time-to-read,.wp-block-post-title{ box-sizing:border-box; } .wp-block-post-title{ word-break:break-word; } .wp-block-post-title :where(a){ display:inline-block; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-decoration:inherit; } .wp-block-post-author-name,.wp-block-preformatted{ box-sizing:border-box; } .wp-block-preformatted{ white-space:pre-wrap; } :where(.wp-block-preformatted.has-background){ padding:1.25em 2.375em; } .wp-block-pullquote{ box-sizing:border-box; margin:0 0 1em; overflow-wrap:break-word; padding:4em 0; text-align:center; } .wp-block-pullquote blockquote,.wp-block-pullquote cite,.wp-block-pullquote p{ color:inherit; } .wp-block-pullquote blockquote{ margin:0; } .wp-block-pullquote p{ margin-top:0; } .wp-block-pullquote p:last-child{ margin-bottom:0; } .wp-block-pullquote.alignleft,.wp-block-pullquote.alignright{ max-width:420px; } .wp-block-pullquote cite,.wp-block-pullquote footer{ position:relative; } .wp-block-pullquote .has-text-color a{ color:inherit; } .wp-block-pullquote.has-text-align-left blockquote{ text-align:right; } .wp-block-pullquote.has-text-align-right blockquote{ text-align:left; } .wp-block-pullquote.has-text-align-center blockquote{ text-align:center; } .wp-block-pullquote.is-style-solid-color{ border:none; } .wp-block-pullquote.is-style-solid-color blockquote{ margin-left:auto; margin-right:auto; max-width:60%; } .wp-block-pullquote.is-style-solid-color blockquote p{ font-size:2em; margin-bottom:0; margin-top:0; } .wp-block-pullquote.is-style-solid-color blockquote cite{ font-style:normal; text-transform:none; } .wp-block-pullquote cite{ color:inherit; display:block; } .wp-block-post-template{ box-sizing:border-box; list-style:none; margin-bottom:0; margin-top:0; max-width:100%; padding:0; } .wp-block-post-template.is-flex-container{ display:flex; flex-direction:row; flex-wrap:wrap; gap:1.25em; } .wp-block-post-template.is-flex-container>li{ margin:0; width:100%; } @media (min-width:600px){ .wp-block-post-template.is-flex-container.is-flex-container.columns-2>li{ width:calc(50% - .625em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-3>li{ width:calc(33.33333% - .83333em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-4>li{ width:calc(25% - .9375em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-5>li{ width:calc(20% - 1em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-6>li{ width:calc(16.66667% - 1.04167em); } } @media (max-width:600px){ .wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid{ grid-template-columns:1fr; } } .wp-block-post-template-is-layout-constrained>li>.alignright,.wp-block-post-template-is-layout-flow>li>.alignright{ float:left; margin-inline-end:0; margin-inline-start:2em; } .wp-block-post-template-is-layout-constrained>li>.alignleft,.wp-block-post-template-is-layout-flow>li>.alignleft{ float:right; margin-inline-end:2em; margin-inline-start:0; } .wp-block-post-template-is-layout-constrained>li>.aligncenter,.wp-block-post-template-is-layout-flow>li>.aligncenter{ margin-inline-end:auto; margin-inline-start:auto; } .wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-next:last-of-type{ margin-inline-start:auto; } .wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-previous:first-child{ margin-inline-end:auto; } .wp-block-query-pagination .wp-block-query-pagination-previous-arrow{ display:inline-block; margin-left:1ch; } .wp-block-query-pagination .wp-block-query-pagination-previous-arrow:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-query-pagination .wp-block-query-pagination-next-arrow{ display:inline-block; margin-right:1ch; } .wp-block-query-pagination .wp-block-query-pagination-next-arrow:not(.is-arrow-chevron){ transform:scaleX(-1);; } .wp-block-query-pagination.aligncenter{ justify-content:center; } .wp-block-query-title,.wp-block-query-total,.wp-block-quote{ box-sizing:border-box; } .wp-block-quote{ overflow-wrap:break-word; } .wp-block-quote.is-large:where(:not(.is-style-plain)),.wp-block-quote.is-style-large:where(:not(.is-style-plain)){ margin-bottom:1em; padding:0 1em; } .wp-block-quote.is-large:where(:not(.is-style-plain)) p,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) p{ font-size:1.5em; font-style:italic; line-height:1.6; } .wp-block-quote.is-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-large:where(:not(.is-style-plain)) footer,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) footer{ font-size:1.125em; text-align:left; } .wp-block-quote>cite{ display:block; } .wp-block-read-more{ display:block; width:fit-content; } .wp-block-read-more:where(:not([style*=text-decoration])){ text-decoration:none; } .wp-block-read-more:where(:not([style*=text-decoration])):active,.wp-block-read-more:where(:not([style*=text-decoration])):focus{ text-decoration:none; } ul.wp-block-rss.alignleft{ margin-right:2em; } ul.wp-block-rss.alignright{ margin-left:2em; } ul.wp-block-rss.is-grid{ display:flex; flex-wrap:wrap; padding:0; } ul.wp-block-rss.is-grid li{ margin:0 0 1em 1em; width:100%; } @media (min-width:600px){ ul.wp-block-rss.columns-2 li{ width:calc(50% - 1em); } ul.wp-block-rss.columns-3 li{ width:calc(33.33333% - 1em); } ul.wp-block-rss.columns-4 li{ width:calc(25% - 1em); } ul.wp-block-rss.columns-5 li{ width:calc(20% - 1em); } ul.wp-block-rss.columns-6 li{ width:calc(16.66667% - 1em); } } .wp-block-rss__item-author,.wp-block-rss__item-publish-date{ display:block; font-size:.8125em; } .wp-block-rss{ box-sizing:border-box; list-style:none; padding:0; } .wp-block-search__button{ margin-right:10px; word-break:normal; } .wp-block-search__button.has-icon{ line-height:0; } .wp-block-search__button svg{ height:1.25em; min-height:24px; min-width:24px; width:1.25em; fill:currentColor; vertical-align:text-bottom; } :where(.wp-block-search__button){ border:1px solid #ccc; padding:6px 10px; } .wp-block-search__inside-wrapper{ display:flex; flex:auto; flex-wrap:nowrap; max-width:100%; } .wp-block-search__label{ width:100%; } .wp-block-search__input{ appearance:none; border:1px solid #949494; flex-grow:1; margin-left:0; margin-right:0; min-width:3rem; padding:8px; text-decoration:unset !important; } .wp-block-search.wp-block-search__button-only .wp-block-search__button{ box-sizing:border-box; display:flex; flex-shrink:0; justify-content:center; margin-right:0; max-width:100%; } .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{ min-width:0 !important; transition-property:width; } .wp-block-search.wp-block-search__button-only .wp-block-search__input{ flex-basis:100%; transition-duration:.3s; } .wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden,.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__inside-wrapper{ overflow:hidden; } .wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__input{ border-left-width:0 !important; border-right-width:0 !important; flex-basis:0; flex-grow:0; margin:0; min-width:0 !important; padding-left:0 !important; padding-right:0 !important; width:0 !important; } :where(.wp-block-search__input){ font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-transform:inherit; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper){ border:1px solid #949494; box-sizing:border-box; padding:4px; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input{ border:none; border-radius:0; padding:0 4px; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input:focus{ outline:none; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) :where(.wp-block-search__button){ padding:4px 8px; } .wp-block-search.aligncenter .wp-block-search__inside-wrapper{ margin:auto; } .wp-block[data-align=right] .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{ float:left; } .wp-block-separator{ border:none; border-top:2px solid; } :root :where(.wp-block-separator.is-style-dots){ height:auto; line-height:1; text-align:center; } :root :where(.wp-block-separator.is-style-dots):before{ color:currentColor; content:"···"; font-family:serif; font-size:1.5em; letter-spacing:2em; padding-left:2em; } .wp-block-separator.is-style-dots{ background:none !important; border:none !important; } .wp-block-site-logo{ box-sizing:border-box; line-height:0; } .wp-block-site-logo a{ display:inline-block; line-height:0; } .wp-block-site-logo.is-default-size img{ height:auto; width:120px; } .wp-block-site-logo img{ height:auto; max-width:100%; } .wp-block-site-logo a,.wp-block-site-logo img{ border-radius:inherit; } .wp-block-site-logo.aligncenter{ margin-left:auto; margin-right:auto; text-align:center; } :root :where(.wp-block-site-logo.is-style-rounded){ border-radius:9999px; } .wp-block-site-tagline,.wp-block-site-title{ box-sizing:border-box; } .wp-block-site-title :where(a){ color:inherit; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-decoration:inherit; } .wp-block-social-links{ background:none; box-sizing:border-box; margin-right:0; padding-left:0; padding-right:0; text-indent:0; } .wp-block-social-links .wp-social-link a,.wp-block-social-links .wp-social-link a:hover{ border-bottom:0; box-shadow:none; text-decoration:none; } .wp-block-social-links .wp-social-link svg{ height:1em; width:1em; } .wp-block-social-links .wp-social-link span:not(.screen-reader-text){ font-size:.65em; margin-left:.5em; margin-right:.5em; } .wp-block-social-links.has-small-icon-size{ font-size:16px; } .wp-block-social-links,.wp-block-social-links.has-normal-icon-size{ font-size:24px; } .wp-block-social-links.has-large-icon-size{ font-size:36px; } .wp-block-social-links.has-huge-icon-size{ font-size:48px; } .wp-block-social-links.aligncenter{ display:flex; justify-content:center; } .wp-block-social-links.alignright{ justify-content:flex-end; } .wp-block-social-link{ border-radius:9999px; display:block; height:auto; } @media not (prefers-reduced-motion){ .wp-block-social-link{ transition:transform .1s ease; } } .wp-block-social-link a{ align-items:center; display:flex; line-height:0; } .wp-block-social-link:hover{ transform:scale(1.1); } .wp-block-social-links .wp-block-social-link.wp-social-link{ display:inline-block; margin:0; padding:0; } .wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor svg,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:active,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:hover,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:visited{ color:currentColor; fill:currentColor; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link{ background-color:#f0f0f0; color:#444; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-amazon{ background-color:#f90; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bandcamp{ background-color:#1ea0c3; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-behance{ background-color:#0757fe; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bluesky{ background-color:#0a7aff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-codepen{ background-color:#1e1f26; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-deviantart{ background-color:#02e49b; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-discord{ background-color:#5865f2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dribbble{ background-color:#e94c89; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dropbox{ background-color:#4280ff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-etsy{ background-color:#f45800; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-facebook{ background-color:#0866ff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-fivehundredpx{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-flickr{ background-color:#0461dd; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-foursquare{ background-color:#e65678; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-github{ background-color:#24292d; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-goodreads{ background-color:#eceadd; color:#382110; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-google{ background-color:#ea4434; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-gravatar{ background-color:#1d4fc4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-instagram{ background-color:#f00075; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-lastfm{ background-color:#e21b24; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-linkedin{ background-color:#0d66c2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-mastodon{ background-color:#3288d4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-medium{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-meetup{ background-color:#f6405f; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-patreon{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pinterest{ background-color:#e60122; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pocket{ background-color:#ef4155; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-reddit{ background-color:#ff4500; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-skype{ background-color:#0478d7; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-snapchat{ background-color:#fefc00; color:#fff; stroke:#000; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-soundcloud{ background-color:#ff5600; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-spotify{ background-color:#1bd760; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-telegram{ background-color:#2aabee; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-threads{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tiktok{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tumblr{ background-color:#011835; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitch{ background-color:#6440a4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitter{ background-color:#1da1f2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vimeo{ background-color:#1eb7ea; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vk{ background-color:#4680c2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-wordpress{ background-color:#3499cd; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-whatsapp{ background-color:#25d366; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-x{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-yelp{ background-color:#d32422; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-youtube{ background-color:red; color:#fff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link{ background:none; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link svg{ height:1.25em; width:1.25em; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-amazon{ color:#f90; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bandcamp{ color:#1ea0c3; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-behance{ color:#0757fe; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bluesky{ color:#0a7aff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-codepen{ color:#1e1f26; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-deviantart{ color:#02e49b; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-discord{ color:#5865f2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dribbble{ color:#e94c89; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dropbox{ color:#4280ff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-etsy{ color:#f45800; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-facebook{ color:#0866ff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-fivehundredpx{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-flickr{ color:#0461dd; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-foursquare{ color:#e65678; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-github{ color:#24292d; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-goodreads{ color:#382110; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-google{ color:#ea4434; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-gravatar{ color:#1d4fc4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-instagram{ color:#f00075; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-lastfm{ color:#e21b24; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-linkedin{ color:#0d66c2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-mastodon{ color:#3288d4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-medium{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-meetup{ color:#f6405f; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-patreon{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pinterest{ color:#e60122; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pocket{ color:#ef4155; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-reddit{ color:#ff4500; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-skype{ color:#0478d7; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-snapchat{ color:#fff; stroke:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-soundcloud{ color:#ff5600; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-spotify{ color:#1bd760; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-telegram{ color:#2aabee; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-threads{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tiktok{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tumblr{ color:#011835; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitch{ color:#6440a4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitter{ color:#1da1f2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vimeo{ color:#1eb7ea; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vk{ color:#4680c2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-whatsapp{ color:#25d366; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-wordpress{ color:#3499cd; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-x{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-yelp{ color:#d32422; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-youtube{ color:red; } .wp-block-social-links.is-style-pill-shape .wp-social-link{ width:auto; } :root :where(.wp-block-social-links .wp-social-link a){ padding:.25em; } :root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a){ padding:0; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a){ padding-left:.6666666667em; padding-right:.6666666667em; } .wp-block-social-links:not(.has-icon-color):not(.has-icon-background-color) .wp-social-link-snapchat .wp-block-social-link-label{ color:#000; } .wp-block-spacer{ clear:both; } .wp-block-tag-cloud{ box-sizing:border-box; } .wp-block-tag-cloud.aligncenter{ justify-content:center; text-align:center; } .wp-block-tag-cloud.alignfull{ padding-left:1em; padding-right:1em; } .wp-block-tag-cloud a{ display:inline-block; margin-left:5px; } .wp-block-tag-cloud span{ display:inline-block; margin-right:5px; text-decoration:none; } :root :where(.wp-block-tag-cloud.is-style-outline){ display:flex; flex-wrap:wrap; gap:1ch; } :root :where(.wp-block-tag-cloud.is-style-outline a){ border:1px solid; font-size:unset !important; margin-left:0; padding:1ch 2ch; text-decoration:none !important; } .wp-block-table{ overflow-x:auto; } .wp-block-table table{ border-collapse:collapse; width:100%; } .wp-block-table thead{ border-bottom:3px solid; } .wp-block-table tfoot{ border-top:3px solid; } .wp-block-table td,.wp-block-table th{ border:1px solid; padding:.5em; } .wp-block-table .has-fixed-layout{ table-layout:fixed; width:100%; } .wp-block-table .has-fixed-layout td,.wp-block-table .has-fixed-layout th{ word-break:break-word; } .wp-block-table.aligncenter,.wp-block-table.alignleft,.wp-block-table.alignright{ display:table; width:auto; } .wp-block-table.aligncenter td,.wp-block-table.aligncenter th,.wp-block-table.alignleft td,.wp-block-table.alignleft th,.wp-block-table.alignright td,.wp-block-table.alignright th{ word-break:break-word; } .wp-block-table .has-subtle-light-gray-background-color{ background-color:#f3f4f5; } .wp-block-table .has-subtle-pale-green-background-color{ background-color:#e9fbe5; } .wp-block-table .has-subtle-pale-blue-background-color{ background-color:#e7f5fe; } .wp-block-table .has-subtle-pale-pink-background-color{ background-color:#fcf0ef; } .wp-block-table.is-style-stripes{ background-color:initial; border-bottom:1px solid #f0f0f0; border-collapse:inherit; border-spacing:0; } .wp-block-table.is-style-stripes tbody tr:nth-child(odd){ background-color:#f0f0f0; } .wp-block-table.is-style-stripes.has-subtle-light-gray-background-color tbody tr:nth-child(odd){ background-color:#f3f4f5; } .wp-block-table.is-style-stripes.has-subtle-pale-green-background-color tbody tr:nth-child(odd){ background-color:#e9fbe5; } .wp-block-table.is-style-stripes.has-subtle-pale-blue-background-color tbody tr:nth-child(odd){ background-color:#e7f5fe; } .wp-block-table.is-style-stripes.has-subtle-pale-pink-background-color tbody tr:nth-child(odd){ background-color:#fcf0ef; } .wp-block-table.is-style-stripes td,.wp-block-table.is-style-stripes th{ border-color:#0000; } .wp-block-table .has-border-color td,.wp-block-table .has-border-color th,.wp-block-table .has-border-color tr,.wp-block-table .has-border-color>*{ border-color:inherit; } .wp-block-table table[style*=border-top-color] tr:first-child,.wp-block-table table[style*=border-top-color] tr:first-child td,.wp-block-table table[style*=border-top-color] tr:first-child th,.wp-block-table table[style*=border-top-color]>*,.wp-block-table table[style*=border-top-color]>* td,.wp-block-table table[style*=border-top-color]>* th{ border-top-color:inherit; } .wp-block-table table[style*=border-top-color] tr:not(:first-child){ border-top-color:initial; } .wp-block-table table[style*=border-right-color] td:last-child,.wp-block-table table[style*=border-right-color] th,.wp-block-table table[style*=border-right-color] tr,.wp-block-table table[style*=border-right-color]>*{ border-left-color:inherit; } .wp-block-table table[style*=border-bottom-color] tr:last-child,.wp-block-table table[style*=border-bottom-color] tr:last-child td,.wp-block-table table[style*=border-bottom-color] tr:last-child th,.wp-block-table table[style*=border-bottom-color]>*,.wp-block-table table[style*=border-bottom-color]>* td,.wp-block-table table[style*=border-bottom-color]>* th{ border-bottom-color:inherit; } .wp-block-table table[style*=border-bottom-color] tr:not(:last-child){ border-bottom-color:initial; } .wp-block-table table[style*=border-left-color] td:first-child,.wp-block-table table[style*=border-left-color] th,.wp-block-table table[style*=border-left-color] tr,.wp-block-table table[style*=border-left-color]>*{ border-right-color:inherit; } .wp-block-table table[style*=border-style] td,.wp-block-table table[style*=border-style] th,.wp-block-table table[style*=border-style] tr,.wp-block-table table[style*=border-style]>*{ border-style:inherit; } .wp-block-table table[style*=border-width] td,.wp-block-table table[style*=border-width] th,.wp-block-table table[style*=border-width] tr,.wp-block-table table[style*=border-width]>*{ border-style:inherit; border-width:inherit; } :root :where(.wp-block-table-of-contents){ box-sizing:border-box; } :where(.wp-block-term-description){ box-sizing:border-box; margin-bottom:var(--wp--style--block-gap); margin-top:var(--wp--style--block-gap); } .wp-block-term-description p{ margin-bottom:0; margin-top:0; } .wp-block-text-columns,.wp-block-text-columns.aligncenter{ display:flex; } .wp-block-text-columns .wp-block-column{ margin:0 1em; padding:0; } .wp-block-text-columns .wp-block-column:first-child{ margin-right:0; } .wp-block-text-columns .wp-block-column:last-child{ margin-left:0; } .wp-block-text-columns.columns-2 .wp-block-column{ width:50%; } .wp-block-text-columns.columns-3 .wp-block-column{ width:33.3333333333%; } .wp-block-text-columns.columns-4 .wp-block-column{ width:25%; } pre.wp-block-verse{ overflow:auto; white-space:pre-wrap; } :where(pre.wp-block-verse){ font-family:inherit; } .wp-block-video{ box-sizing:border-box; } .wp-block-video video{ vertical-align:middle; width:100%; } @supports (position:sticky){ .wp-block-video [poster]{ object-fit:cover; } } .wp-block-video.aligncenter{ text-align:center; } .wp-block-video :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .editor-styles-wrapper,.entry-content{ counter-reset:footnotes; } a[data-fn].fn{ counter-increment:footnotes; display:inline-flex; font-size:smaller; text-decoration:none; text-indent:-9999999px; vertical-align:super; } a[data-fn].fn:after{ content:"[" counter(footnotes) "]"; float:right; text-indent:0; } .wp-element-button{ cursor:pointer; } :root{ --wp--preset--font-size--normal:16px; --wp--preset--font-size--huge:42px; } :root .has-very-light-gray-background-color{ background-color:#eee; } :root .has-very-dark-gray-background-color{ background-color:#313131; } :root .has-very-light-gray-color{ color:#eee; } :root .has-very-dark-gray-color{ color:#313131; } :root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(-135deg, #00d084, #0693e3); } :root .has-purple-crush-gradient-background{ background:linear-gradient(-135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .has-hazy-dawn-gradient-background{ background:linear-gradient(-135deg, #faaca8, #dad0ec); } :root .has-subdued-olive-gradient-background{ background:linear-gradient(-135deg, #fafae1, #67a671); } :root .has-atomic-cream-gradient-background{ background:linear-gradient(-135deg, #fdd79a, #004a59); } :root .has-nightshade-gradient-background{ background:linear-gradient(-135deg, #330968, #31cdcf); } :root .has-midnight-gradient-background{ background:linear-gradient(-135deg, #020381, #2874fc); } .has-regular-font-size{ font-size:1em; } .has-larger-font-size{ font-size:2.625em; } .has-normal-font-size{ font-size:var(--wp--preset--font-size--normal); } .has-huge-font-size{ font-size:var(--wp--preset--font-size--huge); } .has-text-align-center{ text-align:center; } .has-text-align-left{ text-align:left; } .has-text-align-right{ text-align:right; } #end-resizable-editor-section{ display:none; } .aligncenter{ clear:both; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } .screen-reader-text{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .screen-reader-text:focus{ background-color:#ddd; clip-path:none; color:#444; display:block; font-size:1em; height:auto; line-height:normal; padding:15px 23px 14px; right:5px; text-decoration:none; top:5px; width:auto; z-index:100000; } html :where(.has-border-color){ border-style:solid; } html :where([style*=border-top-color]){ border-top-style:solid; } html :where([style*=border-right-color]){ border-left-style:solid; } html :where([style*=border-bottom-color]){ border-bottom-style:solid; } html :where([style*=border-left-color]){ border-right-style:solid; } html :where([style*=border-width]){ border-style:solid; } html :where([style*=border-top-width]){ border-top-style:solid; } html :where([style*=border-right-width]){ border-left-style:solid; } html :where([style*=border-bottom-width]){ border-bottom-style:solid; } html :where([style*=border-left-width]){ border-right-style:solid; } html :where(img[class*=wp-image-]){ height:auto; max-width:100%; } :where(figure){ margin:0 0 1em; } html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height, 0px); } @media screen and (max-width:600px){ html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:0px; } }@charset "UTF-8"; .wp-block-archives{ box-sizing:border-box; } .wp-block-archives-dropdown label{ display:block; } .wp-block-avatar{ line-height:0; } .wp-block-avatar,.wp-block-avatar img{ box-sizing:border-box; } .wp-block-avatar.aligncenter{ text-align:center; } .wp-block-audio{ box-sizing:border-box; } .wp-block-audio :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-audio audio{ min-width:300px; width:100%; } .wp-block-button__link{ align-content:center; box-sizing:border-box; cursor:pointer; display:inline-block; height:100%; text-align:center; word-break:break-word; } .wp-block-button__link.aligncenter{ text-align:center; } .wp-block-button__link.alignright{ text-align:right; } :where(.wp-block-button__link){ border-radius:9999px; box-shadow:none; padding:calc(.667em + 2px) calc(1.333em + 2px); text-decoration:none; } .wp-block-button[style*=text-decoration] .wp-block-button__link{ text-decoration:inherit; } .wp-block-buttons>.wp-block-button.has-custom-width{ max-width:none; } .wp-block-buttons>.wp-block-button.has-custom-width .wp-block-button__link{ width:100%; } .wp-block-buttons>.wp-block-button.has-custom-font-size .wp-block-button__link{ font-size:inherit; } .wp-block-buttons>.wp-block-button.wp-block-button__width-25{ width:calc(25% - var(--wp--style--block-gap, .5em)*.75); } .wp-block-buttons>.wp-block-button.wp-block-button__width-50{ width:calc(50% - var(--wp--style--block-gap, .5em)*.5); } .wp-block-buttons>.wp-block-button.wp-block-button__width-75{ width:calc(75% - var(--wp--style--block-gap, .5em)*.25); } .wp-block-buttons>.wp-block-button.wp-block-button__width-100{ flex-basis:100%; width:100%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-25{ width:25%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-50{ width:50%; } .wp-block-buttons.is-vertical>.wp-block-button.wp-block-button__width-75{ width:75%; } .wp-block-button.is-style-squared,.wp-block-button__link.wp-block-button.is-style-squared{ border-radius:0; } .wp-block-button.no-border-radius,.wp-block-button__link.no-border-radius{ border-radius:0 !important; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link){ border:2px solid; padding:.667em 1.333em; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-text-color)){ color:currentColor; } :root :where(.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background)),:root :where(.wp-block-button.is-style-outline>.wp-block-button__link:not(.has-background)){ background-color:initial; background-image:none; } .wp-block-buttons{ box-sizing:border-box; } .wp-block-buttons.is-vertical{ flex-direction:column; } .wp-block-buttons.is-vertical>.wp-block-button:last-child{ margin-bottom:0; } .wp-block-buttons>.wp-block-button{ display:inline-block; margin:0; } .wp-block-buttons.is-content-justification-left{ justify-content:flex-start; } .wp-block-buttons.is-content-justification-left.is-vertical{ align-items:flex-start; } .wp-block-buttons.is-content-justification-center{ justify-content:center; } .wp-block-buttons.is-content-justification-center.is-vertical{ align-items:center; } .wp-block-buttons.is-content-justification-right{ justify-content:flex-end; } .wp-block-buttons.is-content-justification-right.is-vertical{ align-items:flex-end; } .wp-block-buttons.is-content-justification-space-between{ justify-content:space-between; } .wp-block-buttons.aligncenter{ text-align:center; } .wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block-button.aligncenter{ margin-left:auto; margin-right:auto; width:100%; } .wp-block-buttons[style*=text-decoration] .wp-block-button,.wp-block-buttons[style*=text-decoration] .wp-block-button__link{ text-decoration:inherit; } .wp-block-buttons.has-custom-font-size .wp-block-button__link{ font-size:inherit; } .wp-block-buttons .wp-block-button__link{ width:100%; } .wp-block-button.aligncenter,.wp-block-calendar{ text-align:center; } .wp-block-calendar td,.wp-block-calendar th{ border:1px solid; padding:.25em; } .wp-block-calendar th{ font-weight:400; } .wp-block-calendar caption{ background-color:inherit; } .wp-block-calendar table{ border-collapse:collapse; width:100%; } .wp-block-calendar table:where(:not(.has-text-color)){ color:#40464d; } .wp-block-calendar table:where(:not(.has-text-color)) td,.wp-block-calendar table:where(:not(.has-text-color)) th{ border-color:#ddd; } .wp-block-calendar table.has-background th{ background-color:inherit; } .wp-block-calendar table.has-text-color th{ color:inherit; } :where(.wp-block-calendar table:not(.has-background) th){ background:#ddd; } .wp-block-categories{ box-sizing:border-box; } .wp-block-categories.alignleft{ margin-right:2em; } .wp-block-categories.alignright{ margin-left:2em; } .wp-block-categories.wp-block-categories-dropdown.aligncenter{ text-align:center; } .wp-block-categories .wp-block-categories__label{ display:block; width:100%; } .wp-block-code{ box-sizing:border-box; } .wp-block-code code{ direction:ltr; display:block; font-family:inherit; overflow-wrap:break-word; text-align:initial; white-space:pre-wrap; } .wp-block-columns{ align-items:normal !important; box-sizing:border-box; display:flex; flex-wrap:wrap !important; } @media (min-width:782px){ .wp-block-columns{ flex-wrap:nowrap !important; } } .wp-block-columns.are-vertically-aligned-top{ align-items:flex-start; } .wp-block-columns.are-vertically-aligned-center{ align-items:center; } .wp-block-columns.are-vertically-aligned-bottom{ align-items:flex-end; } @media (max-width:781px){ .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{ flex-basis:100% !important; } } @media (min-width:782px){ .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{ flex-basis:0; flex-grow:1; } .wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column[style*=flex-basis]{ flex-grow:0; } } .wp-block-columns.is-not-stacked-on-mobile{ flex-wrap:nowrap !important; } .wp-block-columns.is-not-stacked-on-mobile>.wp-block-column{ flex-basis:0; flex-grow:1; } .wp-block-columns.is-not-stacked-on-mobile>.wp-block-column[style*=flex-basis]{ flex-grow:0; } :where(.wp-block-columns){ margin-bottom:1.75em; } :where(.wp-block-columns.has-background){ padding:1.25em 2.375em; } .wp-block-column{ flex-grow:1; min-width:0; overflow-wrap:break-word; word-break:break-word; } .wp-block-column.is-vertically-aligned-top{ align-self:flex-start; } .wp-block-column.is-vertically-aligned-center{ align-self:center; } .wp-block-column.is-vertically-aligned-bottom{ align-self:flex-end; } .wp-block-column.is-vertically-aligned-stretch{ align-self:stretch; } .wp-block-column.is-vertically-aligned-bottom,.wp-block-column.is-vertically-aligned-center,.wp-block-column.is-vertically-aligned-top{ width:100%; } .wp-block-post-comments{ box-sizing:border-box; } .wp-block-post-comments .alignleft{ float:left; } .wp-block-post-comments .alignright{ float:right; } .wp-block-post-comments .navigation:after{ clear:both; content:""; display:table; } .wp-block-post-comments .commentlist{ clear:both; list-style:none; margin:0; padding:0; } .wp-block-post-comments .commentlist .comment{ min-height:2.25em; padding-left:3.25em; } .wp-block-post-comments .commentlist .comment p{ font-size:1em; line-height:1.8; margin:1em 0; } .wp-block-post-comments .commentlist .children{ list-style:none; margin:0; padding:0; } .wp-block-post-comments .comment-author{ line-height:1.5; } .wp-block-post-comments .comment-author .avatar{ border-radius:1.5em; display:block; float:left; height:2.5em; margin-right:.75em; margin-top:.5em; width:2.5em; } .wp-block-post-comments .comment-author cite{ font-style:normal; } .wp-block-post-comments .comment-meta{ font-size:.875em; line-height:1.5; } .wp-block-post-comments .comment-meta b{ font-weight:400; } .wp-block-post-comments .comment-meta .comment-awaiting-moderation{ display:block; margin-bottom:1em; margin-top:1em; } .wp-block-post-comments .comment-body .commentmetadata{ font-size:.875em; } .wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-post-comments .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-post-comments .comment-reply-title{ margin-bottom:0; } .wp-block-post-comments .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-left:.5em; } .wp-block-post-comments .reply{ font-size:.875em; margin-bottom:1.4em; } .wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } .wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{ padding:calc(.667em + 2px); } :where(.wp-block-post-comments input[type=submit]){ border:none; } .wp-block-comments{ box-sizing:border-box; } .wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{ font-size:inherit; margin-bottom:.5em; margin-right:.5em; } .wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{ margin-right:0; } .wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow{ display:inline-block; margin-right:1ch; } .wp-block-comments-pagination .wp-block-comments-pagination-previous-arrow:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-comments-pagination .wp-block-comments-pagination-next-arrow{ display:inline-block; margin-left:1ch; } .wp-block-comments-pagination .wp-block-comments-pagination-next-arrow:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-comments-pagination.aligncenter{ justify-content:center; } .wp-block-comment-template{ box-sizing:border-box; list-style:none; margin-bottom:0; max-width:100%; padding:0; } .wp-block-comment-template li{ clear:both; } .wp-block-comment-template ol{ list-style:none; margin-bottom:0; max-width:100%; padding-left:2rem; } .wp-block-comment-template.alignleft{ float:left; } .wp-block-comment-template.aligncenter{ margin-left:auto; margin-right:auto; width:fit-content; } .wp-block-comment-template.alignright{ float:right; } .wp-block-comment-date{ box-sizing:border-box; } .comment-awaiting-moderation{ display:block; font-size:.875em; line-height:1.5; } .wp-block-comment-author-name,.wp-block-comment-content,.wp-block-comment-edit-link,.wp-block-comment-reply-link{ box-sizing:border-box; } .wp-block-cover,.wp-block-cover-image{ align-items:center; background-position:50%; box-sizing:border-box; display:flex; justify-content:center; min-height:430px; overflow:hidden; overflow:clip; padding:1em; position:relative; } .wp-block-cover .has-background-dim:not([class*=-background-color]),.wp-block-cover-image .has-background-dim:not([class*=-background-color]),.wp-block-cover-image.has-background-dim:not([class*=-background-color]),.wp-block-cover.has-background-dim:not([class*=-background-color]){ background-color:#000; } .wp-block-cover .has-background-dim.has-background-gradient,.wp-block-cover-image .has-background-dim.has-background-gradient{ background-color:initial; } .wp-block-cover-image.has-background-dim:before,.wp-block-cover.has-background-dim:before{ background-color:inherit; content:""; } .wp-block-cover .wp-block-cover__background,.wp-block-cover .wp-block-cover__gradient-background,.wp-block-cover-image .wp-block-cover__background,.wp-block-cover-image .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim:not(.has-background-gradient):before,.wp-block-cover.has-background-dim:not(.has-background-gradient):before{ bottom:0; left:0; opacity:.5; position:absolute; right:0; top:0; } .wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-10:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-10 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-10:not(.has-background-gradient):before{ opacity:.1; } .wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-20:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-20 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-20:not(.has-background-gradient):before{ opacity:.2; } .wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-30:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-30 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-30:not(.has-background-gradient):before{ opacity:.3; } .wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-40:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-40 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-40:not(.has-background-gradient):before{ opacity:.4; } .wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-50:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-50 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-50:not(.has-background-gradient):before{ opacity:.5; } .wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-60:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-60 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-60:not(.has-background-gradient):before{ opacity:.6; } .wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-70:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-70 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-70:not(.has-background-gradient):before{ opacity:.7; } .wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-80:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-80 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-80:not(.has-background-gradient):before{ opacity:.8; } .wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-90:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-90 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-90:not(.has-background-gradient):before{ opacity:.9; } .wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover-image.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover-image.has-background-dim.has-background-dim-100:not(.has-background-gradient):before,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__background,.wp-block-cover.has-background-dim.has-background-dim-100 .wp-block-cover__gradient-background,.wp-block-cover.has-background-dim.has-background-dim-100:not(.has-background-gradient):before{ opacity:1; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-0,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-0{ opacity:0; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-10,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-10{ opacity:.1; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-20,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-20{ opacity:.2; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-30,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-30{ opacity:.3; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-40,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-40{ opacity:.4; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-50,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-50{ opacity:.5; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-60,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-60{ opacity:.6; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-70,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-70{ opacity:.7; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-80,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-80{ opacity:.8; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-90,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-90{ opacity:.9; } .wp-block-cover .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__background.has-background-dim.has-background-dim-100,.wp-block-cover-image .wp-block-cover__gradient-background.has-background-dim.has-background-dim-100{ opacity:1; } .wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.alignleft,.wp-block-cover.alignright{ max-width:420px; width:100%; } .wp-block-cover-image.aligncenter,.wp-block-cover-image.alignleft,.wp-block-cover-image.alignright,.wp-block-cover.aligncenter,.wp-block-cover.alignleft,.wp-block-cover.alignright{ display:flex; } .wp-block-cover .wp-block-cover__inner-container,.wp-block-cover-image .wp-block-cover__inner-container{ color:inherit; position:relative; width:100%; } .wp-block-cover-image.is-position-top-left,.wp-block-cover.is-position-top-left{ align-items:flex-start; justify-content:flex-start; } .wp-block-cover-image.is-position-top-center,.wp-block-cover.is-position-top-center{ align-items:flex-start; justify-content:center; } .wp-block-cover-image.is-position-top-right,.wp-block-cover.is-position-top-right{ align-items:flex-start; justify-content:flex-end; } .wp-block-cover-image.is-position-center-left,.wp-block-cover.is-position-center-left{ align-items:center; justify-content:flex-start; } .wp-block-cover-image.is-position-center-center,.wp-block-cover.is-position-center-center{ align-items:center; justify-content:center; } .wp-block-cover-image.is-position-center-right,.wp-block-cover.is-position-center-right{ align-items:center; justify-content:flex-end; } .wp-block-cover-image.is-position-bottom-left,.wp-block-cover.is-position-bottom-left{ align-items:flex-end; justify-content:flex-start; } .wp-block-cover-image.is-position-bottom-center,.wp-block-cover.is-position-bottom-center{ align-items:flex-end; justify-content:center; } .wp-block-cover-image.is-position-bottom-right,.wp-block-cover.is-position-bottom-right{ align-items:flex-end; justify-content:flex-end; } .wp-block-cover-image.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position .wp-block-cover__inner-container{ margin:0; } .wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover-image.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-bottom-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-center-right .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-left .wp-block-cover__inner-container,.wp-block-cover.has-custom-content-position.has-custom-content-position.is-position-top-right .wp-block-cover__inner-container{ margin:0; width:auto; } .wp-block-cover .wp-block-cover__image-background,.wp-block-cover video.wp-block-cover__video-background,.wp-block-cover-image .wp-block-cover__image-background,.wp-block-cover-image video.wp-block-cover__video-background{ border:none; bottom:0; box-shadow:none; height:100%; left:0; margin:0; max-height:none; max-width:none; object-fit:cover; outline:none; padding:0; position:absolute; right:0; top:0; width:100%; } .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:fixed; background-repeat:no-repeat; background-size:cover; } @supports (-webkit-touch-callout:inherit){ .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:scroll; } } @media (prefers-reduced-motion:reduce){ .wp-block-cover-image.has-parallax,.wp-block-cover.has-parallax,.wp-block-cover__image-background.has-parallax,video.wp-block-cover__video-background.has-parallax{ background-attachment:scroll; } } .wp-block-cover-image.is-repeated,.wp-block-cover.is-repeated,.wp-block-cover__image-background.is-repeated,video.wp-block-cover__video-background.is-repeated{ background-repeat:repeat; background-size:auto; } .wp-block-cover-image-text,.wp-block-cover-image-text a,.wp-block-cover-image-text a:active,.wp-block-cover-image-text a:focus,.wp-block-cover-image-text a:hover,.wp-block-cover-text,.wp-block-cover-text a,.wp-block-cover-text a:active,.wp-block-cover-text a:focus,.wp-block-cover-text a:hover,section.wp-block-cover-image h2,section.wp-block-cover-image h2 a,section.wp-block-cover-image h2 a:active,section.wp-block-cover-image h2 a:focus,section.wp-block-cover-image h2 a:hover{ color:#fff; } .wp-block-cover-image .wp-block-cover.has-left-content{ justify-content:flex-start; } .wp-block-cover-image .wp-block-cover.has-right-content{ justify-content:flex-end; } .wp-block-cover-image.has-left-content .wp-block-cover-image-text,.wp-block-cover.has-left-content .wp-block-cover-text,section.wp-block-cover-image.has-left-content>h2{ margin-left:0; text-align:left; } .wp-block-cover-image.has-right-content .wp-block-cover-image-text,.wp-block-cover.has-right-content .wp-block-cover-text,section.wp-block-cover-image.has-right-content>h2{ margin-right:0; text-align:right; } .wp-block-cover .wp-block-cover-text,.wp-block-cover-image .wp-block-cover-image-text,section.wp-block-cover-image>h2{ font-size:2em; line-height:1.25; margin-bottom:0; max-width:840px; padding:.44em; text-align:center; z-index:1; } :where(.wp-block-cover-image:not(.has-text-color)),:where(.wp-block-cover:not(.has-text-color)){ color:#fff; } :where(.wp-block-cover-image.is-light:not(.has-text-color)),:where(.wp-block-cover.is-light:not(.has-text-color)){ color:#000; } :root :where(.wp-block-cover h1:not(.has-text-color)),:root :where(.wp-block-cover h2:not(.has-text-color)),:root :where(.wp-block-cover h3:not(.has-text-color)),:root :where(.wp-block-cover h4:not(.has-text-color)),:root :where(.wp-block-cover h5:not(.has-text-color)),:root :where(.wp-block-cover h6:not(.has-text-color)),:root :where(.wp-block-cover p:not(.has-text-color)){ color:inherit; } body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__image-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__video-background{ z-index:0; } body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__gradient-background,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container,body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)).has-background-dim:not(.has-background-gradient):before{ z-index:1; } .has-modal-open body:not(.editor-styles-wrapper) .wp-block-cover:not(.wp-block-cover:has(.wp-block-cover__background+.wp-block-cover__inner-container)) .wp-block-cover__inner-container{ z-index:auto; } .wp-block-details{ box-sizing:border-box; } .wp-block-details summary{ cursor:pointer; } .wp-block-embed.alignleft,.wp-block-embed.alignright,.wp-block[data-align=left]>[data-type="core/embed"],.wp-block[data-align=right]>[data-type="core/embed"]{ max-width:360px; width:100%; } .wp-block-embed.alignleft .wp-block-embed__wrapper,.wp-block-embed.alignright .wp-block-embed__wrapper,.wp-block[data-align=left]>[data-type="core/embed"] .wp-block-embed__wrapper,.wp-block[data-align=right]>[data-type="core/embed"] .wp-block-embed__wrapper{ min-width:280px; } .wp-block-cover .wp-block-embed{ min-height:240px; min-width:320px; } .wp-block-embed{ overflow-wrap:break-word; } .wp-block-embed :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-embed iframe{ max-width:100%; } .wp-block-embed__wrapper{ position:relative; } .wp-embed-responsive .wp-has-aspect-ratio .wp-block-embed__wrapper:before{ content:""; display:block; padding-top:50%; } .wp-embed-responsive .wp-has-aspect-ratio iframe{ bottom:0; height:100%; left:0; position:absolute; right:0; top:0; width:100%; } .wp-embed-responsive .wp-embed-aspect-21-9 .wp-block-embed__wrapper:before{ padding-top:42.85%; } .wp-embed-responsive .wp-embed-aspect-18-9 .wp-block-embed__wrapper:before{ padding-top:50%; } .wp-embed-responsive .wp-embed-aspect-16-9 .wp-block-embed__wrapper:before{ padding-top:56.25%; } .wp-embed-responsive .wp-embed-aspect-4-3 .wp-block-embed__wrapper:before{ padding-top:75%; } .wp-embed-responsive .wp-embed-aspect-1-1 .wp-block-embed__wrapper:before{ padding-top:100%; } .wp-embed-responsive .wp-embed-aspect-9-16 .wp-block-embed__wrapper:before{ padding-top:177.77%; } .wp-embed-responsive .wp-embed-aspect-1-2 .wp-block-embed__wrapper:before{ padding-top:200%; } .wp-block-file{ box-sizing:border-box; } .wp-block-file:not(.wp-element-button){ font-size:.8em; } .wp-block-file.aligncenter{ text-align:center; } .wp-block-file.alignright{ text-align:right; } .wp-block-file *+.wp-block-file__button{ margin-left:.75em; } :where(.wp-block-file){ margin-bottom:1.5em; } .wp-block-file__embed{ margin-bottom:1em; } :where(.wp-block-file__button){ border-radius:2em; display:inline-block; padding:.5em 1em; } :where(.wp-block-file__button):is(a):active,:where(.wp-block-file__button):is(a):focus,:where(.wp-block-file__button):is(a):hover,:where(.wp-block-file__button):is(a):visited{ box-shadow:none; color:#fff; opacity:.85; text-decoration:none; } .wp-block-form-input__label{ display:flex; flex-direction:column; gap:.25em; margin-bottom:.5em; width:100%; } .wp-block-form-input__label.is-label-inline{ align-items:center; flex-direction:row; gap:.5em; } .wp-block-form-input__label.is-label-inline .wp-block-form-input__label-content{ margin-bottom:.5em; } .wp-block-form-input__label:has(input[type=checkbox]){ flex-direction:row; width:fit-content; } .wp-block-form-input__label:has(input[type=checkbox]) .wp-block-form-input__label-content{ margin:0; } .wp-block-form-input__label:has(.wp-block-form-input__label-content+input[type=checkbox]){ flex-direction:row-reverse; } .wp-block-form-input__label-content{ width:fit-content; } .wp-block-form-input__input{ font-size:1em; margin-bottom:.5em; padding:0 .5em; } .wp-block-form-input__input[type=date],.wp-block-form-input__input[type=datetime-local],.wp-block-form-input__input[type=datetime],.wp-block-form-input__input[type=email],.wp-block-form-input__input[type=month],.wp-block-form-input__input[type=number],.wp-block-form-input__input[type=password],.wp-block-form-input__input[type=search],.wp-block-form-input__input[type=tel],.wp-block-form-input__input[type=text],.wp-block-form-input__input[type=time],.wp-block-form-input__input[type=url],.wp-block-form-input__input[type=week]{ border:1px solid; line-height:2; min-height:2em; } textarea.wp-block-form-input__input{ min-height:10em; } .blocks-gallery-grid:not(.has-nested-images),.wp-block-gallery:not(.has-nested-images){ display:flex; flex-wrap:wrap; list-style-type:none; margin:0; padding:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item{ display:flex; flex-direction:column; flex-grow:1; justify-content:center; margin:0 1em 1em 0; position:relative; width:calc(50% - 1em); } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:nth-of-type(2n){ margin-right:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figure,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figure,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figure{ align-items:flex-end; display:flex; height:100%; justify-content:flex-start; margin:0; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item img{ display:block; height:auto; max-width:100%; width:auto; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption{ background:linear-gradient(0deg, #000000b3, #0000004d 70%, #0000); bottom:0; box-sizing:border-box; color:#fff; font-size:.8em; margin:0; max-height:100%; overflow:auto; padding:3em .77em .7em; position:absolute; text-align:center; width:100%; z-index:2; } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image figcaption img,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image figcaption img,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item figcaption img{ display:inline; } .blocks-gallery-grid:not(.has-nested-images) figcaption,.wp-block-gallery:not(.has-nested-images) figcaption{ flex-grow:1; } .blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-image img,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item a,.blocks-gallery-grid:not(.has-nested-images).is-cropped .blocks-gallery-item img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-image img,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item a,.wp-block-gallery:not(.has-nested-images).is-cropped .blocks-gallery-item img{ flex:1; height:100%; object-fit:cover; width:100%; } .blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item{ margin-right:0; width:100%; } @media (min-width:600px){ .blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item{ margin-right:1em; width:calc(33.33333% - .66667em); } .blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item{ margin-right:1em; width:calc(25% - .75em); } .blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item{ margin-right:1em; width:calc(20% - .8em); } .blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item{ margin-right:1em; width:calc(16.66667% - .83333em); } .blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item{ margin-right:1em; width:calc(14.28571% - .85714em); } .blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image,.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image,.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item{ margin-right:1em; width:calc(12.5% - .875em); } .blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.blocks-gallery-grid:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-image:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-1 .blocks-gallery-item:nth-of-type(1n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-image:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-2 .blocks-gallery-item:nth-of-type(2n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-image:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-3 .blocks-gallery-item:nth-of-type(3n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-image:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-4 .blocks-gallery-item:nth-of-type(4n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-image:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-5 .blocks-gallery-item:nth-of-type(5n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-image:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-6 .blocks-gallery-item:nth-of-type(6n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-image:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-7 .blocks-gallery-item:nth-of-type(7n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-image:nth-of-type(8n),.wp-block-gallery:not(.has-nested-images).columns-8 .blocks-gallery-item:nth-of-type(8n){ margin-right:0; } } .blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-image:last-child,.blocks-gallery-grid:not(.has-nested-images) .blocks-gallery-item:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-image:last-child,.wp-block-gallery:not(.has-nested-images) .blocks-gallery-item:last-child{ margin-right:0; } .blocks-gallery-grid:not(.has-nested-images).alignleft,.blocks-gallery-grid:not(.has-nested-images).alignright,.wp-block-gallery:not(.has-nested-images).alignleft,.wp-block-gallery:not(.has-nested-images).alignright{ max-width:420px; width:100%; } .blocks-gallery-grid:not(.has-nested-images).aligncenter .blocks-gallery-item figure,.wp-block-gallery:not(.has-nested-images).aligncenter .blocks-gallery-item figure{ justify-content:center; } .wp-block-gallery:not(.is-cropped) .blocks-gallery-item{ align-self:flex-start; } figure.wp-block-gallery.has-nested-images{ align-items:normal; } .wp-block-gallery.has-nested-images figure.wp-block-image:not(#individual-image){ margin:0; width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)/2); } .wp-block-gallery.has-nested-images figure.wp-block-image{ box-sizing:border-box; display:flex; flex-direction:column; flex-grow:1; justify-content:center; max-width:100%; position:relative; } .wp-block-gallery.has-nested-images figure.wp-block-image>a,.wp-block-gallery.has-nested-images figure.wp-block-image>div{ flex-direction:column; flex-grow:1; margin:0; } .wp-block-gallery.has-nested-images figure.wp-block-image img{ display:block; height:auto; max-width:100% !important; width:auto; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{ bottom:0; left:0; max-height:100%; position:absolute; right:0; } .wp-block-gallery.has-nested-images figure.wp-block-image:has(figcaption):before{ -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); content:""; height:100%; -webkit-mask-image:linear-gradient(0deg, #000 20%, #0000); mask-image:linear-gradient(0deg, #000 20%, #0000); max-height:40%; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption{ background:linear-gradient(0deg, #0006, #0000); box-sizing:border-box; color:#fff; font-size:13px; margin:0; overflow:auto; padding:1em; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-width:thin; text-align:center; text-shadow:0 0 1.5px #000; will-change:transform; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar{ height:12px; width:12px; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-track{ background-color:initial; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus::-webkit-scrollbar-thumb,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover::-webkit-scrollbar-thumb{ background-color:#fffc; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:focus-within,.wp-block-gallery.has-nested-images figure.wp-block-image figcaption:hover{ scrollbar-color:#fffc #0000; } @media (hover:none){ .wp-block-gallery.has-nested-images figure.wp-block-image figcaption{ scrollbar-color:#fffc #0000; } } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption img{ display:inline; } .wp-block-gallery.has-nested-images figure.wp-block-image figcaption a{ color:inherit; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border img{ box-sizing:border-box; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>a,.wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border>div,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>a,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded>div{ flex:1 1 auto; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border figcaption,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded figcaption{ background:none; color:inherit; flex:initial; margin:0; padding:10px 10px 9px; position:relative; text-shadow:none; } .wp-block-gallery.has-nested-images figure.wp-block-image.has-custom-border:before,.wp-block-gallery.has-nested-images figure.wp-block-image.is-style-rounded:before{ content:none; } .wp-block-gallery.has-nested-images figcaption{ flex-basis:100%; flex-grow:1; text-align:center; } .wp-block-gallery.has-nested-images:not(.is-cropped) figure.wp-block-image:not(#individual-image){ margin-bottom:auto; margin-top:0; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image){ align-self:inherit; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image)>div:not(.components-drop-zone){ display:flex; } .wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) a,.wp-block-gallery.has-nested-images.is-cropped figure.wp-block-image:not(#individual-image) img{ flex:1 0 0%; height:100%; object-fit:cover; width:100%; } .wp-block-gallery.has-nested-images.columns-1 figure.wp-block-image:not(#individual-image){ width:100%; } @media (min-width:600px){ .wp-block-gallery.has-nested-images.columns-3 figure.wp-block-image:not(#individual-image){ width:calc(33.33333% - var(--wp--style--unstable-gallery-gap, 16px)*.66667); } .wp-block-gallery.has-nested-images.columns-4 figure.wp-block-image:not(#individual-image){ width:calc(25% - var(--wp--style--unstable-gallery-gap, 16px)*.75); } .wp-block-gallery.has-nested-images.columns-5 figure.wp-block-image:not(#individual-image){ width:calc(20% - var(--wp--style--unstable-gallery-gap, 16px)*.8); } .wp-block-gallery.has-nested-images.columns-6 figure.wp-block-image:not(#individual-image){ width:calc(16.66667% - var(--wp--style--unstable-gallery-gap, 16px)*.83333); } .wp-block-gallery.has-nested-images.columns-7 figure.wp-block-image:not(#individual-image){ width:calc(14.28571% - var(--wp--style--unstable-gallery-gap, 16px)*.85714); } .wp-block-gallery.has-nested-images.columns-8 figure.wp-block-image:not(#individual-image){ width:calc(12.5% - var(--wp--style--unstable-gallery-gap, 16px)*.875); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image){ width:calc(33.33% - var(--wp--style--unstable-gallery-gap, 16px)*.66667); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2),.wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2)~figure.wp-block-image:not(#individual-image){ width:calc(50% - var(--wp--style--unstable-gallery-gap, 16px)*.5); } .wp-block-gallery.has-nested-images.columns-default figure.wp-block-image:not(#individual-image):first-child:last-child{ width:100%; } } .wp-block-gallery.has-nested-images.alignleft,.wp-block-gallery.has-nested-images.alignright{ max-width:420px; width:100%; } .wp-block-gallery.has-nested-images.aligncenter{ justify-content:center; } .wp-block-group{ box-sizing:border-box; } :where(.wp-block-group.wp-block-group-is-layout-constrained){ position:relative; } h1.has-background,h2.has-background,h3.has-background,h4.has-background,h5.has-background,h6.has-background{ padding:1.25em 2.375em; } h1.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h1.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h2.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h2.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h3.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h3.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h4.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h4.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h5.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h5.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]),h6.has-text-align-left[style*=writing-mode]:where([style*=vertical-lr]),h6.has-text-align-right[style*=writing-mode]:where([style*=vertical-rl]){ rotate:180deg; } .wp-block-image>a,.wp-block-image>figure>a{ display:inline-block; } .wp-block-image img{ box-sizing:border-box; height:auto; max-width:100%; vertical-align:bottom; } @media not (prefers-reduced-motion){ .wp-block-image img.hide{ visibility:hidden; } .wp-block-image img.show{ animation:show-content-image .4s; } } .wp-block-image[style*=border-radius] img,.wp-block-image[style*=border-radius]>a{ border-radius:inherit; } .wp-block-image.has-custom-border img{ box-sizing:border-box; } .wp-block-image.aligncenter{ text-align:center; } .wp-block-image.alignfull>a,.wp-block-image.alignwide>a{ width:100%; } .wp-block-image.alignfull img,.wp-block-image.alignwide img{ height:auto; width:100%; } .wp-block-image .aligncenter,.wp-block-image .alignleft,.wp-block-image .alignright,.wp-block-image.aligncenter,.wp-block-image.alignleft,.wp-block-image.alignright{ display:table; } .wp-block-image .aligncenter>figcaption,.wp-block-image .alignleft>figcaption,.wp-block-image .alignright>figcaption,.wp-block-image.aligncenter>figcaption,.wp-block-image.alignleft>figcaption,.wp-block-image.alignright>figcaption{ caption-side:bottom; display:table-caption; } .wp-block-image .alignleft{ float:left; margin:.5em 1em .5em 0; } .wp-block-image .alignright{ float:right; margin:.5em 0 .5em 1em; } .wp-block-image .aligncenter{ margin-left:auto; margin-right:auto; } .wp-block-image :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .wp-block-image.is-style-circle-mask img{ border-radius:9999px; } @supports ((-webkit-mask-image:none) or (mask-image:none)) or (-webkit-mask-image:none){ .wp-block-image.is-style-circle-mask img{ border-radius:0; -webkit-mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>'); mask-image:url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="50"/></svg>'); mask-mode:alpha; -webkit-mask-position:center; mask-position:center; -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat; -webkit-mask-size:contain; mask-size:contain; } } :root :where(.wp-block-image.is-style-rounded img,.wp-block-image .is-style-rounded img){ border-radius:9999px; } .wp-block-image figure{ margin:0; } .wp-lightbox-container{ display:flex; flex-direction:column; position:relative; } .wp-lightbox-container img{ cursor:zoom-in; } .wp-lightbox-container img:hover+button{ opacity:1; } .wp-lightbox-container button{ align-items:center; -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background-color:#5a5a5a40; border:none; border-radius:4px; cursor:zoom-in; display:flex; height:20px; justify-content:center; opacity:0; padding:0; position:absolute; right:16px; text-align:center; top:16px; width:20px; z-index:100; } @media not (prefers-reduced-motion){ .wp-lightbox-container button{ transition:opacity .2s ease; } } .wp-lightbox-container button:focus-visible{ outline:3px auto #5a5a5a40; outline:3px auto -webkit-focus-ring-color; outline-offset:3px; } .wp-lightbox-container button:hover{ cursor:pointer; opacity:1; } .wp-lightbox-container button:focus{ opacity:1; } .wp-lightbox-container button:focus,.wp-lightbox-container button:hover,.wp-lightbox-container button:not(:hover):not(:active):not(.has-background){ background-color:#5a5a5a40; border:none; } .wp-lightbox-overlay{ box-sizing:border-box; cursor:zoom-out; height:100vh; left:0; overflow:hidden; position:fixed; top:0; visibility:hidden; width:100%; z-index:100000; } .wp-lightbox-overlay .close-button{ align-items:center; cursor:pointer; display:flex; justify-content:center; min-height:40px; min-width:40px; padding:0; position:absolute; right:calc(env(safe-area-inset-right) + 16px); top:calc(env(safe-area-inset-top) + 16px); z-index:5000000; } .wp-lightbox-overlay .close-button:focus,.wp-lightbox-overlay .close-button:hover,.wp-lightbox-overlay .close-button:not(:hover):not(:active):not(.has-background){ background:none; border:none; } .wp-lightbox-overlay .lightbox-image-container{ height:var(--wp--lightbox-container-height); left:50%; overflow:hidden; position:absolute; top:50%; transform:translate(-50%, -50%); transform-origin:top left; width:var(--wp--lightbox-container-width); z-index:9999999999; } .wp-lightbox-overlay .wp-block-image{ align-items:center; box-sizing:border-box; display:flex; height:100%; justify-content:center; margin:0; position:relative; transform-origin:0 0; width:100%; z-index:3000000; } .wp-lightbox-overlay .wp-block-image img{ height:var(--wp--lightbox-image-height); min-height:var(--wp--lightbox-image-height); min-width:var(--wp--lightbox-image-width); width:var(--wp--lightbox-image-width); } .wp-lightbox-overlay .wp-block-image figcaption{ display:none; } .wp-lightbox-overlay button{ background:none; border:none; } .wp-lightbox-overlay .scrim{ background-color:#fff; height:100%; opacity:.9; position:absolute; width:100%; z-index:2000000; } .wp-lightbox-overlay.active{ visibility:visible; } @media not (prefers-reduced-motion){ .wp-lightbox-overlay.active{ animation:turn-on-visibility .25s both; } .wp-lightbox-overlay.active img{ animation:turn-on-visibility .35s both; } .wp-lightbox-overlay.show-closing-animation:not(.active){ animation:turn-off-visibility .35s both; } .wp-lightbox-overlay.show-closing-animation:not(.active) img{ animation:turn-off-visibility .25s both; } .wp-lightbox-overlay.zoom.active{ animation:none; opacity:1; visibility:visible; } .wp-lightbox-overlay.zoom.active .lightbox-image-container{ animation:lightbox-zoom-in .4s; } .wp-lightbox-overlay.zoom.active .lightbox-image-container img{ animation:none; } .wp-lightbox-overlay.zoom.active .scrim{ animation:turn-on-visibility .4s forwards; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active){ animation:none; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container{ animation:lightbox-zoom-out .4s; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .lightbox-image-container img{ animation:none; } .wp-lightbox-overlay.zoom.show-closing-animation:not(.active) .scrim{ animation:turn-off-visibility .4s forwards; } } @keyframes show-content-image{ 0%{ visibility:hidden; } 99%{ visibility:hidden; } to{ visibility:visible; } } @keyframes turn-on-visibility{ 0%{ opacity:0; } to{ opacity:1; } } @keyframes turn-off-visibility{ 0%{ opacity:1; visibility:visible; } 99%{ opacity:0; visibility:visible; } to{ opacity:0; visibility:hidden; } } @keyframes lightbox-zoom-in{ 0%{ transform:translate(calc((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position)), calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale)); } to{ transform:translate(-50%, -50%) scale(1); } } @keyframes lightbox-zoom-out{ 0%{ transform:translate(-50%, -50%) scale(1); visibility:visible; } 99%{ visibility:visible; } to{ transform:translate(calc((-100vw + var(--wp--lightbox-scrollbar-width))/2 + var(--wp--lightbox-initial-left-position)), calc(-50vh + var(--wp--lightbox-initial-top-position))) scale(var(--wp--lightbox-scale)); visibility:hidden; } } ol.wp-block-latest-comments{ box-sizing:border-box; margin-left:0; } :where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment)){ line-height:1.1; } :where(.wp-block-latest-comments:not([style*=line-height] .wp-block-latest-comments__comment-excerpt p)){ line-height:1.8; } .has-dates :where(.wp-block-latest-comments:not([style*=line-height])),.has-excerpts :where(.wp-block-latest-comments:not([style*=line-height])){ line-height:1.5; } .wp-block-latest-comments .wp-block-latest-comments{ padding-left:0; } .wp-block-latest-comments__comment{ list-style:none; margin-bottom:1em; } .has-avatars .wp-block-latest-comments__comment{ list-style:none; min-height:2.25em; } .has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-excerpt,.has-avatars .wp-block-latest-comments__comment .wp-block-latest-comments__comment-meta{ margin-left:3.25em; } .wp-block-latest-comments__comment-excerpt p{ font-size:.875em; margin:.36em 0 1.4em; } .wp-block-latest-comments__comment-date{ display:block; font-size:.75em; } .wp-block-latest-comments .avatar,.wp-block-latest-comments__comment-avatar{ border-radius:1.5em; display:block; float:left; height:2.5em; margin-right:.75em; width:2.5em; } .wp-block-latest-comments[class*=-font-size] a,.wp-block-latest-comments[style*=font-size] a{ font-size:inherit; } .wp-block-latest-posts{ box-sizing:border-box; } .wp-block-latest-posts.alignleft{ margin-right:2em; } .wp-block-latest-posts.alignright{ margin-left:2em; } .wp-block-latest-posts.wp-block-latest-posts__list{ list-style:none; } .wp-block-latest-posts.wp-block-latest-posts__list li{ clear:both; overflow-wrap:break-word; } .wp-block-latest-posts.is-grid{ display:flex; flex-wrap:wrap; } .wp-block-latest-posts.is-grid li{ margin:0 1.25em 1.25em 0; width:100%; } @media (min-width:600px){ .wp-block-latest-posts.columns-2 li{ width:calc(50% - .625em); } .wp-block-latest-posts.columns-2 li:nth-child(2n){ margin-right:0; } .wp-block-latest-posts.columns-3 li{ width:calc(33.33333% - .83333em); } .wp-block-latest-posts.columns-3 li:nth-child(3n){ margin-right:0; } .wp-block-latest-posts.columns-4 li{ width:calc(25% - .9375em); } .wp-block-latest-posts.columns-4 li:nth-child(4n){ margin-right:0; } .wp-block-latest-posts.columns-5 li{ width:calc(20% - 1em); } .wp-block-latest-posts.columns-5 li:nth-child(5n){ margin-right:0; } .wp-block-latest-posts.columns-6 li{ width:calc(16.66667% - 1.04167em); } .wp-block-latest-posts.columns-6 li:nth-child(6n){ margin-right:0; } } :root :where(.wp-block-latest-posts.is-grid){ padding:0; } :root :where(.wp-block-latest-posts.wp-block-latest-posts__list){ padding-left:0; } .wp-block-latest-posts__post-author,.wp-block-latest-posts__post-date{ display:block; font-size:.8125em; } .wp-block-latest-posts__post-excerpt,.wp-block-latest-posts__post-full-content{ margin-bottom:1em; margin-top:.5em; } .wp-block-latest-posts__featured-image a{ display:inline-block; } .wp-block-latest-posts__featured-image img{ height:auto; max-width:100%; width:auto; } .wp-block-latest-posts__featured-image.alignleft{ float:left; margin-right:1em; } .wp-block-latest-posts__featured-image.alignright{ float:right; margin-left:1em; } .wp-block-latest-posts__featured-image.aligncenter{ margin-bottom:1em; text-align:center; } ol,ul{ box-sizing:border-box; } :root :where(.wp-block-list.has-background){ padding:1.25em 2.375em; } .wp-block-loginout,.wp-block-media-text{ box-sizing:border-box; } .wp-block-media-text{ direction:ltr; display:grid; grid-template-columns:50% 1fr; grid-template-rows:auto; } .wp-block-media-text.has-media-on-the-right{ grid-template-columns:1fr 50%; } .wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-top>.wp-block-media-text__media{ align-self:start; } .wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-center>.wp-block-media-text__media,.wp-block-media-text>.wp-block-media-text__content,.wp-block-media-text>.wp-block-media-text__media{ align-self:center; } .wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__content,.wp-block-media-text.is-vertically-aligned-bottom>.wp-block-media-text__media{ align-self:end; } .wp-block-media-text>.wp-block-media-text__media{ grid-column:1; grid-row:1; margin:0; } .wp-block-media-text>.wp-block-media-text__content{ direction:ltr; grid-column:2; grid-row:1; padding:0 8%; word-break:break-word; } .wp-block-media-text.has-media-on-the-right>.wp-block-media-text__media{ grid-column:2; grid-row:1; } .wp-block-media-text.has-media-on-the-right>.wp-block-media-text__content{ grid-column:1; grid-row:1; } .wp-block-media-text__media a{ display:block; } .wp-block-media-text__media img,.wp-block-media-text__media video{ height:auto; max-width:unset; vertical-align:middle; width:100%; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media{ background-size:cover; height:100%; min-height:250px; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media>a{ display:block; height:100%; } .wp-block-media-text.is-image-fill>.wp-block-media-text__media img{ height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; clip:rect(0, 0, 0, 0); border:0; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media{ height:100%; min-height:250px; position:relative; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media>a{ display:block; height:100%; } .wp-block-media-text.is-image-fill-element>.wp-block-media-text__media img{ height:100%; object-fit:cover; position:absolute; width:100%; } @media (max-width:600px){ .wp-block-media-text.is-stacked-on-mobile{ grid-template-columns:100% !important; } .wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__media{ grid-column:1; grid-row:1; } .wp-block-media-text.is-stacked-on-mobile>.wp-block-media-text__content{ grid-column:1; grid-row:2; } } .wp-block-navigation{ position:relative; --navigation-layout-justification-setting:flex-start; --navigation-layout-direction:row; --navigation-layout-wrap:wrap; --navigation-layout-justify:flex-start; --navigation-layout-align:center; } .wp-block-navigation ul{ margin-bottom:0; margin-left:0; margin-top:0; padding-left:0; } .wp-block-navigation ul,.wp-block-navigation ul li{ list-style:none; padding:0; } .wp-block-navigation .wp-block-navigation-item{ align-items:center; display:flex; position:relative; } .wp-block-navigation .wp-block-navigation-item .wp-block-navigation__submenu-container:empty{ display:none; } .wp-block-navigation .wp-block-navigation-item__content{ display:block; } .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content{ color:inherit; } .wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-underline .wp-block-navigation-item__content:focus{ text-decoration:underline; } .wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:active,.wp-block-navigation.has-text-decoration-line-through .wp-block-navigation-item__content:focus{ text-decoration:line-through; } .wp-block-navigation :where(a),.wp-block-navigation :where(a:active),.wp-block-navigation :where(a:focus){ text-decoration:none; } .wp-block-navigation .wp-block-navigation__submenu-icon{ align-self:center; background-color:inherit; border:none; color:currentColor; display:inline-block; font-size:inherit; height:.6em; line-height:0; margin-left:.25em; padding:0; width:.6em; } .wp-block-navigation .wp-block-navigation__submenu-icon svg{ display:inline-block; stroke:currentColor; height:inherit; margin-top:.075em; width:inherit; } .wp-block-navigation.is-vertical{ --navigation-layout-direction:column; --navigation-layout-justify:initial; --navigation-layout-align:flex-start; } .wp-block-navigation.no-wrap{ --navigation-layout-wrap:nowrap; } .wp-block-navigation.items-justified-center{ --navigation-layout-justification-setting:center; --navigation-layout-justify:center; } .wp-block-navigation.items-justified-center.is-vertical{ --navigation-layout-align:center; } .wp-block-navigation.items-justified-right{ --navigation-layout-justification-setting:flex-end; --navigation-layout-justify:flex-end; } .wp-block-navigation.items-justified-right.is-vertical{ --navigation-layout-align:flex-end; } .wp-block-navigation.items-justified-space-between{ --navigation-layout-justification-setting:space-between; --navigation-layout-justify:space-between; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ align-items:normal; background-color:inherit; color:inherit; display:flex; flex-direction:column; height:0; left:-1px; opacity:0; overflow:hidden; position:absolute; top:100%; visibility:hidden; width:0; z-index:2; } @media not (prefers-reduced-motion){ .wp-block-navigation .has-child .wp-block-navigation__submenu-container{ transition:opacity .1s linear; } } .wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content{ display:flex; flex-grow:1; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container>.wp-block-navigation-item>.wp-block-navigation-item__content .wp-block-navigation__submenu-icon{ margin-left:auto; margin-right:0; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation-item__content{ margin:0; } @media (min-width:782px){ .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:100%; top:-1px; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{ background:#0000; content:""; display:block; height:100%; position:absolute; right:100%; width:.5em; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon{ margin-right:.25em; } .wp-block-navigation .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-icon svg{ transform:rotate(-90deg); } } .wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded=true]~.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):hover>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child:not(.open-on-click):not(.open-on-hover-click):focus-within>.wp-block-navigation__submenu-container{ height:auto; min-width:200px; opacity:1; overflow:visible; visibility:visible; width:auto; } .wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container{ left:0; top:100%; } @media (min-width:782px){ .wp-block-navigation.has-background .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:100%; top:0; } } .wp-block-navigation-submenu{ display:flex; position:relative; } .wp-block-navigation-submenu .wp-block-navigation__submenu-icon svg{ stroke:currentColor; } button.wp-block-navigation-item__content{ background-color:initial; border:none; color:currentColor; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-align:left; text-transform:inherit; } .wp-block-navigation-submenu__toggle{ cursor:pointer; } .wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle{ padding-left:0; padding-right:.85em; } .wp-block-navigation-item.open-on-click .wp-block-navigation-submenu__toggle+.wp-block-navigation__submenu-icon{ margin-left:-.6em; pointer-events:none; } .wp-block-navigation-item.open-on-click button.wp-block-navigation-item__content:not(.wp-block-navigation-submenu__toggle){ padding:0; } .wp-block-navigation .wp-block-page-list,.wp-block-navigation__container,.wp-block-navigation__responsive-close,.wp-block-navigation__responsive-container,.wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-dialog{ gap:inherit; } :where(.wp-block-navigation.has-background .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation.has-background .wp-block-navigation-submenu a:not(.wp-element-button)){ padding:.5em 1em; } :where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu a:not(.wp-element-button)),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-submenu button.wp-block-navigation-item__content),:where(.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-pages-list__item button.wp-block-navigation-item__content){ padding:.5em 1em; } .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container{ left:auto; right:0; } .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:-1px; right:-1px; } @media (min-width:782px){ .wp-block-navigation.items-justified-right .wp-block-navigation__container .has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-right .wp-block-page-list>.has-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between .wp-block-page-list>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation.items-justified-space-between>.wp-block-navigation__container>.has-child:last-child .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{ left:auto; right:100%; } } .wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container{ background-color:#fff; border:1px solid #00000026; } .wp-block-navigation.has-background .wp-block-navigation__submenu-container{ background-color:inherit; } .wp-block-navigation:not(.has-text-color) .wp-block-navigation__submenu-container{ color:#000; } .wp-block-navigation__container{ align-items:var(--navigation-layout-align, initial); display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); list-style:none; margin:0; padding-left:0; } .wp-block-navigation__container .is-responsive{ display:none; } .wp-block-navigation__container:only-child,.wp-block-page-list:only-child{ flex-grow:1; } @keyframes overlay-menu__fade-in-animation{ 0%{ opacity:0; transform:translateY(.5em); } to{ opacity:1; transform:translateY(0); } } .wp-block-navigation__responsive-container{ bottom:0; display:none; left:0; position:fixed; right:0; top:0; } .wp-block-navigation__responsive-container :where(.wp-block-navigation-item a){ color:inherit; } .wp-block-navigation__responsive-container .wp-block-navigation__responsive-container-content{ align-items:var(--navigation-layout-align, initial); display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); } .wp-block-navigation__responsive-container:not(.is-menu-open.is-menu-open){ background-color:inherit !important; color:inherit !important; } .wp-block-navigation__responsive-container.is-menu-open{ background-color:inherit; display:flex; flex-direction:column; overflow:auto; padding:clamp(1rem, var(--wp--style--root--padding-top), 20rem) clamp(1rem, var(--wp--style--root--padding-right), 20rem) clamp(1rem, var(--wp--style--root--padding-bottom), 20rem) clamp(1rem, var(--wp--style--root--padding-left), 20rem); z-index:100000; } @media not (prefers-reduced-motion){ .wp-block-navigation__responsive-container.is-menu-open{ animation:overlay-menu__fade-in-animation .1s ease-out; animation-fill-mode:forwards; } } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content{ align-items:var(--navigation-layout-justification-setting, inherit); display:flex; flex-direction:column; flex-wrap:nowrap; overflow:visible; padding-top:calc(2rem + 24px); } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{ justify-content:flex-start; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-icon{ display:none; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container{ border:none; height:auto; min-width:200px; opacity:1; overflow:initial; padding-left:2rem; padding-right:2rem; position:static; visibility:visible; width:auto; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{ gap:inherit; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container{ padding-top:var(--wp--style--block-gap, 2em); } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content{ padding:0; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .wp-block-page-list{ align-items:var(--navigation-layout-justification-setting, initial); display:flex; flex-direction:column; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item .wp-block-navigation__submenu-container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,.wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list{ background:#0000 !important; color:inherit !important; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{ left:auto; right:auto; } @media (min-width:600px){ .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open){ background-color:inherit; display:block; position:relative; width:100%; z-index:auto; } .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) .wp-block-navigation__responsive-container-close{ display:none; } .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container.wp-block-navigation__submenu-container{ left:0; } } .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open{ background-color:#fff; } .wp-block-navigation:not(.has-text-color) .wp-block-navigation__responsive-container.is-menu-open{ color:#000; } .wp-block-navigation__toggle_button_label{ font-size:1rem; font-weight:700; } .wp-block-navigation__responsive-container-close,.wp-block-navigation__responsive-container-open{ background:#0000; border:none; color:currentColor; cursor:pointer; margin:0; padding:0; text-transform:inherit; vertical-align:middle; } .wp-block-navigation__responsive-container-close svg,.wp-block-navigation__responsive-container-open svg{ fill:currentColor; display:block; height:24px; pointer-events:none; width:24px; } .wp-block-navigation__responsive-container-open{ display:flex; } .wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{ font-family:inherit; font-size:inherit; font-weight:inherit; } @media (min-width:600px){ .wp-block-navigation__responsive-container-open:not(.always-shown){ display:none; } } .wp-block-navigation__responsive-container-close{ position:absolute; right:0; top:0; z-index:2; } .wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close{ font-family:inherit; font-size:inherit; font-weight:inherit; } .wp-block-navigation__responsive-close{ width:100%; } .has-modal-open .wp-block-navigation__responsive-close{ margin-left:auto; margin-right:auto; max-width:var(--wp--style--global--wide-size, 100%); } .wp-block-navigation__responsive-close:focus{ outline:none; } .is-menu-open .wp-block-navigation__responsive-close,.is-menu-open .wp-block-navigation__responsive-container-content,.is-menu-open .wp-block-navigation__responsive-dialog{ box-sizing:border-box; } .wp-block-navigation__responsive-dialog{ position:relative; } .has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{ margin-top:46px; } @media (min-width:782px){ .has-modal-open .admin-bar .is-menu-open .wp-block-navigation__responsive-dialog{ margin-top:32px; } } html.has-modal-open{ overflow:hidden; } .wp-block-navigation .wp-block-navigation-item__label{ overflow-wrap:break-word; } .wp-block-navigation .wp-block-navigation-item__description{ display:none; } .link-ui-tools{ border-top:1px solid #f0f0f0; padding:8px; } .link-ui-block-inserter{ padding-top:8px; } .link-ui-block-inserter__back{ margin-left:8px; text-transform:uppercase; } .wp-block-navigation .wp-block-page-list{ align-items:var(--navigation-layout-align, initial); background-color:inherit; display:flex; flex-direction:var(--navigation-layout-direction, initial); flex-wrap:var(--navigation-layout-wrap, wrap); justify-content:var(--navigation-layout-justify, initial); } .wp-block-navigation .wp-block-navigation-item{ background-color:inherit; } .wp-block-page-list{ box-sizing:border-box; } .is-small-text{ font-size:.875em; } .is-regular-text{ font-size:1em; } .is-large-text{ font-size:2.25em; } .is-larger-text{ font-size:3em; } .has-drop-cap:not(:focus):first-letter{ float:left; font-size:8.4em; font-style:normal; font-weight:100; line-height:.68; margin:.05em .1em 0 0; text-transform:uppercase; } body.rtl .has-drop-cap:not(:focus):first-letter{ float:none; margin-left:.1em; } p.has-drop-cap.has-background{ overflow:hidden; } :root :where(p.has-background){ padding:1.25em 2.375em; } :where(p.has-text-color:not(.has-link-color)) a{ color:inherit; } p.has-text-align-left[style*="writing-mode:vertical-lr"],p.has-text-align-right[style*="writing-mode:vertical-rl"]{ rotate:180deg; } .wp-block-post-author{ box-sizing:border-box; display:flex; flex-wrap:wrap; } .wp-block-post-author__byline{ font-size:.5em; margin-bottom:0; margin-top:0; width:100%; } .wp-block-post-author__avatar{ margin-right:1em; } .wp-block-post-author__bio{ font-size:.7em; margin-bottom:.7em; } .wp-block-post-author__content{ flex-basis:0; flex-grow:1; } .wp-block-post-author__name{ margin:0; } .wp-block-post-author-biography{ box-sizing:border-box; } :where(.wp-block-post-comments-form) input:not([type=submit]),:where(.wp-block-post-comments-form) textarea{ border:1px solid #949494; font-family:inherit; font-size:1em; } :where(.wp-block-post-comments-form) input:where(:not([type=submit]):not([type=checkbox])),:where(.wp-block-post-comments-form) textarea{ padding:calc(.667em + 2px); } .wp-block-post-comments-form{ box-sizing:border-box; } .wp-block-post-comments-form[style*=font-weight] :where(.comment-reply-title){ font-weight:inherit; } .wp-block-post-comments-form[style*=font-family] :where(.comment-reply-title){ font-family:inherit; } .wp-block-post-comments-form[class*=-font-size] :where(.comment-reply-title),.wp-block-post-comments-form[style*=font-size] :where(.comment-reply-title){ font-size:inherit; } .wp-block-post-comments-form[style*=line-height] :where(.comment-reply-title){ line-height:inherit; } .wp-block-post-comments-form[style*=font-style] :where(.comment-reply-title){ font-style:inherit; } .wp-block-post-comments-form[style*=letter-spacing] :where(.comment-reply-title){ letter-spacing:inherit; } .wp-block-post-comments-form :where(input[type=submit]){ box-shadow:none; cursor:pointer; display:inline-block; overflow-wrap:break-word; text-align:center; } .wp-block-post-comments-form .comment-form input:not([type=submit]):not([type=checkbox]):not([type=hidden]),.wp-block-post-comments-form .comment-form textarea{ box-sizing:border-box; display:block; width:100%; } .wp-block-post-comments-form .comment-form-author label,.wp-block-post-comments-form .comment-form-email label,.wp-block-post-comments-form .comment-form-url label{ display:block; margin-bottom:.25em; } .wp-block-post-comments-form .comment-form-cookies-consent{ display:flex; gap:.25em; } .wp-block-post-comments-form .comment-form-cookies-consent #wp-comment-cookies-consent{ margin-top:.35em; } .wp-block-post-comments-form .comment-reply-title{ margin-bottom:0; } .wp-block-post-comments-form .comment-reply-title :where(small){ font-size:var(--wp--preset--font-size--medium, smaller); margin-left:.5em; } .wp-block-post-comments-count{ box-sizing:border-box; } .wp-block-post-content{ display:flow-root; } .wp-block-post-comments-link,.wp-block-post-date{ box-sizing:border-box; } :where(.wp-block-post-excerpt){ box-sizing:border-box; margin-bottom:var(--wp--style--block-gap); margin-top:var(--wp--style--block-gap); } .wp-block-post-excerpt__excerpt{ margin-bottom:0; margin-top:0; } .wp-block-post-excerpt__more-text{ margin-bottom:0; margin-top:var(--wp--style--block-gap); } .wp-block-post-excerpt__more-link{ display:inline-block; } .wp-block-post-featured-image{ margin-left:0; margin-right:0; } .wp-block-post-featured-image a{ display:block; height:100%; } .wp-block-post-featured-image :where(img){ box-sizing:border-box; height:auto; max-width:100%; vertical-align:bottom; width:100%; } .wp-block-post-featured-image.alignfull img,.wp-block-post-featured-image.alignwide img{ width:100%; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim{ background-color:#000; inset:0; position:absolute; } .wp-block-post-featured-image{ position:relative; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-gradient{ background-color:initial; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-0{ opacity:0; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-10{ opacity:.1; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-20{ opacity:.2; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-30{ opacity:.3; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-40{ opacity:.4; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-50{ opacity:.5; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-60{ opacity:.6; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-70{ opacity:.7; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-80{ opacity:.8; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-90{ opacity:.9; } .wp-block-post-featured-image .wp-block-post-featured-image__overlay.has-background-dim-100{ opacity:1; } .wp-block-post-featured-image:where(.alignleft,.alignright){ width:100%; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous{ display:inline-block; margin-right:1ch; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-previous:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next{ display:inline-block; margin-left:1ch; } .wp-block-post-navigation-link .wp-block-post-navigation-link__arrow-next:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-post-navigation-link.has-text-align-left[style*="writing-mode: vertical-lr"],.wp-block-post-navigation-link.has-text-align-right[style*="writing-mode: vertical-rl"]{ rotate:180deg; } .wp-block-post-terms{ box-sizing:border-box; } .wp-block-post-terms .wp-block-post-terms__separator{ white-space:pre-wrap; } .wp-block-post-time-to-read,.wp-block-post-title{ box-sizing:border-box; } .wp-block-post-title{ word-break:break-word; } .wp-block-post-title :where(a){ display:inline-block; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-decoration:inherit; } .wp-block-post-author-name,.wp-block-preformatted{ box-sizing:border-box; } .wp-block-preformatted{ white-space:pre-wrap; } :where(.wp-block-preformatted.has-background){ padding:1.25em 2.375em; } .wp-block-pullquote{ box-sizing:border-box; margin:0 0 1em; overflow-wrap:break-word; padding:4em 0; text-align:center; } .wp-block-pullquote blockquote,.wp-block-pullquote cite,.wp-block-pullquote p{ color:inherit; } .wp-block-pullquote blockquote{ margin:0; } .wp-block-pullquote p{ margin-top:0; } .wp-block-pullquote p:last-child{ margin-bottom:0; } .wp-block-pullquote.alignleft,.wp-block-pullquote.alignright{ max-width:420px; } .wp-block-pullquote cite,.wp-block-pullquote footer{ position:relative; } .wp-block-pullquote .has-text-color a{ color:inherit; } .wp-block-pullquote.has-text-align-left blockquote{ text-align:left; } .wp-block-pullquote.has-text-align-right blockquote{ text-align:right; } .wp-block-pullquote.has-text-align-center blockquote{ text-align:center; } .wp-block-pullquote.is-style-solid-color{ border:none; } .wp-block-pullquote.is-style-solid-color blockquote{ margin-left:auto; margin-right:auto; max-width:60%; } .wp-block-pullquote.is-style-solid-color blockquote p{ font-size:2em; margin-bottom:0; margin-top:0; } .wp-block-pullquote.is-style-solid-color blockquote cite{ font-style:normal; text-transform:none; } .wp-block-pullquote cite{ color:inherit; display:block; } .wp-block-post-template{ box-sizing:border-box; list-style:none; margin-bottom:0; margin-top:0; max-width:100%; padding:0; } .wp-block-post-template.is-flex-container{ display:flex; flex-direction:row; flex-wrap:wrap; gap:1.25em; } .wp-block-post-template.is-flex-container>li{ margin:0; width:100%; } @media (min-width:600px){ .wp-block-post-template.is-flex-container.is-flex-container.columns-2>li{ width:calc(50% - .625em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-3>li{ width:calc(33.33333% - .83333em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-4>li{ width:calc(25% - .9375em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-5>li{ width:calc(20% - 1em); } .wp-block-post-template.is-flex-container.is-flex-container.columns-6>li{ width:calc(16.66667% - 1.04167em); } } @media (max-width:600px){ .wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid.wp-block-post-template-is-layout-grid{ grid-template-columns:1fr; } } .wp-block-post-template-is-layout-constrained>li>.alignright,.wp-block-post-template-is-layout-flow>li>.alignright{ float:right; margin-inline-end:0; margin-inline-start:2em; } .wp-block-post-template-is-layout-constrained>li>.alignleft,.wp-block-post-template-is-layout-flow>li>.alignleft{ float:left; margin-inline-end:2em; margin-inline-start:0; } .wp-block-post-template-is-layout-constrained>li>.aligncenter,.wp-block-post-template-is-layout-flow>li>.aligncenter{ margin-inline-end:auto; margin-inline-start:auto; } .wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-next:last-of-type{ margin-inline-start:auto; } .wp-block-query-pagination.is-content-justification-space-between>.wp-block-query-pagination-previous:first-child{ margin-inline-end:auto; } .wp-block-query-pagination .wp-block-query-pagination-previous-arrow{ display:inline-block; margin-right:1ch; } .wp-block-query-pagination .wp-block-query-pagination-previous-arrow:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-query-pagination .wp-block-query-pagination-next-arrow{ display:inline-block; margin-left:1ch; } .wp-block-query-pagination .wp-block-query-pagination-next-arrow:not(.is-arrow-chevron){ transform:scaleX(1); } .wp-block-query-pagination.aligncenter{ justify-content:center; } .wp-block-query-title,.wp-block-query-total,.wp-block-quote{ box-sizing:border-box; } .wp-block-quote{ overflow-wrap:break-word; } .wp-block-quote.is-large:where(:not(.is-style-plain)),.wp-block-quote.is-style-large:where(:not(.is-style-plain)){ margin-bottom:1em; padding:0 1em; } .wp-block-quote.is-large:where(:not(.is-style-plain)) p,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) p{ font-size:1.5em; font-style:italic; line-height:1.6; } .wp-block-quote.is-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-large:where(:not(.is-style-plain)) footer,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) cite,.wp-block-quote.is-style-large:where(:not(.is-style-plain)) footer{ font-size:1.125em; text-align:right; } .wp-block-quote>cite{ display:block; } .wp-block-read-more{ display:block; width:fit-content; } .wp-block-read-more:where(:not([style*=text-decoration])){ text-decoration:none; } .wp-block-read-more:where(:not([style*=text-decoration])):active,.wp-block-read-more:where(:not([style*=text-decoration])):focus{ text-decoration:none; } ul.wp-block-rss.alignleft{ margin-right:2em; } ul.wp-block-rss.alignright{ margin-left:2em; } ul.wp-block-rss.is-grid{ display:flex; flex-wrap:wrap; padding:0; } ul.wp-block-rss.is-grid li{ margin:0 1em 1em 0; width:100%; } @media (min-width:600px){ ul.wp-block-rss.columns-2 li{ width:calc(50% - 1em); } ul.wp-block-rss.columns-3 li{ width:calc(33.33333% - 1em); } ul.wp-block-rss.columns-4 li{ width:calc(25% - 1em); } ul.wp-block-rss.columns-5 li{ width:calc(20% - 1em); } ul.wp-block-rss.columns-6 li{ width:calc(16.66667% - 1em); } } .wp-block-rss__item-author,.wp-block-rss__item-publish-date{ display:block; font-size:.8125em; } .wp-block-rss{ box-sizing:border-box; list-style:none; padding:0; } .wp-block-search__button{ margin-left:10px; word-break:normal; } .wp-block-search__button.has-icon{ line-height:0; } .wp-block-search__button svg{ height:1.25em; min-height:24px; min-width:24px; width:1.25em; fill:currentColor; vertical-align:text-bottom; } :where(.wp-block-search__button){ border:1px solid #ccc; padding:6px 10px; } .wp-block-search__inside-wrapper{ display:flex; flex:auto; flex-wrap:nowrap; max-width:100%; } .wp-block-search__label{ width:100%; } .wp-block-search__input{ appearance:none; border:1px solid #949494; flex-grow:1; margin-left:0; margin-right:0; min-width:3rem; padding:8px; text-decoration:unset !important; } .wp-block-search.wp-block-search__button-only .wp-block-search__button{ box-sizing:border-box; display:flex; flex-shrink:0; justify-content:center; margin-left:0; max-width:100%; } .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{ min-width:0 !important; transition-property:width; } .wp-block-search.wp-block-search__button-only .wp-block-search__input{ flex-basis:100%; transition-duration:.3s; } .wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden,.wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__inside-wrapper{ overflow:hidden; } .wp-block-search.wp-block-search__button-only.wp-block-search__searchfield-hidden .wp-block-search__input{ border-left-width:0 !important; border-right-width:0 !important; flex-basis:0; flex-grow:0; margin:0; min-width:0 !important; padding-left:0 !important; padding-right:0 !important; width:0 !important; } :where(.wp-block-search__input){ font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-transform:inherit; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper){ border:1px solid #949494; box-sizing:border-box; padding:4px; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input{ border:none; border-radius:0; padding:0 4px; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) .wp-block-search__input:focus{ outline:none; } :where(.wp-block-search__button-inside .wp-block-search__inside-wrapper) :where(.wp-block-search__button){ padding:4px 8px; } .wp-block-search.aligncenter .wp-block-search__inside-wrapper{ margin:auto; } .wp-block[data-align=right] .wp-block-search.wp-block-search__button-only .wp-block-search__inside-wrapper{ float:right; } .wp-block-separator{ border:none; border-top:2px solid; } :root :where(.wp-block-separator.is-style-dots){ height:auto; line-height:1; text-align:center; } :root :where(.wp-block-separator.is-style-dots):before{ color:currentColor; content:"···"; font-family:serif; font-size:1.5em; letter-spacing:2em; padding-left:2em; } .wp-block-separator.is-style-dots{ background:none !important; border:none !important; } .wp-block-site-logo{ box-sizing:border-box; line-height:0; } .wp-block-site-logo a{ display:inline-block; line-height:0; } .wp-block-site-logo.is-default-size img{ height:auto; width:120px; } .wp-block-site-logo img{ height:auto; max-width:100%; } .wp-block-site-logo a,.wp-block-site-logo img{ border-radius:inherit; } .wp-block-site-logo.aligncenter{ margin-left:auto; margin-right:auto; text-align:center; } :root :where(.wp-block-site-logo.is-style-rounded){ border-radius:9999px; } .wp-block-site-tagline,.wp-block-site-title{ box-sizing:border-box; } .wp-block-site-title :where(a){ color:inherit; font-family:inherit; font-size:inherit; font-style:inherit; font-weight:inherit; letter-spacing:inherit; line-height:inherit; text-decoration:inherit; } .wp-block-social-links{ background:none; box-sizing:border-box; margin-left:0; padding-left:0; padding-right:0; text-indent:0; } .wp-block-social-links .wp-social-link a,.wp-block-social-links .wp-social-link a:hover{ border-bottom:0; box-shadow:none; text-decoration:none; } .wp-block-social-links .wp-social-link svg{ height:1em; width:1em; } .wp-block-social-links .wp-social-link span:not(.screen-reader-text){ font-size:.65em; margin-left:.5em; margin-right:.5em; } .wp-block-social-links.has-small-icon-size{ font-size:16px; } .wp-block-social-links,.wp-block-social-links.has-normal-icon-size{ font-size:24px; } .wp-block-social-links.has-large-icon-size{ font-size:36px; } .wp-block-social-links.has-huge-icon-size{ font-size:48px; } .wp-block-social-links.aligncenter{ display:flex; justify-content:center; } .wp-block-social-links.alignright{ justify-content:flex-end; } .wp-block-social-link{ border-radius:9999px; display:block; height:auto; } @media not (prefers-reduced-motion){ .wp-block-social-link{ transition:transform .1s ease; } } .wp-block-social-link a{ align-items:center; display:flex; line-height:0; } .wp-block-social-link:hover{ transform:scale(1.1); } .wp-block-social-links .wp-block-social-link.wp-social-link{ display:inline-block; margin:0; padding:0; } .wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor svg,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:active,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:hover,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:visited{ color:currentColor; fill:currentColor; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link{ background-color:#f0f0f0; color:#444; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-amazon{ background-color:#f90; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bandcamp{ background-color:#1ea0c3; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-behance{ background-color:#0757fe; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bluesky{ background-color:#0a7aff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-codepen{ background-color:#1e1f26; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-deviantart{ background-color:#02e49b; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-discord{ background-color:#5865f2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dribbble{ background-color:#e94c89; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dropbox{ background-color:#4280ff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-etsy{ background-color:#f45800; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-facebook{ background-color:#0866ff; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-fivehundredpx{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-flickr{ background-color:#0461dd; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-foursquare{ background-color:#e65678; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-github{ background-color:#24292d; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-goodreads{ background-color:#eceadd; color:#382110; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-google{ background-color:#ea4434; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-gravatar{ background-color:#1d4fc4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-instagram{ background-color:#f00075; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-lastfm{ background-color:#e21b24; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-linkedin{ background-color:#0d66c2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-mastodon{ background-color:#3288d4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-medium{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-meetup{ background-color:#f6405f; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-patreon{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pinterest{ background-color:#e60122; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pocket{ background-color:#ef4155; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-reddit{ background-color:#ff4500; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-skype{ background-color:#0478d7; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-snapchat{ background-color:#fefc00; color:#fff; stroke:#000; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-soundcloud{ background-color:#ff5600; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-spotify{ background-color:#1bd760; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-telegram{ background-color:#2aabee; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-threads{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tiktok{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tumblr{ background-color:#011835; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitch{ background-color:#6440a4; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitter{ background-color:#1da1f2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vimeo{ background-color:#1eb7ea; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vk{ background-color:#4680c2; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-wordpress{ background-color:#3499cd; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-whatsapp{ background-color:#25d366; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-x{ background-color:#000; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-yelp{ background-color:#d32422; color:#fff; } :where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-youtube{ background-color:red; color:#fff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link{ background:none; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link svg{ height:1.25em; width:1.25em; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-amazon{ color:#f90; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bandcamp{ color:#1ea0c3; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-behance{ color:#0757fe; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bluesky{ color:#0a7aff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-codepen{ color:#1e1f26; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-deviantart{ color:#02e49b; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-discord{ color:#5865f2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dribbble{ color:#e94c89; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dropbox{ color:#4280ff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-etsy{ color:#f45800; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-facebook{ color:#0866ff; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-fivehundredpx{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-flickr{ color:#0461dd; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-foursquare{ color:#e65678; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-github{ color:#24292d; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-goodreads{ color:#382110; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-google{ color:#ea4434; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-gravatar{ color:#1d4fc4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-instagram{ color:#f00075; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-lastfm{ color:#e21b24; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-linkedin{ color:#0d66c2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-mastodon{ color:#3288d4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-medium{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-meetup{ color:#f6405f; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-patreon{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pinterest{ color:#e60122; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pocket{ color:#ef4155; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-reddit{ color:#ff4500; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-skype{ color:#0478d7; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-snapchat{ color:#fff; stroke:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-soundcloud{ color:#ff5600; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-spotify{ color:#1bd760; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-telegram{ color:#2aabee; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-threads{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tiktok{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tumblr{ color:#011835; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitch{ color:#6440a4; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitter{ color:#1da1f2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vimeo{ color:#1eb7ea; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vk{ color:#4680c2; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-whatsapp{ color:#25d366; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-wordpress{ color:#3499cd; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-x{ color:#000; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-yelp{ color:#d32422; } :where(.wp-block-social-links.is-style-logos-only) .wp-social-link-youtube{ color:red; } .wp-block-social-links.is-style-pill-shape .wp-social-link{ width:auto; } :root :where(.wp-block-social-links .wp-social-link a){ padding:.25em; } :root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a){ padding:0; } :root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a){ padding-left:.6666666667em; padding-right:.6666666667em; } .wp-block-social-links:not(.has-icon-color):not(.has-icon-background-color) .wp-social-link-snapchat .wp-block-social-link-label{ color:#000; } .wp-block-spacer{ clear:both; } .wp-block-tag-cloud{ box-sizing:border-box; } .wp-block-tag-cloud.aligncenter{ justify-content:center; text-align:center; } .wp-block-tag-cloud.alignfull{ padding-left:1em; padding-right:1em; } .wp-block-tag-cloud a{ display:inline-block; margin-right:5px; } .wp-block-tag-cloud span{ display:inline-block; margin-left:5px; text-decoration:none; } :root :where(.wp-block-tag-cloud.is-style-outline){ display:flex; flex-wrap:wrap; gap:1ch; } :root :where(.wp-block-tag-cloud.is-style-outline a){ border:1px solid; font-size:unset !important; margin-right:0; padding:1ch 2ch; text-decoration:none !important; } .wp-block-table{ overflow-x:auto; } .wp-block-table table{ border-collapse:collapse; width:100%; } .wp-block-table thead{ border-bottom:3px solid; } .wp-block-table tfoot{ border-top:3px solid; } .wp-block-table td,.wp-block-table th{ border:1px solid; padding:.5em; } .wp-block-table .has-fixed-layout{ table-layout:fixed; width:100%; } .wp-block-table .has-fixed-layout td,.wp-block-table .has-fixed-layout th{ word-break:break-word; } .wp-block-table.aligncenter,.wp-block-table.alignleft,.wp-block-table.alignright{ display:table; width:auto; } .wp-block-table.aligncenter td,.wp-block-table.aligncenter th,.wp-block-table.alignleft td,.wp-block-table.alignleft th,.wp-block-table.alignright td,.wp-block-table.alignright th{ word-break:break-word; } .wp-block-table .has-subtle-light-gray-background-color{ background-color:#f3f4f5; } .wp-block-table .has-subtle-pale-green-background-color{ background-color:#e9fbe5; } .wp-block-table .has-subtle-pale-blue-background-color{ background-color:#e7f5fe; } .wp-block-table .has-subtle-pale-pink-background-color{ background-color:#fcf0ef; } .wp-block-table.is-style-stripes{ background-color:initial; border-bottom:1px solid #f0f0f0; border-collapse:inherit; border-spacing:0; } .wp-block-table.is-style-stripes tbody tr:nth-child(odd){ background-color:#f0f0f0; } .wp-block-table.is-style-stripes.has-subtle-light-gray-background-color tbody tr:nth-child(odd){ background-color:#f3f4f5; } .wp-block-table.is-style-stripes.has-subtle-pale-green-background-color tbody tr:nth-child(odd){ background-color:#e9fbe5; } .wp-block-table.is-style-stripes.has-subtle-pale-blue-background-color tbody tr:nth-child(odd){ background-color:#e7f5fe; } .wp-block-table.is-style-stripes.has-subtle-pale-pink-background-color tbody tr:nth-child(odd){ background-color:#fcf0ef; } .wp-block-table.is-style-stripes td,.wp-block-table.is-style-stripes th{ border-color:#0000; } .wp-block-table .has-border-color td,.wp-block-table .has-border-color th,.wp-block-table .has-border-color tr,.wp-block-table .has-border-color>*{ border-color:inherit; } .wp-block-table table[style*=border-top-color] tr:first-child,.wp-block-table table[style*=border-top-color] tr:first-child td,.wp-block-table table[style*=border-top-color] tr:first-child th,.wp-block-table table[style*=border-top-color]>*,.wp-block-table table[style*=border-top-color]>* td,.wp-block-table table[style*=border-top-color]>* th{ border-top-color:inherit; } .wp-block-table table[style*=border-top-color] tr:not(:first-child){ border-top-color:initial; } .wp-block-table table[style*=border-right-color] td:last-child,.wp-block-table table[style*=border-right-color] th,.wp-block-table table[style*=border-right-color] tr,.wp-block-table table[style*=border-right-color]>*{ border-right-color:inherit; } .wp-block-table table[style*=border-bottom-color] tr:last-child,.wp-block-table table[style*=border-bottom-color] tr:last-child td,.wp-block-table table[style*=border-bottom-color] tr:last-child th,.wp-block-table table[style*=border-bottom-color]>*,.wp-block-table table[style*=border-bottom-color]>* td,.wp-block-table table[style*=border-bottom-color]>* th{ border-bottom-color:inherit; } .wp-block-table table[style*=border-bottom-color] tr:not(:last-child){ border-bottom-color:initial; } .wp-block-table table[style*=border-left-color] td:first-child,.wp-block-table table[style*=border-left-color] th,.wp-block-table table[style*=border-left-color] tr,.wp-block-table table[style*=border-left-color]>*{ border-left-color:inherit; } .wp-block-table table[style*=border-style] td,.wp-block-table table[style*=border-style] th,.wp-block-table table[style*=border-style] tr,.wp-block-table table[style*=border-style]>*{ border-style:inherit; } .wp-block-table table[style*=border-width] td,.wp-block-table table[style*=border-width] th,.wp-block-table table[style*=border-width] tr,.wp-block-table table[style*=border-width]>*{ border-style:inherit; border-width:inherit; } :root :where(.wp-block-table-of-contents){ box-sizing:border-box; } :where(.wp-block-term-description){ box-sizing:border-box; margin-bottom:var(--wp--style--block-gap); margin-top:var(--wp--style--block-gap); } .wp-block-term-description p{ margin-bottom:0; margin-top:0; } .wp-block-text-columns,.wp-block-text-columns.aligncenter{ display:flex; } .wp-block-text-columns .wp-block-column{ margin:0 1em; padding:0; } .wp-block-text-columns .wp-block-column:first-child{ margin-left:0; } .wp-block-text-columns .wp-block-column:last-child{ margin-right:0; } .wp-block-text-columns.columns-2 .wp-block-column{ width:50%; } .wp-block-text-columns.columns-3 .wp-block-column{ width:33.3333333333%; } .wp-block-text-columns.columns-4 .wp-block-column{ width:25%; } pre.wp-block-verse{ overflow:auto; white-space:pre-wrap; } :where(pre.wp-block-verse){ font-family:inherit; } .wp-block-video{ box-sizing:border-box; } .wp-block-video video{ vertical-align:middle; width:100%; } @supports (position:sticky){ .wp-block-video [poster]{ object-fit:cover; } } .wp-block-video.aligncenter{ text-align:center; } .wp-block-video :where(figcaption){ margin-bottom:1em; margin-top:.5em; } .editor-styles-wrapper,.entry-content{ counter-reset:footnotes; } a[data-fn].fn{ counter-increment:footnotes; display:inline-flex; font-size:smaller; text-decoration:none; text-indent:-9999999px; vertical-align:super; } a[data-fn].fn:after{ content:"[" counter(footnotes) "]"; float:left; text-indent:0; } .wp-element-button{ cursor:pointer; } :root{ --wp--preset--font-size--normal:16px; --wp--preset--font-size--huge:42px; } :root .has-very-light-gray-background-color{ background-color:#eee; } :root .has-very-dark-gray-background-color{ background-color:#313131; } :root .has-very-light-gray-color{ color:#eee; } :root .has-very-dark-gray-color{ color:#313131; } :root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{ background:linear-gradient(135deg, #00d084, #0693e3); } :root .has-purple-crush-gradient-background{ background:linear-gradient(135deg, #34e2e4, #4721fb 50%, #ab1dfe); } :root .has-hazy-dawn-gradient-background{ background:linear-gradient(135deg, #faaca8, #dad0ec); } :root .has-subdued-olive-gradient-background{ background:linear-gradient(135deg, #fafae1, #67a671); } :root .has-atomic-cream-gradient-background{ background:linear-gradient(135deg, #fdd79a, #004a59); } :root .has-nightshade-gradient-background{ background:linear-gradient(135deg, #330968, #31cdcf); } :root .has-midnight-gradient-background{ background:linear-gradient(135deg, #020381, #2874fc); } .has-regular-font-size{ font-size:1em; } .has-larger-font-size{ font-size:2.625em; } .has-normal-font-size{ font-size:var(--wp--preset--font-size--normal); } .has-huge-font-size{ font-size:var(--wp--preset--font-size--huge); } .has-text-align-center{ text-align:center; } .has-text-align-left{ text-align:left; } .has-text-align-right{ text-align:right; } #end-resizable-editor-section{ display:none; } .aligncenter{ clear:both; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } .screen-reader-text{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .screen-reader-text:focus{ background-color:#ddd; clip-path:none; color:#444; display:block; font-size:1em; height:auto; left:5px; line-height:normal; padding:15px 23px 14px; text-decoration:none; top:5px; width:auto; z-index:100000; } html :where(.has-border-color){ border-style:solid; } html :where([style*=border-top-color]){ border-top-style:solid; } html :where([style*=border-right-color]){ border-right-style:solid; } html :where([style*=border-bottom-color]){ border-bottom-style:solid; } html :where([style*=border-left-color]){ border-left-style:solid; } html :where([style*=border-width]){ border-style:solid; } html :where([style*=border-top-width]){ border-top-style:solid; } html :where([style*=border-right-width]){ border-right-style:solid; } html :where([style*=border-bottom-width]){ border-bottom-style:solid; } html :where([style*=border-left-width]){ border-left-style:solid; } html :where(img[class*=wp-image-]){ height:auto; max-width:100%; } :where(figure){ margin:0 0 1em; } html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height, 0px); } @media screen and (max-width:600px){ html :where(.is-position-sticky){ --wp-admin--admin-bar--position-offset:0px; } }.wp-element-button{ cursor:revert; } .wp-element-button[role=textbox]{ cursor:text; }.wp-element-button{ cursor:pointer; }html :where(.editor-styles-wrapper){background:#fff;color:initial;font-family:serif;font-size:medium;line-height:normal}:where(.editor-styles-wrapper) .wp-align-wrapper{max-width:840px}:where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-full,:where(.editor-styles-wrapper) .wp-align-wrapper>.wp-block{max-width:none}:where(.editor-styles-wrapper) .wp-align-wrapper.wp-align-wide{max-width:840px}:where(.editor-styles-wrapper) a{transition:none}:where(.editor-styles-wrapper) code,:where(.editor-styles-wrapper) kbd{background:inherit;font-family:monospace;font-size:inherit;margin:0;padding:0}:where(.editor-styles-wrapper) p{font-size:revert;line-height:revert;margin:revert}:where(.editor-styles-wrapper) ol,:where(.editor-styles-wrapper) ul{box-sizing:border-box;list-style-type:revert;margin:revert;padding:revert}:where(.editor-styles-wrapper) ol ol,:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ol,:where(.editor-styles-wrapper) ul ul{margin:revert}:where(.editor-styles-wrapper) ol li,:where(.editor-styles-wrapper) ul li{margin:revert}:where(.editor-styles-wrapper) ol ul,:where(.editor-styles-wrapper) ul ul{list-style-type:revert}:where(.editor-styles-wrapper) h1,:where(.editor-styles-wrapper) h2,:where(.editor-styles-wrapper) h3,:where(.editor-styles-wrapper) h4,:where(.editor-styles-wrapper) h5,:where(.editor-styles-wrapper) h6{color:revert;font-size:revert;font-weight:revert;line-height:revert;margin:revert}:where(.editor-styles-wrapper) select{-webkit-appearance:revert;background:revert;border:revert;border-radius:revert;box-shadow:revert;color:revert;cursor:revert;font-family:system-ui;font-size:revert;font-weight:revert;line-height:revert;margin:revert;max-width:revert;min-height:revert;outline:revert;padding:revert;text-shadow:revert;transform:revert;vertical-align:revert}:where(.editor-styles-wrapper) select:disabled,:where(.editor-styles-wrapper) select:focus{background-color:revert;background-image:revert;border-color:revert;box-shadow:revert;color:revert;cursor:revert;text-shadow:revert;transform:revert}.wp-element-button{cursor:pointer}ul.wp-block-archives{padding-left:2.5em}.wp-block-archives .wp-block-archives{border:0;margin:0}.wp-block-audio{margin-left:0;margin-right:0;position:relative}.wp-block-audio.is-transient audio{opacity:.3}.wp-block-audio .components-spinner{left:50%;margin-left:-9px;margin-top:-9px;position:absolute;top:50%}.wp-block-avatar__image img{width:100%}.wp-block-avatar.aligncenter .components-resizable-box__container{margin:0 auto}.wp-block[data-align=center]>.wp-block-button{margin-left:auto;margin-right:auto;text-align:center}.wp-block[data-align=right]>.wp-block-button{ /*!rtl:ignore*/text-align:right}.wp-block-button{cursor:text;position:relative}.wp-block-button:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:-2px}.wp-block-button[data-rich-text-placeholder]:after{opacity:.8}div[data-type="core/button"]{display:table}.wp-block-buttons>.wp-block,.wp-block-buttons>.wp-block-button.wp-block-button.wp-block-button.wp-block-button.wp-block-button{margin:0}.wp-block-buttons>.block-list-appender{align-items:center;display:inline-flex}.wp-block-buttons.is-vertical>.block-list-appender .block-list-appender__toggle{justify-content:flex-start}.wp-block-buttons>.wp-block-button:focus{box-shadow:none}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center]{margin-left:auto;margin-right:auto;margin-top:0;width:100%}.wp-block-buttons:not(.is-content-justification-space-between,.is-content-justification-right,.is-content-justification-left,.is-content-justification-center) .wp-block[data-align=center] .wp-block-button{margin-bottom:0}.wp-block[data-align=center]>.wp-block-buttons{align-items:center;justify-content:center}.wp-block[data-align=right]>.wp-block-buttons{justify-content:flex-end}.wp-block-categories ul{padding-left:2.5em}.wp-block-categories ul ul{margin-top:6px}[data-align=center] .wp-block-categories{text-align:center}.wp-block-categories__indentation{padding-left:16px}.wp-block-code code{background:none}.wp-block-columns :where(.wp-block){margin-left:0;margin-right:0;max-width:none}html :where(.wp-block-column){margin-bottom:0;margin-top:0}.wp-block-comments__legacy-placeholder,.wp-block-post-comments{box-sizing:border-box}.wp-block-comments__legacy-placeholder .alignleft,.wp-block-post-comments .alignleft{float:left}.wp-block-comments__legacy-placeholder .alignright,.wp-block-post-comments .alignright{float:right}.wp-block-comments__legacy-placeholder .navigation:after,.wp-block-post-comments .navigation:after{clear:both;content:"";display:table}.wp-block-comments__legacy-placeholder .commentlist,.wp-block-post-comments .commentlist{clear:both;list-style:none;margin:0;padding:0}.wp-block-comments__legacy-placeholder .commentlist .comment,.wp-block-post-comments .commentlist .comment{min-height:2.25em;padding-left:3.25em}.wp-block-comments__legacy-placeholder .commentlist .comment p,.wp-block-post-comments .commentlist .comment p{font-size:1em;line-height:1.8;margin:1em 0}.wp-block-comments__legacy-placeholder .commentlist .children,.wp-block-post-comments .commentlist .children{list-style:none;margin:0;padding:0}.wp-block-comments__legacy-placeholder .comment-author,.wp-block-post-comments .comment-author{line-height:1.5}.wp-block-comments__legacy-placeholder .comment-author .avatar,.wp-block-post-comments .comment-author .avatar{border-radius:1.5em;display:block;float:left;height:2.5em;margin-right:.75em;margin-top:.5em;width:2.5em}.wp-block-comments__legacy-placeholder .comment-author cite,.wp-block-post-comments .comment-author cite{font-style:normal}.wp-block-comments__legacy-placeholder .comment-meta,.wp-block-post-comments .comment-meta{font-size:.875em;line-height:1.5}.wp-block-comments__legacy-placeholder .comment-meta b,.wp-block-post-comments .comment-meta b{font-weight:400}.wp-block-comments__legacy-placeholder .comment-meta .comment-awaiting-moderation,.wp-block-post-comments .comment-meta .comment-awaiting-moderation{display:block;margin-bottom:1em;margin-top:1em}.wp-block-comments__legacy-placeholder .comment-body .commentmetadata,.wp-block-post-comments .comment-body .commentmetadata{font-size:.875em}.wp-block-comments__legacy-placeholder .comment-form-author label,.wp-block-comments__legacy-placeholder .comment-form-comment label,.wp-block-comments__legacy-placeholder .comment-form-email label,.wp-block-comments__legacy-placeholder .comment-form-url label,.wp-block-post-comments .comment-form-author label,.wp-block-post-comments .comment-form-comment label,.wp-block-post-comments .comment-form-email label,.wp-block-post-comments .comment-form-url label{display:block;margin-bottom:.25em}.wp-block-comments__legacy-placeholder .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder .comment-form textarea,.wp-block-post-comments .comment-form input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments .comment-form textarea{box-sizing:border-box;display:block;width:100%}.wp-block-comments__legacy-placeholder .comment-form-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent{display:flex;gap:.25em}.wp-block-comments__legacy-placeholder .comment-form-cookies-consent #wp-comment-cookies-consent,.wp-block-post-comments .comment-form-cookies-consent #wp-comment-cookies-consent{margin-top:.35em}.wp-block-comments__legacy-placeholder .comment-reply-title,.wp-block-post-comments .comment-reply-title{margin-bottom:0}.wp-block-comments__legacy-placeholder .comment-reply-title :where(small),.wp-block-post-comments .comment-reply-title :where(small){font-size:var(--wp--preset--font-size--medium,smaller);margin-left:.5em}.wp-block-comments__legacy-placeholder .reply,.wp-block-post-comments .reply{font-size:.875em;margin-bottom:1.4em}.wp-block-comments__legacy-placeholder input:not([type=submit]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]),.wp-block-post-comments textarea{border:1px solid #949494;font-family:inherit;font-size:1em}.wp-block-comments__legacy-placeholder input:not([type=submit]):not([type=checkbox]),.wp-block-comments__legacy-placeholder textarea,.wp-block-post-comments input:not([type=submit]):not([type=checkbox]),.wp-block-post-comments textarea{padding:calc(.667em + 2px)}:where(.wp-block-post-comments input[type=submit],.wp-block-comments__legacy-placeholder input[type=submit]){border:none}.wp-block-comments{box-sizing:border-box}.block-library-comments-toolbar__popover .components-popover__content{min-width:230px}.wp-block-comments__legacy-placeholder *{pointer-events:none}.wp-block-comment-author-avatar__placeholder{border:1px dashed;height:100%;width:100%;stroke:currentColor;stroke-dasharray:3}.wp-block[data-align=center]>.wp-block-comments-pagination{justify-content:center}:where(.editor-styles-wrapper) .wp-block-comments-pagination{max-width:100%}:where(.editor-styles-wrapper) .wp-block-comments-pagination.block-editor-block-list__layout{margin:0}.wp-block-comments-pagination>.wp-block-comments-pagination-next,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers,.wp-block-comments-pagination>.wp-block-comments-pagination-previous{font-size:inherit;margin:.5em .5em .5em 0}.wp-block-comments-pagination>.wp-block-comments-pagination-next:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-numbers:last-child,.wp-block-comments-pagination>.wp-block-comments-pagination-previous:last-child{margin-right:0}.wp-block-comments-pagination-numbers a{text-decoration:underline}.wp-block-comments-pagination-numbers .page-numbers{margin-right:2px}.wp-block-comments-pagination-numbers .page-numbers:last-child{margin-right:0}.wp-block-comments-title.has-background{padding:inherit}.wp-block-cover.is-placeholder{align-items:stretch;display:flex;min-height:240px;padding:0!important}.wp-block-cover.is-placeholder .components-placeholder.is-large{justify-content:flex-start;z-index:1}.wp-block-cover.is-placeholder:focus:after{min-height:auto}.wp-block-cover.components-placeholder h2{color:inherit}.wp-block-cover.is-transient{position:relative}.wp-block-cover.is-transient:before{background-color:#fff;content:"";height:100%;opacity:.3;position:absolute;width:100%;z-index:1}.wp-block-cover.is-transient .wp-block-cover__inner-container{z-index:2}.wp-block-cover .components-spinner{left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%)}.wp-block-cover .wp-block-cover__inner-container{margin-left:0;margin-right:0;text-align:left}.wp-block-cover .wp-block-cover__placeholder-background-options{width:100%}.wp-block-cover .wp-block-cover__image--placeholder-image{bottom:0;left:0;position:absolute;right:0;top:0}[data-align=left]>.wp-block-cover,[data-align=right]>.wp-block-cover{max-width:420px;width:100%}.block-library-cover__reset-button{margin-left:auto}.block-library-cover__resize-container{bottom:0;left:0;min-height:50px;position:absolute!important;right:0;top:0}.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .block-library-cover__resize-container,.components-popover.block-editor-block-popover.block-library-cover__resizable-box-popover .components-popover__content>div{overflow:visible;pointer-events:none}.block-editor-block-patterns-list__list-item .has-parallax.wp-block-cover{background-attachment:scroll}.color-block-support-panel__inner-wrapper>:not(.block-editor-tools-panel-color-gradient-settings__item){margin-top:24px}.wp-block-details summary div{display:inline}.wp-block-embed{clear:both;margin-left:0;margin-right:0}.wp-block-embed.is-loading{display:flex;justify-content:center}.wp-block-embed .wp-block-embed__placeholder-input{flex:1 1 auto}.wp-block-embed .components-placeholder__error{word-break:break-word}.wp-block-post-content .wp-block-embed__learn-more a{color:var(--wp-admin-theme-color)}.block-library-embed__interactive-overlay{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0}.wp-block[data-align=left]>.wp-block-embed,.wp-block[data-align=right]>.wp-block-embed{max-width:360px;width:100%}.wp-block[data-align=left]>.wp-block-embed .wp-block-embed__wrapper,.wp-block[data-align=right]>.wp-block-embed .wp-block-embed__wrapper{min-width:280px}.wp-block-file{align-items:center;display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:0}.wp-block[data-align=left]>.wp-block-file,.wp-block[data-align=right]>.wp-block-file{height:auto}.wp-block[data-align=center]>.wp-block-file{text-align:center}.wp-block-file .components-resizable-box__container{margin-bottom:1em}.wp-block-file .wp-block-file__preview{height:100%;margin-bottom:1em;width:100%}.wp-block-file .wp-block-file__preview-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.wp-block-file .wp-block-file__content-wrapper{flex-grow:1}.wp-block-file a{min-width:1em}.wp-block-file a:not(.wp-block-file__button){display:inline-block}.wp-block-file .wp-block-file__button-richtext-wrapper{display:inline-block;margin-left:.75em}.wp-block-form-input .is-input-hidden{background:repeating-linear-gradient(45deg,#0000,#0000 5px,currentColor 0,currentColor 6px);border:1px dashed;box-sizing:border-box;font-size:.85em;opacity:.3;padding:.5em}.wp-block-form-input .is-input-hidden input[type=text]{background:#0000}.wp-block-form-input.is-selected .is-input-hidden{background:none;opacity:1}.wp-block-form-input.is-selected .is-input-hidden input[type=text]{background:unset}.wp-block-form-submission-notification>*{background:repeating-linear-gradient(45deg,#0000,#0000 5px,currentColor 0,currentColor 6px);border:1px dashed;box-sizing:border-box;opacity:.25}.wp-block-form-submission-notification.is-selected>*,.wp-block-form-submission-notification:has(.is-selected)>*{background:none;opacity:1}.wp-block-form-submission-notification.is-selected:after,.wp-block-form-submission-notification:has(.is-selected):after{display:none!important}.wp-block-form-submission-notification:after{align-items:center;display:flex;font-size:1.1em;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%}.wp-block-form-submission-notification.form-notification-type-success:after{content:attr(data-message-success)}.wp-block-form-submission-notification.form-notification-type-error:after{content:attr(data-message-error)}.wp-block-freeform.block-library-rich-text__tinymce{height:auto}.wp-block-freeform.block-library-rich-text__tinymce li,.wp-block-freeform.block-library-rich-text__tinymce p{line-height:1.8}.wp-block-freeform.block-library-rich-text__tinymce ol,.wp-block-freeform.block-library-rich-text__tinymce ul{margin-left:0;padding-left:2.5em}.wp-block-freeform.block-library-rich-text__tinymce blockquote{border-left:4px solid #000;box-shadow:inset 0 0 0 0 #ddd;margin:0;padding-left:1em}.wp-block-freeform.block-library-rich-text__tinymce pre{color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:15px;white-space:pre-wrap}.wp-block-freeform.block-library-rich-text__tinymce>:first-child{margin-top:0}.wp-block-freeform.block-library-rich-text__tinymce>:last-child{margin-bottom:0}.wp-block-freeform.block-library-rich-text__tinymce.mce-edit-focus{outline:none}.wp-block-freeform.block-library-rich-text__tinymce a{color:var(--wp-admin-theme-color)}.wp-block-freeform.block-library-rich-text__tinymce:focus a[data-mce-selected]{background:#e5f5fa;border-radius:2px;box-shadow:0 0 0 1px #e5f5fa;margin:0 -2px;padding:0 2px}.wp-block-freeform.block-library-rich-text__tinymce code{background:#f0f0f0;border-radius:2px;color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:14px;padding:2px}.wp-block-freeform.block-library-rich-text__tinymce:focus code[data-mce-selected]{background:#ddd}.wp-block-freeform.block-library-rich-text__tinymce .alignright{float:right;margin:.5em 0 .5em 1em}.wp-block-freeform.block-library-rich-text__tinymce .alignleft{float:left;margin:.5em 1em .5em 0}.wp-block-freeform.block-library-rich-text__tinymce .aligncenter{display:block;margin-left:auto;margin-right:auto}.wp-block-freeform.block-library-rich-text__tinymce .wp-more-tag{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAADtgAAAAoBAMAAAA86gLBAAAAJFBMVEVMaXG7u7vBwcHDw8POzs68vLzGxsbMzMy+vr7AwMDQ0NDGxsYKLGzpAAAADHRSTlMA///zWf+/f///TMxNVGuqAAABwklEQVR4Ae3dMXLaQBTH4bfj8UCpx8hq0vgKvgFNemhT6Qo6gg6R+0ZahM2QLmyBJ99XWP9V5+o3jIUcLQEAAAAAAAAAAAAAAAAAAAAAAABQ8j0WL9lfTtlt18uNXAUA8O/KVtfa1tdcrOdSh9gCQAMlh1hMNbZZ1bsrsQWABsrhLRbz7z5in/32UbfUMUbkMQCAh5RfGYv82UdMdZ6HS2wjT2ILAI8r3XmM2B3WvM59vfO2xXYW2yYAENuPU8S+X/N67mKxzy225yaxBQCxLV392UdcvwV0jPVUj98ntkBWT7C7+9u2/V/vGtvXIWJ6/4rtbottWa6Ri0NUT/u72LYttrb97LHdvUXMxxrb8TO2W2TF1rYbbLG1bbGNjMi4+2Sbi1FsbbvNFlvbFtt5fDnE3d9sP1/XeIyV2Nr2U2/guZUuptNrH/dPI9eLB6SaAEBs6wPJf3/PNk9tYgsAYrv/8TFuzx/fvkFqGtrEFgDEdpcZUb7ejXy6ntrEFgDENvL6gsas4vbdyKt4DACI7TxElJv/Z7udpqFNbAFAbKduy2uU2trttM/x28UWAAAAAAAAAAAAAAAAAAAAAAAAAADgDyPwGmGTCZp7AAAAAElFTkSuQmCC);background-position:50%;background-repeat:no-repeat;background-size:1900px 20px;cursor:default;display:block;height:20px;margin:15px auto;outline:0;width:96%}.wp-block-freeform.block-library-rich-text__tinymce img::selection{background-color:initial}.wp-block-freeform.block-library-rich-text__tinymce div.mceTemp{-ms-user-select:element}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption{margin:0;max-width:100%}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption a,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption img{display:block}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption,.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption *{-webkit-user-drag:none}.wp-block-freeform.block-library-rich-text__tinymce dl.wp-caption .wp-caption-dd{margin:0;padding-top:.5em}.wp-block-freeform.block-library-rich-text__tinymce .wpview{border:1px solid #0000;clear:both;margin-bottom:16px;position:relative;width:99.99%}.wp-block-freeform.block-library-rich-text__tinymce .wpview iframe{background:#0000;display:block;max-width:100%}.wp-block-freeform.block-library-rich-text__tinymce .wpview .mce-shim{bottom:0;left:0;position:absolute;right:0;top:0}.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected="2"] .mce-shim{display:none}.wp-block-freeform.block-library-rich-text__tinymce .wpview .loading-placeholder{border:1px dashed #ddd;padding:10px}.wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error{border:1px solid #ddd;margin:0;padding:1em 0;word-wrap:break-word}.wp-block-freeform.block-library-rich-text__tinymce .wpview .wpview-error p{margin:0;text-align:center}.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .loading-placeholder,.wp-block-freeform.block-library-rich-text__tinymce .wpview[data-mce-selected] .wpview-error{border-color:#0000}.wp-block-freeform.block-library-rich-text__tinymce .wpview .dashicons{display:block;font-size:32px;height:32px;margin:0 auto;width:32px}.wp-block-freeform.block-library-rich-text__tinymce .wpview.wpview-type-gallery:after{clear:both;content:"";display:table}.wp-block-freeform.block-library-rich-text__tinymce .gallery img[data-mce-selected]:focus{outline:none}.wp-block-freeform.block-library-rich-text__tinymce .gallery a{cursor:default}.wp-block-freeform.block-library-rich-text__tinymce .gallery{line-height:1;margin:auto -6px;overflow-x:hidden;padding:6px 0}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-item{box-sizing:border-box;float:left;margin:0;padding:6px;text-align:center}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption,.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-icon{margin:0}.wp-block-freeform.block-library-rich-text__tinymce .gallery .gallery-caption{font-size:13px;margin:4px 0}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-1 .gallery-item{width:100%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-2 .gallery-item{width:50%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-3 .gallery-item{width:33.3333333333%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-4 .gallery-item{width:25%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-5 .gallery-item{width:20%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-6 .gallery-item{width:16.6666666667%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-7 .gallery-item{width:14.2857142857%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-8 .gallery-item{width:12.5%}.wp-block-freeform.block-library-rich-text__tinymce .gallery-columns-9 .gallery-item{width:11.1111111111%}.wp-block-freeform.block-library-rich-text__tinymce .gallery img{border:none;height:auto;max-width:100%;padding:0}div[data-type="core/freeform"]:before{border:1px solid #ddd;outline:1px solid #0000}@media not (prefers-reduced-motion){div[data-type="core/freeform"]:before{transition:border-color .1s linear,box-shadow .1s linear}}div[data-type="core/freeform"].is-selected:before{border-color:#1e1e1e}div[data-type="core/freeform"] .block-editor-block-contextual-toolbar+div{margin-top:0;padding-top:0}div[data-type="core/freeform"].is-selected .block-library-rich-text__tinymce:after{clear:both;content:"";display:table}.mce-toolbar-grp .mce-btn.mce-active button,.mce-toolbar-grp .mce-btn.mce-active i,.mce-toolbar-grp .mce-btn.mce-active:hover button,.mce-toolbar-grp .mce-btn.mce-active:hover i{color:#1e1e1e}.mce-toolbar-grp .mce-rtl .mce-flow-layout-item.mce-last{margin-left:8px;margin-right:0}.mce-toolbar-grp .mce-btn i{font-style:normal}.block-library-classic__toolbar{border:1px solid #ddd;border-bottom:none;border-radius:2px;display:none;margin:0 0 8px;padding:0;position:sticky;top:0;width:auto;z-index:31}div[data-type="core/freeform"].is-selected .block-library-classic__toolbar{border-color:#1e1e1e;display:block}.block-library-classic__toolbar .mce-tinymce{box-shadow:none}@media (min-width:600px){.block-library-classic__toolbar{padding:0}}.block-library-classic__toolbar:empty{background:#f5f5f5;border-bottom:1px solid #e2e4e7;display:block}.block-library-classic__toolbar:empty:before{color:#555d66;content:attr(data-placeholder);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:37px;padding:14px}.block-library-classic__toolbar div.mce-toolbar-grp{border-bottom:1px solid #1e1e1e}.block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar .mce-menubar>div,.block-library-classic__toolbar .mce-tinymce-inline,.block-library-classic__toolbar .mce-tinymce-inline>div,.block-library-classic__toolbar div.mce-toolbar-grp,.block-library-classic__toolbar div.mce-toolbar-grp>div{height:auto!important;width:100%!important}.block-library-classic__toolbar .mce-container-body.mce-abs-layout{overflow:visible}.block-library-classic__toolbar .mce-menubar,.block-library-classic__toolbar div.mce-toolbar-grp{position:static}.block-library-classic__toolbar .mce-toolbar-grp>div{padding:1px 3px}.block-library-classic__toolbar .mce-toolbar-grp .mce-toolbar:not(:first-child){display:none}.block-library-classic__toolbar.has-advanced-toolbar .mce-toolbar-grp .mce-toolbar{display:block}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{height:50vh!important}@media (min-width:960px){.block-editor-freeform-modal .block-editor-freeform-modal__content:not(.is-full-screen){height:9999rem}.block-editor-freeform-modal .block-editor-freeform-modal__content .components-modal__header+div{height:100%}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-tinymce{height:calc(100% - 52px)}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-container-body{display:flex;flex-direction:column;height:100%;min-width:50vw}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area{display:flex;flex-direction:column;flex-grow:1}.block-editor-freeform-modal .block-editor-freeform-modal__content .mce-edit-area iframe{flex-grow:1;height:10px!important}}.block-editor-freeform-modal__actions{margin-top:16px}:root :where(figure.wp-block-gallery){display:block}:root :where(figure.wp-block-gallery)>.blocks-gallery-caption{flex:0 0 100%}:root :where(figure.wp-block-gallery)>.blocks-gallery-media-placeholder-wrapper{flex-basis:100%}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice.is-error{display:block}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice__content{margin:4px 0}:root :where(figure.wp-block-gallery) .wp-block-image .components-notice__dismiss{position:absolute;right:5px;top:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .components-placeholder__label{display:none}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder.is-appender .block-editor-media-placeholder__button{margin-bottom:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder{margin:0}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder .components-placeholder__label{display:flex}:root :where(figure.wp-block-gallery) .block-editor-media-placeholder figcaption{z-index:2}:root :where(figure.wp-block-gallery) .components-spinner{left:50%;margin-left:-9px;margin-top:-9px;position:absolute;top:50%}.gallery-settings-buttons .components-button:first-child{margin-right:8px}.gallery-image-sizes .components-base-control__label{margin-bottom:4px}.gallery-image-sizes .gallery-image-sizes__loading{align-items:center;color:#757575;display:flex;font-size:12px}.gallery-image-sizes .components-spinner{margin:0 8px 0 4px}.blocks-gallery-item figure:not(.is-selected):focus,.blocks-gallery-item img:focus{outline:none}.blocks-gallery-item figure.is-selected:before{bottom:0;box-shadow:0 0 0 1px #fff inset,0 0 0 3px var(--wp-admin-theme-color) inset;content:"";left:0;outline:2px solid #0000;pointer-events:none;position:absolute;right:0;top:0;z-index:1}.blocks-gallery-item figure.is-transient img{opacity:.3}.blocks-gallery-item .block-editor-media-placeholder{height:100%;margin:0}.blocks-gallery-item .block-editor-media-placeholder .components-placeholder__label{display:flex}.wp-block-gallery ul.blocks-gallery-grid{margin:0;padding:0}@media (min-width:600px){.wp-block-update-gallery-modal{max-width:480px}}.wp-block-update-gallery-modal-buttons{display:flex;gap:12px;justify-content:flex-end}.wp-block-group .block-editor-block-list__insertion-point{left:0;right:0}[data-type="core/group"].is-selected .block-list-appender{margin-left:0;margin-right:0}[data-type="core/group"].is-selected .has-background .block-list-appender{margin-bottom:18px;margin-top:18px}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child{gap:inherit;pointer-events:none}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-default-block-appender__content,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{display:inherit;flex:1;flex-direction:inherit;width:100%}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child:after{border:1px dashed;content:"";display:flex;flex:1 0 40px;min-height:38px;pointer-events:none}.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-button-block-appender,.wp-block-group.is-layout-flex.block-editor-block-list__block>.block-list-appender:only-child .block-editor-inserter{pointer-events:all}.block-library-html__edit .block-library-html__preview-overlay{height:100%;left:0;position:absolute;top:0;width:100%}.block-library-html__edit .block-editor-plain-text{background:#fff!important;border:1px solid #1e1e1e!important;border-radius:2px!important;box-shadow:none!important;box-sizing:border-box;color:#1e1e1e!important;direction:ltr;font-family:Menlo,Consolas,monaco,monospace!important;font-size:16px!important;max-height:250px;padding:12px!important}@media (min-width:600px){.block-library-html__edit .block-editor-plain-text{font-size:13px!important}}.block-library-html__edit .block-editor-plain-text:focus{border-color:var(--wp-admin-theme-color)!important;box-shadow:0 0 0 1px var(--wp-admin-theme-color)!important;outline:2px solid #0000!important}.wp-block-image.wp-block-image .block-editor-media-placeholder.is-small{min-height:60px}figure.wp-block-image:not(.wp-block){margin:0}.wp-block-image{position:relative}.wp-block-image .is-applying img,.wp-block-image.is-transient img{opacity:.3}.wp-block-image figcaption img{display:inline}.wp-block-image .components-spinner{left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%)}.wp-block-image__placeholder{aspect-ratio:4/3}.wp-block-image__placeholder.has-illustration:before{background:#fff;opacity:.8}.wp-block-image__placeholder .components-placeholder__illustration{opacity:.1}.wp-block-image .components-resizable-box__container{display:table}.wp-block-image .components-resizable-box__container img{display:block;height:inherit;width:inherit}.block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{left:0;margin:-1px 0;position:absolute;right:0}@media (min-width:600px){.block-editor-block-list__block[data-type="core/image"] .block-editor-block-toolbar .block-editor-url-input__button-modal{margin:-1px}}[data-align=full]>.wp-block-image img,[data-align=wide]>.wp-block-image img{height:auto;width:100%}.wp-block[data-align=center]>.wp-block-image,.wp-block[data-align=left]>.wp-block-image,.wp-block[data-align=right]>.wp-block-image{display:table}.wp-block[data-align=center]>.wp-block-image>figcaption,.wp-block[data-align=left]>.wp-block-image>figcaption,.wp-block[data-align=right]>.wp-block-image>figcaption{caption-side:bottom;display:table-caption}.wp-block[data-align=left]>.wp-block-image{margin:.5em 1em .5em 0}.wp-block[data-align=right]>.wp-block-image{margin:.5em 0 .5em 1em}.wp-block[data-align=center]>.wp-block-image{margin-left:auto;margin-right:auto;text-align:center}.wp-block[data-align]:has(>.wp-block-image){position:relative}.wp-block-image__crop-area{max-width:100%;overflow:hidden;position:relative;width:100%}.wp-block-image__crop-area .reactEasyCrop_Container{pointer-events:auto}.wp-block-image__crop-area .reactEasyCrop_Container .reactEasyCrop_Image{border:none;border-radius:0}.wp-block-image__crop-icon{align-items:center;display:flex;justify-content:center;min-width:48px;padding:0 8px}.wp-block-image__crop-icon svg{fill:currentColor}.wp-block-image__zoom .components-popover__content{min-width:260px;overflow:visible!important}.wp-block-image__toolbar_content_textarea__container{padding:8px}.wp-block-image__toolbar_content_textarea{width:250px}.wp-block-latest-posts>li{overflow:hidden}.wp-block-latest-posts li a>div{display:inline}:root :where(.wp-block-latest-posts){padding-left:2.5em}:root :where(.wp-block-latest-posts.is-grid),:root :where(.wp-block-latest-posts__list){padding-left:0}.wp-block-media-text__media{position:relative}.wp-block-media-text__media.is-transient img{opacity:.3}.wp-block-media-text__media .components-spinner{left:50%;margin-left:-9px;margin-top:-9px;position:absolute;top:50%}.wp-block-media-text .__resizable_base__{grid-column:1/span 2;grid-row:2}.wp-block-media-text .editor-media-container__resizer{width:100%!important}.wp-block-media-text.is-image-fill .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill .editor-media-container__resizer,.wp-block-media-text.is-image-fill-element .components-placeholder.has-illustration,.wp-block-media-text.is-image-fill-element .editor-media-container__resizer{height:100%!important}.wp-block-media-text>.block-editor-block-list__layout>.block-editor-block-list__block{max-width:unset}.wp-block-media-text--placeholder-image{min-height:205px}.block-editor-block-list__block[data-type="core/more"]{margin-bottom:28px;margin-top:28px;max-width:100%;text-align:center}.wp-block-more{display:block;text-align:center;white-space:nowrap}.wp-block-more input[type=text]{background:#fff;border:none;border-radius:4px;box-shadow:none;color:#757575;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;height:24px;margin:0;max-width:100%;padding:6px 8px;position:relative;text-align:center;text-transform:uppercase;white-space:nowrap}.wp-block-more input[type=text]:focus{box-shadow:none}.wp-block-more:before{border-top:3px dashed #ccc;content:"";left:0;position:absolute;right:0;top:50%}.editor-styles-wrapper .wp-block-navigation ul{margin-bottom:0;margin-left:0;margin-top:0;padding-left:0}.editor-styles-wrapper .wp-block-navigation .wp-block-navigation-item.wp-block{margin:revert}.wp-block-navigation-item__label{display:inline}.wp-block-navigation-item,.wp-block-navigation__container{background-color:inherit}.wp-block-navigation:not(.is-selected):not(.has-child-selected) .has-child:hover>.wp-block-navigation__submenu-container{opacity:0;visibility:hidden}.has-child.has-child-selected>.wp-block-navigation__submenu-container,.has-child.is-selected>.wp-block-navigation__submenu-container{display:flex;opacity:1;visibility:visible}.is-dragging-components-draggable .has-child.is-dragging-within>.wp-block-navigation__submenu-container{opacity:1;visibility:visible}.is-editing>.wp-block-navigation__container{display:flex;flex-direction:column;opacity:1;visibility:visible}.is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container{opacity:1;visibility:hidden}.is-dragging-components-draggable .wp-block-navigation-link>.wp-block-navigation__container .block-editor-block-draggable-chip-wrapper{visibility:visible}.is-editing>.wp-block-navigation__submenu-container>.block-list-appender{display:block;position:static;width:100%}.is-editing>.wp-block-navigation__submenu-container>.block-list-appender .block-editor-button-block-appender{background:#1e1e1e;color:#fff;margin-left:auto;margin-right:0;padding:0;width:24px}.wp-block-navigation__submenu-container .block-list-appender{display:none}.block-library-colors-selector{width:auto}.block-library-colors-selector .block-library-colors-selector__toggle{display:block;margin:0 auto;padding:3px;width:auto}.block-library-colors-selector .block-library-colors-selector__icon-container{align-items:center;border-radius:4px;display:flex;height:30px;margin:0 auto;padding:3px;position:relative}.block-library-colors-selector .block-library-colors-selector__state-selection{border-radius:11px;box-shadow:inset 0 0 0 1px #0003;height:22px;line-height:20px;margin-left:auto;margin-right:auto;min-height:22px;min-width:22px;padding:2px;width:22px}.block-library-colors-selector .block-library-colors-selector__state-selection>svg{min-width:auto!important}.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg,.block-library-colors-selector .block-library-colors-selector__state-selection.has-text-color>svg path{color:inherit}.block-library-colors-selector__popover .color-palette-controller-container{padding:16px}.block-library-colors-selector__popover .components-base-control__label{height:20px;line-height:20px}.block-library-colors-selector__popover .component-color-indicator{float:right;margin-top:2px}.block-library-colors-selector__popover .components-panel__body-title{display:none}.wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender{background-color:#1e1e1e;color:#fff;height:24px}.wp-block-navigation .wp-block+.block-list-appender .block-editor-button-block-appender.block-editor-button-block-appender.block-editor-button-block-appender{padding:0}.wp-block-navigation .wp-block .wp-block .block-editor-button-block-appender{background-color:initial;color:#1e1e1e}@keyframes loadingpulse{0%{opacity:1}50%{opacity:.5}to{opacity:1}}.components-placeholder.wp-block-navigation-placeholder{background:none;box-shadow:none;color:inherit;min-height:0;outline:none;padding:0}.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset{font-size:inherit}.components-placeholder.wp-block-navigation-placeholder .components-placeholder__fieldset .components-button{margin-bottom:0}.wp-block-navigation.is-selected .components-placeholder.wp-block-navigation-placeholder{color:#1e1e1e}.wp-block-navigation-placeholder__preview{align-items:center;background:#0000;color:currentColor;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;min-width:96px}.wp-block-navigation.is-selected .wp-block-navigation-placeholder__preview{display:none}.wp-block-navigation-placeholder__preview:before{border:1px dashed;border-radius:inherit;bottom:0;content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0}.wp-block-navigation-placeholder__preview>svg{fill:currentColor}.wp-block-navigation.is-vertical .is-medium .components-placeholder__fieldset,.wp-block-navigation.is-vertical .is-small .components-placeholder__fieldset{min-height:90px}.wp-block-navigation.is-vertical .is-large .components-placeholder__fieldset{min-height:132px}.wp-block-navigation-placeholder__controls,.wp-block-navigation-placeholder__preview{align-items:flex-start;flex-direction:row;padding:6px 8px}.wp-block-navigation-placeholder__controls{background-color:#fff;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;display:none;float:left;position:relative;width:100%;z-index:1}.wp-block-navigation.is-selected .wp-block-navigation-placeholder__controls{display:flex}.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-medium .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator,.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions__indicator+hr{display:none}.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions{align-items:flex-start;flex-direction:column}.is-small .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr,.wp-block-navigation.is-vertical .wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__actions hr{display:none}.wp-block-navigation-placeholder__controls .wp-block-navigation-placeholder__icon{height:36px;margin-right:12px}.wp-block-navigation-placeholder__actions__indicator{align-items:center;display:flex;height:36px;justify-content:flex-start;line-height:0;margin-left:4px;padding:0 6px 0 0}.wp-block-navigation-placeholder__actions__indicator svg{margin-right:4px;fill:currentColor}.wp-block-navigation .components-placeholder.is-medium .components-placeholder__fieldset{flex-direction:row!important}.wp-block-navigation-placeholder__actions{align-items:center;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;gap:6px;height:100%}.wp-block-navigation-placeholder__actions .components-dropdown,.wp-block-navigation-placeholder__actions>.components-button{margin-right:0}.wp-block-navigation-placeholder__actions.wp-block-navigation-placeholder__actions hr{background-color:#1e1e1e;border:0;height:100%;margin:auto 0;max-height:16px;min-height:1px;min-width:1px}@media (min-width:600px){.wp-block-navigation__responsive-container:not(.is-menu-open) .components-button.wp-block-navigation__responsive-container-close{display:none}}.wp-block-navigation__responsive-container.is-menu-open{position:fixed;top:155px}@media (min-width:782px){.wp-block-navigation__responsive-container.is-menu-open{left:36px;top:93px}}@media (min-width:960px){.wp-block-navigation__responsive-container.is-menu-open{left:160px}}.is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{top:141px}.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{left:0;top:155px}@media (min-width:782px){.is-fullscreen-mode .wp-block-navigation__responsive-container.is-menu-open{top:61px}}.is-fullscreen-mode .is-mobile-preview .wp-block-navigation__responsive-container.is-menu-open,.is-fullscreen-mode .is-tablet-preview .wp-block-navigation__responsive-container.is-menu-open{top:109px}body.editor-styles-wrapper .wp-block-navigation__responsive-container.is-menu-open{bottom:0;left:0;right:0;top:0}.components-button.wp-block-navigation__responsive-container-close.wp-block-navigation__responsive-container-close,.components-button.wp-block-navigation__responsive-container-open.wp-block-navigation__responsive-container-open{color:inherit;height:auto;padding:0}.components-heading.wp-block-navigation-off-canvas-editor__title{margin:0}.wp-block-navigation-off-canvas-editor__header{margin-bottom:8px}.is-menu-open .wp-block-navigation__responsive-container-content * .block-list-appender{margin-top:16px}@keyframes fadein{0%{opacity:0}to{opacity:1}}.wp-block-navigation__loading-indicator-container{padding:8px 12px}.wp-block-navigation .wp-block-navigation__uncontrolled-inner-blocks-loading-indicator{margin-top:0}@keyframes fadeouthalf{0%{opacity:1}to{opacity:.5}}.wp-block-navigation-delete-menu-button{justify-content:center;margin-bottom:16px;width:100%}.components-button.is-link.wp-block-navigation-manage-menus-button{margin-bottom:16px}.wp-block-navigation__overlay-menu-preview{align-items:center;background-color:#f0f0f0;display:flex;height:64px!important;justify-content:space-between;margin-bottom:12px;padding:0 24px;width:100%}.wp-block-navigation__overlay-menu-preview.open{background-color:#fff;box-shadow:inset 0 0 0 1px #e0e0e0;outline:1px solid #0000}.wp-block-navigation-placeholder__actions hr+hr,.wp-block-navigation__toolbar-menu-selector.components-toolbar-group:empty{display:none}.wp-block-navigation__navigation-selector{margin-bottom:16px;width:100%}.wp-block-navigation__navigation-selector-button{border:1px solid;justify-content:space-between;width:100%}.wp-block-navigation__navigation-selector-button__icon{flex:0 0 auto}.wp-block-navigation__navigation-selector-button__label{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wp-block-navigation__navigation-selector-button--createnew{border:1px solid;margin-bottom:16px;width:100%}.wp-block-navigation__responsive-container-open.components-button{opacity:1}.wp-block-navigation__menu-inspector-controls{overflow-x:auto;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-width:thin;will-change:transform}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar{height:12px;width:12px}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-track{background-color:initial}.wp-block-navigation__menu-inspector-controls::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.wp-block-navigation__menu-inspector-controls:focus-within::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:focus::-webkit-scrollbar-thumb,.wp-block-navigation__menu-inspector-controls:hover::-webkit-scrollbar-thumb{background-color:#949494}.wp-block-navigation__menu-inspector-controls:focus,.wp-block-navigation__menu-inspector-controls:focus-within,.wp-block-navigation__menu-inspector-controls:hover{scrollbar-color:#949494 #0000}@media (hover:none){.wp-block-navigation__menu-inspector-controls{scrollbar-color:#949494 #0000}}.wp-block-navigation__menu-inspector-controls__empty-message{margin-left:24px}.wp-block-navigation__overlay-menu-icon-toggle-group{margin-bottom:16px}.wp-block-navigation .block-list-appender{position:relative}.wp-block-navigation .has-child{cursor:pointer}.wp-block-navigation .has-child .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation .has-child:hover .wp-block-navigation__submenu-container{z-index:29}.wp-block-navigation .has-child.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation .has-child.is-selected>.wp-block-navigation__submenu-container{height:auto!important;min-width:200px!important;opacity:1!important;overflow:visible!important;visibility:visible!important;width:auto!important}.wp-block-navigation-item .wp-block-navigation-item__content{cursor:text}.wp-block-navigation-item.is-editing,.wp-block-navigation-item.is-selected{min-width:20px}.wp-block-navigation-item .block-list-appender{margin:16px auto 16px 16px}.wp-block-navigation-link__invalid-item{color:#000}.wp-block-navigation-link__placeholder{background-image:none!important;box-shadow:none!important;position:relative;text-decoration:none!important}.wp-block-navigation-link__placeholder .wp-block-navigation-link__placeholder-text span{-webkit-text-decoration:wavy underline;text-decoration:wavy underline;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none;text-underline-offset:.25rem}.wp-block-navigation-link__placeholder.wp-block-navigation-item__content{cursor:pointer}.link-control-transform{border-top:1px solid #ccc;padding:0 16px 8px}.link-control-transform__subheading{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.link-control-transform__items{display:flex;justify-content:space-between}.link-control-transform__item{flex-basis:33%;flex-direction:column;gap:8px;height:auto}.wp-block-navigation-submenu{display:block}.wp-block-navigation-submenu .wp-block-navigation__submenu-container{z-index:28}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container{height:auto!important;left:-1px;min-width:200px!important;opacity:1!important;position:absolute;top:100%;visibility:visible!important;width:auto!important}@media (min-width:782px){.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container{left:100%;top:-1px}.wp-block-navigation-submenu.has-child-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before,.wp-block-navigation-submenu.is-selected>.wp-block-navigation__submenu-container .wp-block-navigation__submenu-container:before{background:#0000;content:"";display:block;height:100%;position:absolute;right:100%;width:.5em}}.block-editor-block-list__block[data-type="core/nextpage"]{margin-bottom:28px;margin-top:28px;max-width:100%;text-align:center}.wp-block-nextpage{display:block;text-align:center;white-space:nowrap}.wp-block-nextpage>span{background:#fff;border-radius:4px;color:#757575;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;height:24px;padding:6px 8px;position:relative;text-transform:uppercase}.wp-block-nextpage:before{border-top:3px dashed #ccc;content:"";left:0;position:absolute;right:0;top:50%}.wp-block-navigation .wp-block-page-list,.wp-block-navigation .wp-block-page-list>div{background-color:inherit}.wp-block-navigation.items-justified-space-between .wp-block-page-list,.wp-block-navigation.items-justified-space-between .wp-block-page-list>div{display:contents;flex:1}.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.has-child-selected .wp-block-page-list>div,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list,.wp-block-navigation.items-justified-space-between.is-selected .wp-block-page-list>div{flex:inherit}.wp-block-navigation .wp-block-navigation__submenu-container>.wp-block-page-list{display:block}.wp-block-pages-list__item__link{pointer-events:none}@media (min-width:600px){.wp-block-page-list-modal{max-width:480px}}.wp-block-page-list-modal-buttons{display:flex;gap:12px;justify-content:flex-end}.wp-block-page-list .open-on-click:focus-within>.wp-block-navigation__submenu-container{height:auto;min-width:200px;opacity:1;visibility:visible;width:auto}.wp-block-page-list__loading-indicator-container{padding:8px 12px}.block-editor-block-list__block[data-type="core/paragraph"].has-drop-cap:focus{min-height:auto!important}.block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{opacity:1}.block-editor-block-list__block[data-empty=true]+.block-editor-block-list__block[data-empty=true]:not([data-custom-placeholder=true]) [data-rich-text-placeholder]{opacity:0}.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-left[style*="writing-mode: vertical-lr"],.block-editor-block-list__block[data-type="core/paragraph"].has-text-align-right[style*="writing-mode: vertical-rl"]{rotate:180deg}.is-zoomed-out .block-editor-block-list__block[data-empty=true] [data-rich-text-placeholder]{opacity:0}.wp-block-post-author__inspector-settings .components-base-control,.wp-block-post-author__inspector-settings .components-base-control:last-child{margin-bottom:0}.wp-block-post-excerpt .wp-block-post-excerpt__excerpt.is-inline{display:inline}.wp-block-pullquote.is-style-solid-color blockquote p{font-size:32px}.wp-block-pullquote.is-style-solid-color .wp-block-pullquote__citation{font-style:normal;text-transform:none}.wp-block-pullquote .wp-block-pullquote__citation{color:inherit}.wp-block-rss li a>div{display:inline}.wp-block-rss__placeholder-form .wp-block-rss__placeholder-input{flex:1 1 auto}.wp-block-rss .wp-block-rss{all:inherit;margin:0;padding:0}.wp-block[data-align=center] .wp-block-search .wp-block-search__inside-wrapper{margin:auto}.wp-block-search :where(.wp-block-search__button){align-items:center;border-radius:initial;display:flex;height:auto;justify-content:center;text-align:center}.wp-block-search__inspector-controls .components-base-control{margin-bottom:0}.block-editor-block-list__block[data-type="core/separator"]{padding-bottom:.1px;padding-top:.1px}.blocks-shortcode__textarea{background:#fff!important;border:1px solid #1e1e1e!important;border-radius:2px!important;box-shadow:none!important;box-sizing:border-box;color:#1e1e1e!important;font-family:Menlo,Consolas,monaco,monospace!important;font-size:16px!important;max-height:250px;padding:12px!important;resize:none}@media (min-width:600px){.blocks-shortcode__textarea{font-size:13px!important}}.blocks-shortcode__textarea:focus{border-color:var(--wp-admin-theme-color)!important;box-shadow:0 0 0 1px var(--wp-admin-theme-color)!important;outline:2px solid #0000!important}.wp-block-site-logo.aligncenter>div,.wp-block[data-align=center]>.wp-block-site-logo{display:table;margin-left:auto;margin-right:auto}.wp-block-site-logo a{pointer-events:none}.wp-block-site-logo .custom-logo-link{cursor:inherit}.wp-block-site-logo .custom-logo-link:focus{box-shadow:none}.wp-block-site-logo img{display:block;height:auto;max-width:100%}.wp-block-site-logo.is-transient{position:relative}.wp-block-site-logo.is-transient img{opacity:.3}.wp-block-site-logo.is-transient .components-spinner{left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%)}.wp-block-site-logo.wp-block-site-logo.is-default-size .components-placeholder{height:60px;width:60px}.wp-block-site-logo.wp-block-site-logo .components-resizable-box__container,.wp-block-site-logo.wp-block-site-logo>div{border-radius:inherit}.wp-block-site-logo.wp-block-site-logo .components-placeholder{align-items:center;border-radius:inherit;display:flex;height:100%;justify-content:center;min-height:48px;min-width:48px;padding:0;width:100%}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-drop-zone__content-text,.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-form-file-upload{display:none}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button{align-items:center;background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);border-radius:50%;border-style:solid;color:#fff;display:flex;height:48px;justify-content:center;margin:auto;padding:0;position:relative;width:48px}.wp-block-site-logo.wp-block-site-logo .components-placeholder .components-button.components-button>svg{color:inherit}.block-library-site-logo__inspector-media-replace-container{position:relative}.block-library-site-logo__inspector-media-replace-container .components-drop-zone__content-icon{display:none}.block-library-site-logo__inspector-media-replace-container button.components-button{box-shadow:inset 0 0 0 1px #ccc;color:#1e1e1e;display:block;height:40px;width:100%}.block-library-site-logo__inspector-media-replace-container button.components-button:hover{color:var(--wp-admin-theme-color)}.block-library-site-logo__inspector-media-replace-container button.components-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-media-replace-title{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-library-site-logo__inspector-media-replace-container .components-dropdown{display:block}.block-library-site-logo__inspector-media-replace-container img{aspect-ratio:1;border-radius:50%!important;box-shadow:inset 0 0 0 1px #0003;min-width:20px;width:20px}.block-library-site-logo__inspector-media-replace-container .block-library-site-logo__inspector-readonly-logo-preview{display:flex;height:40px;padding:6px 12px}.wp-block-site-tagline__placeholder,.wp-block-site-title__placeholder{border:1px dashed;padding:1em 0}.wp-block-social-links .wp-social-link{line-height:0}.wp-block-social-link-anchor{align-items:center;background:none;border:0;box-sizing:border-box;color:currentColor;cursor:pointer;display:inline-flex;font-family:inherit;font-size:inherit;font-weight:inherit;height:auto;margin:0;opacity:1;padding:.25em}.wp-block-social-link-anchor:hover{transform:none}:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link button){padding-left:.6666666667em;padding-right:.6666666667em}:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link button){padding:0}.wp-block-social-link__toolbar_content_text{width:250px}.wp-block-social-links div.block-editor-url-input{display:inline-block;margin-left:8px}.wp-social-link:hover{transform:none}:root :where(.wp-block-social-links),:root :where(.wp-block-social-links.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link){padding:0}:root :where(.wp-block-social-links__social-placeholder .wp-social-link){padding:.25em}:root :where(.wp-block-social-links.is-style-pill-shape .wp-block-social-links__social-placeholder .wp-social-link){padding-left:.6666666667em;padding-right:.6666666667em}.wp-block-social-links__social-placeholder{display:flex;list-style:none;opacity:.8}.wp-block-social-links__social-placeholder>.wp-social-link{margin-left:0!important;margin-right:0!important;padding-left:0!important;padding-right:0!important;visibility:hidden;width:0!important}.wp-block-social-links__social-placeholder>.wp-block-social-links__social-placeholder-icons{display:flex}.wp-block-social-links__social-placeholder .wp-social-link:before{border-radius:50%;content:"";display:block;height:1em;width:1em}.is-style-logos-only .wp-block-social-links__social-placeholder .wp-social-link:before{background:currentColor}.wp-block-social-links .wp-block-social-links__social-prompt{cursor:default;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:24px;list-style:none;margin-bottom:auto;margin-top:auto;min-height:24px;padding-right:8px}.wp-block.wp-block-social-links.aligncenter,.wp-block[data-align=center]>.wp-block-social-links{justify-content:center}.block-editor-block-preview__content .components-button:disabled{opacity:1}.wp-social-link.wp-social-link__is-incomplete{opacity:.5}.wp-block-social-links .is-selected .wp-social-link__is-incomplete,.wp-social-link.wp-social-link__is-incomplete:focus,.wp-social-link.wp-social-link__is-incomplete:hover{opacity:1}.wp-block-social-links .block-list-appender{position:static}.wp-block-social-links .block-list-appender .block-editor-inserter{font-size:inherit}.wp-block-social-links .block-list-appender .block-editor-button-block-appender{font-size:inherit;height:1.5em;padding:0;width:1.5em}.block-editor-block-list__block[data-type="core/spacer"]:before{content:"";display:block;height:100%;min-height:8px;min-width:8px;position:absolute;width:100%;z-index:1}.block-library-spacer__resize-container.has-show-handle,.wp-block-spacer.is-hovered .block-library-spacer__resize-container,.wp-block-spacer.is-selected.custom-sizes-disabled{background:#0000001a}.is-dark-theme .block-library-spacer__resize-container.has-show-handle,.is-dark-theme .wp-block-spacer.is-hovered .block-library-spacer__resize-container,.is-dark-theme .wp-block-spacer.is-selected.custom-sizes-disabled{background:#ffffff26}.block-library-spacer__resize-container{clear:both}.block-library-spacer__resize-container:not(.is-resizing){height:100%!important;width:100%!important}.block-library-spacer__resize-container .components-resizable-box__handle:before{content:none}.block-library-spacer__resize-container.resize-horizontal{height:100%!important;margin-bottom:0}.wp-block[data-align=center]>.wp-block-table,.wp-block[data-align=left]>.wp-block-table,.wp-block[data-align=right]>.wp-block-table{height:auto}.wp-block[data-align=center]>.wp-block-table table,.wp-block[data-align=left]>.wp-block-table table,.wp-block[data-align=right]>.wp-block-table table{width:auto}.wp-block[data-align=center]>.wp-block-table td,.wp-block[data-align=center]>.wp-block-table th,.wp-block[data-align=left]>.wp-block-table td,.wp-block[data-align=left]>.wp-block-table th,.wp-block[data-align=right]>.wp-block-table td,.wp-block[data-align=right]>.wp-block-table th{word-break:break-word}.wp-block[data-align=center]>.wp-block-table{text-align:initial}.wp-block[data-align=center]>.wp-block-table table{margin:0 auto}.wp-block-table td,.wp-block-table th{border:1px solid;padding:.5em}.wp-block-table td.is-selected,.wp-block-table th.is-selected{border-color:var(--wp-admin-theme-color);border-style:double;box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.wp-block-table table.has-individual-borders td,.wp-block-table table.has-individual-borders th,.wp-block-table table.has-individual-borders tr,.wp-block-table table.has-individual-borders>*{border:1px solid}.blocks-table__placeholder-form.blocks-table__placeholder-form{align-items:flex-start;display:flex;flex-direction:column;gap:8px}@media (min-width:782px){.blocks-table__placeholder-form.blocks-table__placeholder-form{align-items:flex-end;flex-direction:row}}.blocks-table__placeholder-input{width:112px}.wp-block-tag-cloud .wp-block-tag-cloud{border:none;border-radius:inherit;margin:0;padding:0}.block-editor-template-part__selection-modal{z-index:1000001}.block-editor-template-part__selection-modal .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:1280px){.block-editor-template-part__selection-modal .block-editor-block-patterns-list{column-count:3}}.block-editor-template-part__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.block-library-template-part__selection-search{background:#fff;padding:16px 0;position:sticky;top:0;z-index:2}.block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{outline-color:var(--wp-block-synced-color)}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.has-editable-outline:after{border:none}.wp-block-text-columns .block-editor-rich-text__editable:focus{outline:1px solid #ddd}.wp-block[data-align=center]>.wp-block-video{text-align:center}.wp-block-video{position:relative}.wp-block-video.is-transient video{opacity:.3}.wp-block-video .components-spinner{left:50%;margin-left:-9px;margin-top:-9px;position:absolute;top:50%}.editor-video-poster-control .components-button{margin-right:8px}.block-library-video-tracks-editor{z-index:159990}.block-library-video-tracks-editor__track-list-track{padding-left:12px}.block-library-video-tracks-editor__single-track-editor-kind-select{max-width:240px}.block-library-video-tracks-editor__single-track-editor-edit-track-label,.block-library-video-tracks-editor__tracks-informative-message-title{color:#757575;display:block;font-size:11px;font-weight:500;margin-top:4px;text-transform:uppercase}.block-library-video-tracks-editor>.components-popover__content{width:360px}.block-library-video-tracks-editor__add-tracks-container .components-menu-group__label,.block-library-video-tracks-editor__track-list .components-menu-group__label{padding:0}.block-library-video-tracks-editor__tracks-informative-message{padding:8px}.block-library-video-tracks-editor__tracks-informative-message-description{margin-bottom:0}.block-library-query-pattern__selection-modal .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:1280px){.block-library-query-pattern__selection-modal .block-editor-block-patterns-list{column-count:3}}.block-library-query-pattern__selection-modal .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.block-library-query-pattern__selection-modal .block-library-query-pattern__selection-search{background:#fff;margin-bottom:-4px;padding:16px 0;position:sticky;top:0;transform:translateY(-4px);z-index:2}@media (min-width:600px){.wp-block-query__enhanced-pagination-modal{max-width:480px}}.block-editor-block-settings-menu__popover.is-expanded{overflow-y:scroll}.block-editor-block-settings-menu__popover .block-library-query-pattern__selection-content{height:100%}.block-editor-block-settings-menu__popover .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr;grid-gap:12px;min-width:280px}@media (min-width:600px){.block-editor-block-settings-menu__popover .block-editor-block-patterns-list{grid-template-columns:1fr 1fr;min-width:480px}}.block-editor-block-settings-menu__popover .block-editor-block-patterns-list__list-item{margin-bottom:0}.wp-block[data-align=center]>.wp-block-query-pagination{justify-content:center}:where(.editor-styles-wrapper) .wp-block-query-pagination{max-width:100%}:where(.editor-styles-wrapper) .wp-block-query-pagination.block-editor-block-list__layout{margin:0}.wp-block-query-pagination-numbers a{text-decoration:underline}.wp-block-query-pagination-numbers .page-numbers{margin-right:2px}.wp-block-query-pagination-numbers .page-numbers:last-child{margin-right:0}.wp-block-post-featured-image .block-editor-media-placeholder{-webkit-backdrop-filter:none;backdrop-filter:none;z-index:1}.wp-block-post-featured-image .components-placeholder,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder{align-items:center;display:flex;justify-content:center;min-height:200px;padding:0}.wp-block-post-featured-image .components-placeholder .components-form-file-upload,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-form-file-upload{display:none}.wp-block-post-featured-image .components-placeholder .components-button,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button{align-items:center;background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);border-radius:50%;border-style:solid;color:#fff;display:flex;height:48px;justify-content:center;margin:auto;padding:0;position:relative;width:48px}.wp-block-post-featured-image .components-placeholder .components-button>svg,.wp-block-post-featured-image .wp-block-post-featured-image__placeholder .components-button>svg{color:inherit}.wp-block-post-featured-image .components-placeholder:where(.has-border-color),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where(.has-border-color),.wp-block-post-featured-image img:where(.has-border-color){border-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-top-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-color]),.wp-block-post-featured-image img:where([style*=border-top-color]){border-top-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-right-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-color]),.wp-block-post-featured-image img:where([style*=border-right-color]){border-right-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-color]),.wp-block-post-featured-image img:where([style*=border-bottom-color]){border-bottom-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-left-color]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-color]),.wp-block-post-featured-image img:where([style*=border-left-color]){border-left-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-width]),.wp-block-post-featured-image img:where([style*=border-width]){border-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-top-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-top-width]),.wp-block-post-featured-image img:where([style*=border-top-width]){border-top-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-right-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-right-width]),.wp-block-post-featured-image img:where([style*=border-right-width]){border-right-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-bottom-width]),.wp-block-post-featured-image img:where([style*=border-bottom-width]){border-bottom-style:solid}.wp-block-post-featured-image .components-placeholder:where([style*=border-left-width]),.wp-block-post-featured-image .wp-block-post-featured-image__placeholder:where([style*=border-left-width]),.wp-block-post-featured-image img:where([style*=border-left-width]){border-left-style:solid}.wp-block-post-featured-image[style*=height] .components-placeholder{height:100%;min-height:48px;min-width:48px;width:100%}.wp-block-post-featured-image>a{pointer-events:none}.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-button,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__instructions,.wp-block-post-featured-image.is-selected .components-placeholder.has-illustration .components-placeholder__label{opacity:1;pointer-events:auto}.wp-block-post-featured-image.is-transient{position:relative}.wp-block-post-featured-image.is-transient img{opacity:.3}.wp-block-post-featured-image.is-transient .components-spinner{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}div[data-type="core/post-featured-image"] img{display:block;height:auto;max-width:100%}.wp-block-post-comments-form *{pointer-events:none}.wp-block-post-comments-form .block-editor-warning *{pointer-events:auto}.wp-element-button{cursor:revert}.wp-element-button[role=textbox]{cursor:text}:root .editor-styles-wrapper .has-very-light-gray-background-color{background-color:#eee}:root .editor-styles-wrapper .has-very-dark-gray-background-color{background-color:#313131}:root .editor-styles-wrapper .has-very-light-gray-color{color:#eee}:root .editor-styles-wrapper .has-very-dark-gray-color{color:#313131}:root .editor-styles-wrapper .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .editor-styles-wrapper .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .editor-styles-wrapper .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .editor-styles-wrapper .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .editor-styles-wrapper .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .editor-styles-wrapper .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .editor-styles-wrapper .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}:where(.editor-styles-wrapper) .has-regular-font-size{font-size:16px}:where(.editor-styles-wrapper) .has-larger-font-size{font-size:42px}:where(.editor-styles-wrapper) iframe:not([frameborder]){border:0}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.reusable-blocks-menu-items__convert-modal{z-index:1000001}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.reusable-blocks-menu-items__convert-modal{z-index:1000001}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .reusable-blocks-menu-items__convert-modal{ z-index:1000001; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .reusable-blocks-menu-items__convert-modal{ z-index:1000001; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-format-toolbar__image-popover{z-index:159990}.block-editor-format-toolbar__image-popover .block-editor-format-toolbar__image-container-content{padding:16px;width:260px}.block-editor-format-toolbar__link-container-content{align-items:center;display:flex}.block-editor-format-toolbar__link-container-value{flex-grow:1;flex-shrink:1;margin:7px;max-width:500px;min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-format-toolbar__link-container-value.has-invalid-link{color:#cc1818}.format-library__inline-color-popover [role=tabpanel]{padding:16px;width:260px}.block-editor-format-toolbar__language-popover .components-popover__content{padding:1rem;width:auto}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-format-toolbar__image-popover{z-index:159990}.block-editor-format-toolbar__image-popover .block-editor-format-toolbar__image-container-content{padding:16px;width:260px}.block-editor-format-toolbar__link-container-content{align-items:center;display:flex}.block-editor-format-toolbar__link-container-value{flex-grow:1;flex-shrink:1;margin:7px;max-width:500px;min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-format-toolbar__link-container-value.has-invalid-link{color:#cc1818}.format-library__inline-color-popover [role=tabpanel]{padding:16px;width:260px}.block-editor-format-toolbar__language-popover .components-popover__content{padding:1rem;width:auto}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-format-toolbar__image-popover{ z-index:159990; } .block-editor-format-toolbar__image-popover .block-editor-format-toolbar__image-container-content{ padding:16px; width:260px; } .block-editor-format-toolbar__link-container-content{ align-items:center; display:flex; } .block-editor-format-toolbar__link-container-value{ flex-grow:1; flex-shrink:1; margin:7px; max-width:500px; min-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-format-toolbar__link-container-value.has-invalid-link{ color:#cc1818; } .format-library__inline-color-popover [role=tabpanel]{ padding:16px; width:260px; } .block-editor-format-toolbar__language-popover .components-popover__content{ padding:1rem; width:auto; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-format-toolbar__image-popover{ z-index:159990; } .block-editor-format-toolbar__image-popover .block-editor-format-toolbar__image-container-content{ padding:16px; width:260px; } .block-editor-format-toolbar__link-container-content{ align-items:center; display:flex; } .block-editor-format-toolbar__link-container-value{ flex-grow:1; flex-shrink:1; margin:7px; max-width:500px; min-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-format-toolbar__link-container-value.has-invalid-link{ color:#cc1818; } .format-library__inline-color-popover [role=tabpanel]{ padding:16px; width:260px; } .block-editor-format-toolbar__language-popover .components-popover__content{ padding:1rem; width:auto; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .editor-styles-wrapper :where(:not(.is-layout-flex,.is-layout-grid))>.wp-block{ margin-left:auto; margin-right:auto; } html :where(.editor-styles-wrapper){ padding:8px; } html :where(.editor-styles-wrapper) .block-editor-block-list__layout.is-root-container>.wp-block[data-align=full]{ margin-left:-8px; margin-right:-8px; } html :where(.wp-block){ margin-bottom:28px; margin-top:28px; max-width:840px; } html :where(.wp-block)[data-align=wide]{ max-width:1100px; } html :where(.wp-block)[data-align=full]{ max-width:none; } html :where(.wp-block)[data-align=left],html :where(.wp-block)[data-align=right]{ height:0; width:100%; } html :where(.wp-block)[data-align=left]:before,html :where(.wp-block)[data-align=right]:before{ content:none; } html :where(.wp-block)[data-align=left]>*{ float:left; margin-right:2em; } html :where(.wp-block)[data-align=right]>*{ float:right; margin-left:2em; } html :where(.wp-block)[data-align=full],html :where(.wp-block)[data-align=wide]{ clear:both; } .wp-block-group>[data-align=full]{ margin-left:auto; margin-right:auto; } .wp-block-group.has-background>[data-align=full]{ margin-right:-30px; width:calc(100% + 60px); } [data-align=full] .wp-block-group>.wp-block{ padding-left:14px; padding-right:14px; } @media (min-width:600px){ [data-align=full] .wp-block-group>.wp-block{ padding-left:0; padding-right:0; } } [data-align=full] .wp-block-group>[data-align=full]{ max-width:none; padding-left:0; padding-right:0; right:0; width:100%; } [data-align=full] .wp-block-group.has-background>[data-align=full]{ width:calc(100% + 60px); }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .editor-styles-wrapper :where(:not(.is-layout-flex,.is-layout-grid))>.wp-block{ margin-left:auto; margin-right:auto; } html :where(.editor-styles-wrapper){ padding:8px; } html :where(.editor-styles-wrapper) .block-editor-block-list__layout.is-root-container>.wp-block[data-align=full]{ margin-left:-8px; margin-right:-8px; } html :where(.wp-block){ margin-bottom:28px; margin-top:28px; max-width:840px; } html :where(.wp-block)[data-align=wide]{ max-width:1100px; } html :where(.wp-block)[data-align=full]{ max-width:none; } html :where(.wp-block)[data-align=left],html :where(.wp-block)[data-align=right]{ height:0; width:100%; } html :where(.wp-block)[data-align=left]:before,html :where(.wp-block)[data-align=right]:before{ content:none; } html :where(.wp-block)[data-align=left]>*{ float:left; margin-right:2em; } html :where(.wp-block)[data-align=right]>*{ float:right; margin-left:2em; } html :where(.wp-block)[data-align=full],html :where(.wp-block)[data-align=wide]{ clear:both; } .wp-block-group>[data-align=full]{ margin-left:auto; margin-right:auto; } .wp-block-group.has-background>[data-align=full]{ margin-left:-30px; width:calc(100% + 60px); } [data-align=full] .wp-block-group>.wp-block{ padding-left:14px; padding-right:14px; } @media (min-width:600px){ [data-align=full] .wp-block-group>.wp-block{ padding-left:0; padding-right:0; } } [data-align=full] .wp-block-group>[data-align=full]{ left:0; max-width:none; padding-left:0; padding-right:0; width:100%; } [data-align=full] .wp-block-group.has-background>[data-align=full]{ width:calc(100% + 60px); }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.editor-styles-wrapper :where(:not(.is-layout-flex,.is-layout-grid))>.wp-block{margin-left:auto;margin-right:auto}html :where(.editor-styles-wrapper){padding:8px}html :where(.editor-styles-wrapper) .block-editor-block-list__layout.is-root-container>.wp-block[data-align=full]{margin-left:-8px;margin-right:-8px}html :where(.wp-block){margin-bottom:28px;margin-top:28px;max-width:840px}html :where(.wp-block)[data-align=wide]{max-width:1100px}html :where(.wp-block)[data-align=full]{max-width:none}html :where(.wp-block)[data-align=left],html :where(.wp-block)[data-align=right]{height:0;width:100%}html :where(.wp-block)[data-align=left]:before,html :where(.wp-block)[data-align=right]:before{content:none}html :where(.wp-block)[data-align=left]>*{ /*!rtl:begin:ignore*/float:left;margin-right:2em /*!rtl:end:ignore*/}html :where(.wp-block)[data-align=right]>*{ /*!rtl:begin:ignore*/float:right;margin-left:2em /*!rtl:end:ignore*/}html :where(.wp-block)[data-align=full],html :where(.wp-block)[data-align=wide]{clear:both}.wp-block-group>[data-align=full]{margin-left:auto;margin-right:auto}.wp-block-group.has-background>[data-align=full]{margin-left:-30px;width:calc(100% + 60px)}[data-align=full] .wp-block-group>.wp-block{padding-left:14px;padding-right:14px}@media (min-width:600px){[data-align=full] .wp-block-group>.wp-block{padding-left:0;padding-right:0}}[data-align=full] .wp-block-group>[data-align=full]{left:0;max-width:none;padding-left:0;padding-right:0;width:100%}[data-align=full] .wp-block-group.has-background>[data-align=full]{width:calc(100% + 60px)}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}@media (min-width:782px){.edit-post-fullscreen-mode-close.components-button{align-items:center;align-self:stretch;background:#1e1e1e;border:none;border-radius:0;color:#fff;display:flex;height:60px;position:relative;width:60px}.edit-post-fullscreen-mode-close.components-button:active{color:#fff}.edit-post-fullscreen-mode-close.components-button:focus{box-shadow:none}.edit-post-fullscreen-mode-close.components-button:before{border-radius:4px;bottom:10px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-post-fullscreen-mode-close.components-button:before{transition:box-shadow .1s ease}}@media (min-width:782px){.edit-post-fullscreen-mode-close.components-button:hover:before{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #757575}.edit-post-fullscreen-mode-close.components-button.has-icon:hover:before{box-shadow:none}.edit-post-fullscreen-mode-close.components-button:focus:before{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #ffffff1a,inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}}.edit-post-fullscreen-mode-close.components-button .edit-post-fullscreen-mode-close_site-icon{border-radius:2px;height:36px;margin-top:-1px;object-fit:cover;width:36px}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon{width:60px}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon svg{display:block}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon:after{content:none}.edit-post-meta-boxes-main{background-color:#fff;display:flex;filter:drop-shadow(0 -1px rgba(0,0,0,.133));flex-direction:column;outline:1px solid #0000;overflow:hidden}.edit-post-meta-boxes-main.is-resizable{padding-block-start:24px}.edit-post-meta-boxes-main__presenter{box-shadow:0 1px #ddd;display:flex;outline:1px solid #0000;position:relative;z-index:1}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button,.is-toggle-only>.edit-post-meta-boxes-main__presenter{appearance:none;background-color:initial;border:none;outline:none;padding:0}.is-toggle-only>.edit-post-meta-boxes-main__presenter{align-items:center;cursor:pointer;flex-shrink:0;height:32px;justify-content:space-between;padding-inline:24px 12px}.is-toggle-only>.edit-post-meta-boxes-main__presenter:is(:hover,:focus-visible){color:var(--wp-admin-theme-color)}.is-toggle-only>.edit-post-meta-boxes-main__presenter:focus-visible:after{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.is-toggle-only>.edit-post-meta-boxes-main__presenter>svg{fill:currentColor}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter{inset:0 0 auto}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{cursor:inherit;height:24px;margin:auto;width:64px}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{background-color:#ddd;border-radius:2px;content:"";height:4px;inset-block:calc(50% - 2px) auto;outline:2px solid #0000;outline-offset:-2px;position:absolute;transform:translateX(50%);width:inherit}@media not (prefers-reduced-motion){.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{transition:width .3s ease-out}}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter:is(:hover,:focus-within)>button:before{background-color:var(--wp-admin-theme-color);width:80px}@media (pointer:coarse){.is-resizable.edit-post-meta-boxes-main{padding-block-start:32px}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{height:32px}}.edit-post-meta-boxes-main__liner{isolation:isolate;overflow:auto}.edit-post-layout__metaboxes{clear:both}.has-metaboxes .interface-interface-skeleton__content:has(.edit-post-meta-boxes-main) .editor-visual-editor{flex-basis:0%;flex-shrink:1}.has-metaboxes .editor-visual-editor.is-iframed{isolation:isolate}.components-editor-notices__snackbar{bottom:24px;left:0;padding-left:24px;padding-right:24px;position:fixed}.edit-post-layout .components-editor-notices__snackbar{right:0}@media (min-width:783px){.edit-post-layout .components-editor-notices__snackbar{right:160px}}@media (min-width:783px){.auto-fold .edit-post-layout .components-editor-notices__snackbar{right:36px}}@media (min-width:961px){.auto-fold .edit-post-layout .components-editor-notices__snackbar{right:160px}}.folded .edit-post-layout .components-editor-notices__snackbar{right:0}@media (min-width:783px){.folded .edit-post-layout .components-editor-notices__snackbar{right:36px}}body.is-fullscreen-mode .edit-post-layout .components-editor-notices__snackbar{right:0!important}.edit-post-meta-boxes-area{position:relative}.edit-post-meta-boxes-area .inside,.edit-post-meta-boxes-area__container{box-sizing:initial}.edit-post-meta-boxes-area input,.edit-post-meta-boxes-area textarea{box-sizing:border-box}.edit-post-meta-boxes-area .postbox-header{border-bottom:0;border-top:1px solid #ddd}.edit-post-meta-boxes-area #poststuff{margin:0 auto;min-width:auto;padding-top:0}.edit-post-meta-boxes-area #poststuff .stuffbox>h3,.edit-post-meta-boxes-area #poststuff h2.hndle,.edit-post-meta-boxes-area #poststuff h3.hndle{box-sizing:border-box;color:inherit;font-weight:600;outline:none;padding:0 24px;position:relative;width:100%}.edit-post-meta-boxes-area .postbox{border:0;color:inherit;margin-bottom:0}.edit-post-meta-boxes-area .postbox>.inside{color:inherit;margin:0;padding:0 24px 24px}.edit-post-meta-boxes-area .postbox .handlediv{height:44px;width:44px}.edit-post-meta-boxes-area.is-loading:before{background:#0000;bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.edit-post-meta-boxes-area .components-spinner{left:20px;position:absolute;top:10px;z-index:5}.edit-post-meta-boxes-area .is-hidden{display:none}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]{border:1px solid #757575}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:checked{background:#fff;border-color:#757575}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:before{margin:-3px -4px}.edit-post-meta-boxes-area__clear{clear:both}.edit-post-welcome-guide,.edit-template-welcome-guide{width:312px}.edit-post-welcome-guide__image,.edit-template-welcome-guide__image{background:#00a0d2;margin:0 0 16px}.edit-post-welcome-guide__image>img,.edit-template-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-post-welcome-guide__heading,.edit-template-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-post-welcome-guide__text,.edit-template-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 24px;padding:0 32px}.edit-post-welcome-guide__inserter-icon,.edit-template-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-template-welcome-guide .components-button svg{fill:#fff}body.js.block-editor-page{background:#fff}body.js.block-editor-page #wpcontent{padding-right:0}body.js.block-editor-page #wpbody-content{padding-bottom:0}body.js.block-editor-page #wpbody-content>div:not(.block-editor):not(#screen-meta),body.js.block-editor-page #wpfooter{display:none}body.js.block-editor-page .a11y-speak-region{right:-1px;top:-1px}body.js.block-editor-page ul#adminmenu a.wp-has-current-submenu:after,body.js.block-editor-page ul#adminmenu>li.current>a.current:after{border-left-color:#fff}body.js.block-editor-page .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}.block-editor-page #wpwrap{overflow-y:auto}@media (min-width:782px){.block-editor-page #wpwrap{overflow-y:initial}}.edit-post-visual-editor.is-iframed,.editor-header,.editor-post-publish-panel,.editor-sidebar,.editor-text-editor{box-sizing:border-box}.edit-post-visual-editor.is-iframed *,.edit-post-visual-editor.is-iframed :after,.edit-post-visual-editor.is-iframed :before,.editor-header *,.editor-header :after,.editor-header :before,.editor-post-publish-panel *,.editor-post-publish-panel :after,.editor-post-publish-panel :before,.editor-sidebar *,.editor-sidebar :after,.editor-sidebar :before,.editor-text-editor *,.editor-text-editor :after,.editor-text-editor :before{box-sizing:inherit}@media (min-width:600px){.block-editor__container{bottom:0;left:0;min-height:calc(100vh - 46px);position:absolute;right:0;top:0}}@media (min-width:782px){.block-editor__container{min-height:calc(100vh - 32px)}body.is-fullscreen-mode .block-editor__container{min-height:100vh}}.block-editor__container img{height:auto;max-width:100%}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}@media (min-width:782px){.edit-post-fullscreen-mode-close.components-button{align-items:center;align-self:stretch;background:#1e1e1e;border:none;border-radius:0;color:#fff;display:flex;height:60px;position:relative;width:60px}.edit-post-fullscreen-mode-close.components-button:active{color:#fff}.edit-post-fullscreen-mode-close.components-button:focus{box-shadow:none}.edit-post-fullscreen-mode-close.components-button:before{border-radius:4px;bottom:10px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-post-fullscreen-mode-close.components-button:before{transition:box-shadow .1s ease}}@media (min-width:782px){.edit-post-fullscreen-mode-close.components-button:hover:before{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #757575}.edit-post-fullscreen-mode-close.components-button.has-icon:hover:before{box-shadow:none}.edit-post-fullscreen-mode-close.components-button:focus:before{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #ffffff1a,inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}}.edit-post-fullscreen-mode-close.components-button .edit-post-fullscreen-mode-close_site-icon{border-radius:2px;height:36px;margin-top:-1px;object-fit:cover;width:36px}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon{width:60px}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon svg{display:block}.show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon:after{content:none}.edit-post-meta-boxes-main{background-color:#fff;display:flex;filter:drop-shadow(0 -1px rgba(0,0,0,.133));flex-direction:column;outline:1px solid #0000;overflow:hidden}.edit-post-meta-boxes-main.is-resizable{padding-block-start:24px}.edit-post-meta-boxes-main__presenter{box-shadow:0 1px #ddd;display:flex;outline:1px solid #0000;position:relative;z-index:1}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button,.is-toggle-only>.edit-post-meta-boxes-main__presenter{appearance:none;background-color:initial;border:none;outline:none;padding:0}.is-toggle-only>.edit-post-meta-boxes-main__presenter{align-items:center;cursor:pointer;flex-shrink:0;height:32px;justify-content:space-between;padding-inline:24px 12px}.is-toggle-only>.edit-post-meta-boxes-main__presenter:is(:hover,:focus-visible){color:var(--wp-admin-theme-color)}.is-toggle-only>.edit-post-meta-boxes-main__presenter:focus-visible:after{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.is-toggle-only>.edit-post-meta-boxes-main__presenter>svg{fill:currentColor}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter{inset:0 0 auto}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{cursor:inherit;height:24px;margin:auto;width:64px}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{background-color:#ddd;border-radius:2px;content:"";height:4px;inset-block:calc(50% - 2px) auto;outline:2px solid #0000;outline-offset:-2px;position:absolute;transform:translateX(-50%);width:inherit}@media not (prefers-reduced-motion){.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{transition:width .3s ease-out}}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter:is(:hover,:focus-within)>button:before{background-color:var(--wp-admin-theme-color);width:80px}@media (pointer:coarse){.is-resizable.edit-post-meta-boxes-main{padding-block-start:32px}.is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{height:32px}}.edit-post-meta-boxes-main__liner{isolation:isolate;overflow:auto}.edit-post-layout__metaboxes{clear:both}.has-metaboxes .interface-interface-skeleton__content:has(.edit-post-meta-boxes-main) .editor-visual-editor{flex-basis:0%;flex-shrink:1}.has-metaboxes .editor-visual-editor.is-iframed{isolation:isolate}.components-editor-notices__snackbar{bottom:24px;padding-left:24px;padding-right:24px;position:fixed;right:0}.edit-post-layout .components-editor-notices__snackbar{left:0}@media (min-width:783px){.edit-post-layout .components-editor-notices__snackbar{left:160px}}@media (min-width:783px){.auto-fold .edit-post-layout .components-editor-notices__snackbar{left:36px}}@media (min-width:961px){.auto-fold .edit-post-layout .components-editor-notices__snackbar{left:160px}}.folded .edit-post-layout .components-editor-notices__snackbar{left:0}@media (min-width:783px){.folded .edit-post-layout .components-editor-notices__snackbar{left:36px}}body.is-fullscreen-mode .edit-post-layout .components-editor-notices__snackbar{left:0!important}.edit-post-meta-boxes-area{position:relative}.edit-post-meta-boxes-area .inside,.edit-post-meta-boxes-area__container{box-sizing:initial}.edit-post-meta-boxes-area input,.edit-post-meta-boxes-area textarea{box-sizing:border-box}.edit-post-meta-boxes-area .postbox-header{border-bottom:0;border-top:1px solid #ddd}.edit-post-meta-boxes-area #poststuff{margin:0 auto;min-width:auto;padding-top:0}.edit-post-meta-boxes-area #poststuff .stuffbox>h3,.edit-post-meta-boxes-area #poststuff h2.hndle,.edit-post-meta-boxes-area #poststuff h3.hndle{box-sizing:border-box;color:inherit;font-weight:600;outline:none;padding:0 24px;position:relative;width:100%}.edit-post-meta-boxes-area .postbox{border:0;color:inherit;margin-bottom:0}.edit-post-meta-boxes-area .postbox>.inside{color:inherit;margin:0;padding:0 24px 24px}.edit-post-meta-boxes-area .postbox .handlediv{height:44px;width:44px}.edit-post-meta-boxes-area.is-loading:before{background:#0000;bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.edit-post-meta-boxes-area .components-spinner{position:absolute;right:20px;top:10px;z-index:5}.edit-post-meta-boxes-area .is-hidden{display:none}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]{border:1px solid #757575}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:checked{background:#fff;border-color:#757575}.edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:before{margin:-3px -4px}.edit-post-meta-boxes-area__clear{clear:both}.edit-post-welcome-guide,.edit-template-welcome-guide{width:312px}.edit-post-welcome-guide__image,.edit-template-welcome-guide__image{background:#00a0d2;margin:0 0 16px}.edit-post-welcome-guide__image>img,.edit-template-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-post-welcome-guide__heading,.edit-template-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-post-welcome-guide__text,.edit-template-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 24px;padding:0 32px}.edit-post-welcome-guide__inserter-icon,.edit-template-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-template-welcome-guide .components-button svg{fill:#fff}body.js.block-editor-page{background:#fff}body.js.block-editor-page #wpcontent{padding-left:0}body.js.block-editor-page #wpbody-content{padding-bottom:0}body.js.block-editor-page #wpbody-content>div:not(.block-editor):not(#screen-meta),body.js.block-editor-page #wpfooter{display:none}body.js.block-editor-page .a11y-speak-region{left:-1px;top:-1px}body.js.block-editor-page ul#adminmenu a.wp-has-current-submenu:after,body.js.block-editor-page ul#adminmenu>li.current>a.current:after{border-right-color:#fff}body.js.block-editor-page .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}.block-editor-page #wpwrap{overflow-y:auto}@media (min-width:782px){.block-editor-page #wpwrap{overflow-y:initial}}.edit-post-visual-editor.is-iframed,.editor-header,.editor-post-publish-panel,.editor-sidebar,.editor-text-editor{box-sizing:border-box}.edit-post-visual-editor.is-iframed *,.edit-post-visual-editor.is-iframed :after,.edit-post-visual-editor.is-iframed :before,.editor-header *,.editor-header :after,.editor-header :before,.editor-post-publish-panel *,.editor-post-publish-panel :after,.editor-post-publish-panel :before,.editor-sidebar *,.editor-sidebar :after,.editor-sidebar :before,.editor-text-editor *,.editor-text-editor :after,.editor-text-editor :before{box-sizing:inherit}@media (min-width:600px){.block-editor__container{bottom:0;left:0;min-height:calc(100vh - 46px);position:absolute;right:0;top:0}}@media (min-width:782px){.block-editor__container{min-height:calc(100vh - 32px)}body.is-fullscreen-mode .block-editor__container{min-height:100vh}}.block-editor__container img{height:auto;max-width:100%}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.editor-styles-wrapper :where(:not(.is-layout-flex,.is-layout-grid))>.wp-block{margin-left:auto;margin-right:auto}html :where(.editor-styles-wrapper){padding:8px}html :where(.editor-styles-wrapper) .block-editor-block-list__layout.is-root-container>.wp-block[data-align=full]{margin-left:-8px;margin-right:-8px}html :where(.wp-block){margin-bottom:28px;margin-top:28px;max-width:840px}html :where(.wp-block)[data-align=wide]{max-width:1100px}html :where(.wp-block)[data-align=full]{max-width:none}html :where(.wp-block)[data-align=left],html :where(.wp-block)[data-align=right]{height:0;width:100%}html :where(.wp-block)[data-align=left]:before,html :where(.wp-block)[data-align=right]:before{content:none}html :where(.wp-block)[data-align=left]>*{float:left;margin-right:2em}html :where(.wp-block)[data-align=right]>*{float:right;margin-left:2em}html :where(.wp-block)[data-align=full],html :where(.wp-block)[data-align=wide]{clear:both}.wp-block-group>[data-align=full]{margin-left:auto;margin-right:auto}.wp-block-group.has-background>[data-align=full]{margin-right:-30px;width:calc(100% + 60px)}[data-align=full] .wp-block-group>.wp-block{padding-left:14px;padding-right:14px}@media (min-width:600px){[data-align=full] .wp-block-group>.wp-block{padding-left:0;padding-right:0}}[data-align=full] .wp-block-group>[data-align=full]{max-width:none;padding-left:0;padding-right:0;right:0;width:100%}[data-align=full] .wp-block-group.has-background>[data-align=full]{width:calc(100% + 60px)}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } @media (min-width:782px){ .edit-post-fullscreen-mode-close.components-button{ align-items:center; align-self:stretch; background:#1e1e1e; border:none; border-radius:0; color:#fff; display:flex; height:60px; position:relative; width:60px; } .edit-post-fullscreen-mode-close.components-button:active{ color:#fff; } .edit-post-fullscreen-mode-close.components-button:focus{ box-shadow:none; } .edit-post-fullscreen-mode-close.components-button:before{ border-radius:4px; bottom:10px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-post-fullscreen-mode-close.components-button:before{ transition:box-shadow .1s ease; } } @media (min-width:782px){ .edit-post-fullscreen-mode-close.components-button:hover:before{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #757575; } .edit-post-fullscreen-mode-close.components-button.has-icon:hover:before{ box-shadow:none; } .edit-post-fullscreen-mode-close.components-button:focus:before{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #ffffff1a, inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } } .edit-post-fullscreen-mode-close.components-button .edit-post-fullscreen-mode-close_site-icon{ border-radius:2px; height:36px; margin-top:-1px; object-fit:cover; width:36px; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon{ width:60px; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon svg{ display:block; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon:after{ content:none; } .edit-post-meta-boxes-main{ background-color:#fff; display:flex; filter:drop-shadow(0 -1px rgba(0, 0, 0, .133)); flex-direction:column; outline:1px solid #0000; overflow:hidden; } .edit-post-meta-boxes-main.is-resizable{ padding-block-start:24px; } .edit-post-meta-boxes-main__presenter{ box-shadow:0 1px #ddd; display:flex; outline:1px solid #0000; position:relative; z-index:1; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button,.is-toggle-only>.edit-post-meta-boxes-main__presenter{ appearance:none; background-color:initial; border:none; outline:none; padding:0; } .is-toggle-only>.edit-post-meta-boxes-main__presenter{ align-items:center; cursor:pointer; flex-shrink:0; height:32px; justify-content:space-between; padding-inline:24px 12px; } .is-toggle-only>.edit-post-meta-boxes-main__presenter:is(:hover,:focus-visible){ color:var(--wp-admin-theme-color); } .is-toggle-only>.edit-post-meta-boxes-main__presenter:focus-visible:after{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .is-toggle-only>.edit-post-meta-boxes-main__presenter>svg{ fill:currentColor; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter{ inset:0 0 auto; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{ cursor:inherit; height:24px; margin:auto; width:64px; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{ background-color:#ddd; border-radius:2px; content:""; height:4px; inset-block:calc(50% - 2px) auto; outline:2px solid #0000; outline-offset:-2px; position:absolute; transform:translateX(50%); width:inherit; } @media not (prefers-reduced-motion){ .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{ transition:width .3s ease-out; } } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter:is(:hover,:focus-within)>button:before{ background-color:var(--wp-admin-theme-color); width:80px; } @media (pointer:coarse){ .is-resizable.edit-post-meta-boxes-main{ padding-block-start:32px; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{ height:32px; } } .edit-post-meta-boxes-main__liner{ isolation:isolate; overflow:auto; } .edit-post-layout__metaboxes{ clear:both; } .has-metaboxes .interface-interface-skeleton__content:has(.edit-post-meta-boxes-main) .editor-visual-editor{ flex-basis:0%; flex-shrink:1; } .has-metaboxes .editor-visual-editor.is-iframed{ isolation:isolate; } .components-editor-notices__snackbar{ bottom:24px; left:0; padding-left:24px; padding-right:24px; position:fixed; } .edit-post-layout .components-editor-notices__snackbar{ right:0; } @media (min-width:783px){ .edit-post-layout .components-editor-notices__snackbar{ right:160px; } } @media (min-width:783px){ .auto-fold .edit-post-layout .components-editor-notices__snackbar{ right:36px; } } @media (min-width:961px){ .auto-fold .edit-post-layout .components-editor-notices__snackbar{ right:160px; } } .folded .edit-post-layout .components-editor-notices__snackbar{ right:0; } @media (min-width:783px){ .folded .edit-post-layout .components-editor-notices__snackbar{ right:36px; } } body.is-fullscreen-mode .edit-post-layout .components-editor-notices__snackbar{ right:0 !important; } .edit-post-meta-boxes-area{ position:relative; } .edit-post-meta-boxes-area .inside,.edit-post-meta-boxes-area__container{ box-sizing:initial; } .edit-post-meta-boxes-area input,.edit-post-meta-boxes-area textarea{ box-sizing:border-box; } .edit-post-meta-boxes-area .postbox-header{ border-bottom:0; border-top:1px solid #ddd; } .edit-post-meta-boxes-area #poststuff{ margin:0 auto; min-width:auto; padding-top:0; } .edit-post-meta-boxes-area #poststuff .stuffbox>h3,.edit-post-meta-boxes-area #poststuff h2.hndle,.edit-post-meta-boxes-area #poststuff h3.hndle{ box-sizing:border-box; color:inherit; font-weight:600; outline:none; padding:0 24px; position:relative; width:100%; } .edit-post-meta-boxes-area .postbox{ border:0; color:inherit; margin-bottom:0; } .edit-post-meta-boxes-area .postbox>.inside{ color:inherit; margin:0; padding:0 24px 24px; } .edit-post-meta-boxes-area .postbox .handlediv{ height:44px; width:44px; } .edit-post-meta-boxes-area.is-loading:before{ background:#0000; bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-post-meta-boxes-area .components-spinner{ left:20px; position:absolute; top:10px; z-index:5; } .edit-post-meta-boxes-area .is-hidden{ display:none; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]{ border:1px solid #757575; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:checked{ background:#fff; border-color:#757575; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:before{ margin:-3px -4px; } .edit-post-meta-boxes-area__clear{ clear:both; } .edit-post-welcome-guide,.edit-template-welcome-guide{ width:312px; } .edit-post-welcome-guide__image,.edit-template-welcome-guide__image{ background:#00a0d2; margin:0 0 16px; } .edit-post-welcome-guide__image>img,.edit-template-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-post-welcome-guide__heading,.edit-template-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-post-welcome-guide__text,.edit-template-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 24px; padding:0 32px; } .edit-post-welcome-guide__inserter-icon,.edit-template-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-template-welcome-guide .components-button svg{ fill:#fff; } body.js.block-editor-page{ background:#fff; } body.js.block-editor-page #wpcontent{ padding-right:0; } body.js.block-editor-page #wpbody-content{ padding-bottom:0; } body.js.block-editor-page #wpbody-content>div:not(.block-editor):not(#screen-meta),body.js.block-editor-page #wpfooter{ display:none; } body.js.block-editor-page .a11y-speak-region{ right:-1px; top:-1px; } body.js.block-editor-page ul#adminmenu a.wp-has-current-submenu:after,body.js.block-editor-page ul#adminmenu>li.current>a.current:after{ border-left-color:#fff; } body.js.block-editor-page .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } .block-editor-page #wpwrap{ overflow-y:auto; } @media (min-width:782px){ .block-editor-page #wpwrap{ overflow-y:initial; } } .edit-post-visual-editor.is-iframed,.editor-header,.editor-post-publish-panel,.editor-sidebar,.editor-text-editor{ box-sizing:border-box; } .edit-post-visual-editor.is-iframed *,.edit-post-visual-editor.is-iframed :after,.edit-post-visual-editor.is-iframed :before,.editor-header *,.editor-header :after,.editor-header :before,.editor-post-publish-panel *,.editor-post-publish-panel :after,.editor-post-publish-panel :before,.editor-sidebar *,.editor-sidebar :after,.editor-sidebar :before,.editor-text-editor *,.editor-text-editor :after,.editor-text-editor :before{ box-sizing:inherit; } @media (min-width:600px){ .block-editor__container{ bottom:0; left:0; min-height:calc(100vh - 46px); position:absolute; right:0; top:0; } } @media (min-width:782px){ .block-editor__container{ min-height:calc(100vh - 32px); } body.is-fullscreen-mode .block-editor__container{ min-height:100vh; } } .block-editor__container img{ height:auto; max-width:100%; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } @media (min-width:782px){ .edit-post-fullscreen-mode-close.components-button{ align-items:center; align-self:stretch; background:#1e1e1e; border:none; border-radius:0; color:#fff; display:flex; height:60px; position:relative; width:60px; } .edit-post-fullscreen-mode-close.components-button:active{ color:#fff; } .edit-post-fullscreen-mode-close.components-button:focus{ box-shadow:none; } .edit-post-fullscreen-mode-close.components-button:before{ border-radius:4px; bottom:10px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-post-fullscreen-mode-close.components-button:before{ transition:box-shadow .1s ease; } } @media (min-width:782px){ .edit-post-fullscreen-mode-close.components-button:hover:before{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #757575; } .edit-post-fullscreen-mode-close.components-button.has-icon:hover:before{ box-shadow:none; } .edit-post-fullscreen-mode-close.components-button:focus:before{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #ffffff1a, inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } } .edit-post-fullscreen-mode-close.components-button .edit-post-fullscreen-mode-close_site-icon{ border-radius:2px; height:36px; margin-top:-1px; object-fit:cover; width:36px; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon{ width:60px; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon svg{ display:block; } .show-icon-labels .editor-header .edit-post-fullscreen-mode-close.has-icon:after{ content:none; } .edit-post-meta-boxes-main{ background-color:#fff; display:flex; filter:drop-shadow(0 -1px rgba(0, 0, 0, .133)); flex-direction:column; outline:1px solid #0000; overflow:hidden; } .edit-post-meta-boxes-main.is-resizable{ padding-block-start:24px; } .edit-post-meta-boxes-main__presenter{ box-shadow:0 1px #ddd; display:flex; outline:1px solid #0000; position:relative; z-index:1; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button,.is-toggle-only>.edit-post-meta-boxes-main__presenter{ appearance:none; background-color:initial; border:none; outline:none; padding:0; } .is-toggle-only>.edit-post-meta-boxes-main__presenter{ align-items:center; cursor:pointer; flex-shrink:0; height:32px; justify-content:space-between; padding-inline:24px 12px; } .is-toggle-only>.edit-post-meta-boxes-main__presenter:is(:hover,:focus-visible){ color:var(--wp-admin-theme-color); } .is-toggle-only>.edit-post-meta-boxes-main__presenter:focus-visible:after{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .is-toggle-only>.edit-post-meta-boxes-main__presenter>svg{ fill:currentColor; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter{ inset:0 0 auto; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{ cursor:inherit; height:24px; margin:auto; width:64px; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{ background-color:#ddd; border-radius:2px; content:""; height:4px; inset-block:calc(50% - 2px) auto; outline:2px solid #0000; outline-offset:-2px; position:absolute; transform:translateX(-50%); width:inherit; } @media not (prefers-reduced-motion){ .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button:before{ transition:width .3s ease-out; } } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter:is(:hover,:focus-within)>button:before{ background-color:var(--wp-admin-theme-color); width:80px; } @media (pointer:coarse){ .is-resizable.edit-post-meta-boxes-main{ padding-block-start:32px; } .is-resizable.edit-post-meta-boxes-main .edit-post-meta-boxes-main__presenter>button{ height:32px; } } .edit-post-meta-boxes-main__liner{ isolation:isolate; overflow:auto; } .edit-post-layout__metaboxes{ clear:both; } .has-metaboxes .interface-interface-skeleton__content:has(.edit-post-meta-boxes-main) .editor-visual-editor{ flex-basis:0%; flex-shrink:1; } .has-metaboxes .editor-visual-editor.is-iframed{ isolation:isolate; } .components-editor-notices__snackbar{ bottom:24px; padding-left:24px; padding-right:24px; position:fixed; right:0; } .edit-post-layout .components-editor-notices__snackbar{ left:0; } @media (min-width:783px){ .edit-post-layout .components-editor-notices__snackbar{ left:160px; } } @media (min-width:783px){ .auto-fold .edit-post-layout .components-editor-notices__snackbar{ left:36px; } } @media (min-width:961px){ .auto-fold .edit-post-layout .components-editor-notices__snackbar{ left:160px; } } .folded .edit-post-layout .components-editor-notices__snackbar{ left:0; } @media (min-width:783px){ .folded .edit-post-layout .components-editor-notices__snackbar{ left:36px; } } body.is-fullscreen-mode .edit-post-layout .components-editor-notices__snackbar{ left:0 !important; } .edit-post-meta-boxes-area{ position:relative; } .edit-post-meta-boxes-area .inside,.edit-post-meta-boxes-area__container{ box-sizing:initial; } .edit-post-meta-boxes-area input,.edit-post-meta-boxes-area textarea{ box-sizing:border-box; } .edit-post-meta-boxes-area .postbox-header{ border-bottom:0; border-top:1px solid #ddd; } .edit-post-meta-boxes-area #poststuff{ margin:0 auto; min-width:auto; padding-top:0; } .edit-post-meta-boxes-area #poststuff .stuffbox>h3,.edit-post-meta-boxes-area #poststuff h2.hndle,.edit-post-meta-boxes-area #poststuff h3.hndle{ box-sizing:border-box; color:inherit; font-weight:600; outline:none; padding:0 24px; position:relative; width:100%; } .edit-post-meta-boxes-area .postbox{ border:0; color:inherit; margin-bottom:0; } .edit-post-meta-boxes-area .postbox>.inside{ color:inherit; margin:0; padding:0 24px 24px; } .edit-post-meta-boxes-area .postbox .handlediv{ height:44px; width:44px; } .edit-post-meta-boxes-area.is-loading:before{ background:#0000; bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-post-meta-boxes-area .components-spinner{ position:absolute; right:20px; top:10px; z-index:5; } .edit-post-meta-boxes-area .is-hidden{ display:none; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]{ border:1px solid #757575; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:checked{ background:#fff; border-color:#757575; } .edit-post-meta-boxes-area .metabox-location-side .postbox input[type=checkbox]:before{ margin:-3px -4px; } .edit-post-meta-boxes-area__clear{ clear:both; } .edit-post-welcome-guide,.edit-template-welcome-guide{ width:312px; } .edit-post-welcome-guide__image,.edit-template-welcome-guide__image{ background:#00a0d2; margin:0 0 16px; } .edit-post-welcome-guide__image>img,.edit-template-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-post-welcome-guide__heading,.edit-template-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-post-welcome-guide__text,.edit-template-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 24px; padding:0 32px; } .edit-post-welcome-guide__inserter-icon,.edit-template-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-template-welcome-guide .components-button svg{ fill:#fff; } body.js.block-editor-page{ background:#fff; } body.js.block-editor-page #wpcontent{ padding-left:0; } body.js.block-editor-page #wpbody-content{ padding-bottom:0; } body.js.block-editor-page #wpbody-content>div:not(.block-editor):not(#screen-meta),body.js.block-editor-page #wpfooter{ display:none; } body.js.block-editor-page .a11y-speak-region{ left:-1px; top:-1px; } body.js.block-editor-page ul#adminmenu a.wp-has-current-submenu:after,body.js.block-editor-page ul#adminmenu>li.current>a.current:after{ border-right-color:#fff; } body.js.block-editor-page .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } .block-editor-page #wpwrap{ overflow-y:auto; } @media (min-width:782px){ .block-editor-page #wpwrap{ overflow-y:initial; } } .edit-post-visual-editor.is-iframed,.editor-header,.editor-post-publish-panel,.editor-sidebar,.editor-text-editor{ box-sizing:border-box; } .edit-post-visual-editor.is-iframed *,.edit-post-visual-editor.is-iframed :after,.edit-post-visual-editor.is-iframed :before,.editor-header *,.editor-header :after,.editor-header :before,.editor-post-publish-panel *,.editor-post-publish-panel :after,.editor-post-publish-panel :before,.editor-sidebar *,.editor-sidebar :after,.editor-sidebar :before,.editor-text-editor *,.editor-text-editor :after,.editor-text-editor :before{ box-sizing:inherit; } @media (min-width:600px){ .block-editor__container{ bottom:0; left:0; min-height:calc(100vh - 46px); position:absolute; right:0; top:0; } } @media (min-width:782px){ .block-editor__container{ min-height:calc(100vh - 32px); } body.is-fullscreen-mode .block-editor__container{ min-height:100vh; } } .block-editor__container img{ height:auto; max-width:100%; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .dataviews-wrapper{ box-sizing:border-box; container:dataviews-wrapper/inline-size; display:flex; flex-direction:column; font-size:13px; height:100%; line-height:1.4; overflow:auto; scroll-padding-bottom:64px; } .dataviews-filters__container,.dataviews__view-actions{ box-sizing:border-box; flex-shrink:0; left:0; padding:16px 48px; position:sticky; } @media not (prefers-reduced-motion){ .dataviews-filters__container,.dataviews__view-actions{ transition:padding .1s ease-out; } } .dataviews-loading,.dataviews-no-results{ align-items:center; display:flex; flex-grow:1; justify-content:center; padding:0 48px; } @media not (prefers-reduced-motion){ .dataviews-loading,.dataviews-no-results{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-filters__container,.dataviews__view-actions{ padding:12px 24px; } .dataviews-loading,.dataviews-no-results{ padding-left:24px; padding-right:24px; } } .dataviews-title-field{ font-size:13px; font-weight:500; width:100%; } .dataviews-title-field,.dataviews-title-field a{ color:#2f2f2f; text-overflow:ellipsis; white-space:nowrap; } .dataviews-title-field a{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; } .dataviews-title-field a:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field a:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-title-field button.components-button.is-link{ color:#1e1e1e; display:block; font-weight:inherit; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; width:100%; } .dataviews-title-field button.components-button.is-link:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable{ color:#2f2f2f; cursor:pointer; } .dataviews-title-field--clickable:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-bulk-actions-footer__item-count{ color:#1e1e1e; font-size:11px; font-weight:500; text-transform:uppercase; } .dataviews-bulk-actions-footer__container{ margin-right:auto; min-height:32px; } .dataviews-filters__button{ position:relative; } .dataviews-filters__container{ padding-top:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{ opacity:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{ opacity:1; } .dataviews-filters__summary-popover{ font-size:13px; line-height:1.4; } .dataviews-filters__summary-popover .components-popover__content{ border-radius:4px; width:230px; } .dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{ padding:0; } .dataviews-filters__summary-operators-container{ padding:8px 8px 0; } .dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){ border-bottom:1px solid #e0e0e0; padding-bottom:8px; } .dataviews-filters__summary-operators-container:empty{ display:none; } .dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{ color:#757575; } .dataviews-filters__summary-chip-container{ position:relative; white-space:pre-wrap; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{ align-items:center; background:#f0f0f0; border:1px solid #0000; border-radius:16px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:flex; min-height:32px; padding:4px 12px; position:relative; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{ padding-inline-end:28px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{ background:#e0e0e0; color:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{ background:rgba(var(--wp-admin-theme-color--rgb), .04); color:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{ background:rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{ font-weight:500; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{ align-items:center; background:#0000; border:0; border-radius:50%; cursor:pointer; display:flex; height:24px; justify-content:center; padding:0; position:absolute; right:4px; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{ fill:#757575; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{ background:#e0e0e0; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{ fill:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{ fill:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__search-widget-filter-combobox-list{ border-top:1px solid #e0e0e0; max-height:184px; overflow:auto; padding:4px; } .dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{ font-weight:600; } .dataviews-filters__search-widget-listbox{ overflow:auto; padding:4px; } .dataviews-filters__search-widget-listitem{ align-items:center; border-radius:2px; box-sizing:border-box; cursor:default; display:flex; gap:8px; margin-block-end:2px; padding:8px 12px; } .dataviews-filters__search-widget-listitem:last-child{ margin-block-end:0; } .dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{ background-color:var(--wp-admin-theme-color); color:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{ fill:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{ color:#fff; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{ flex-shrink:0; height:24px; width:24px; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{ color:#757575; display:block; font-size:12px; line-height:16px; overflow:hidden; text-overflow:ellipsis; } .dataviews-filters__search-widget-filter-combobox__wrapper{ padding:8px; position:relative; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ background:#f0f0f0; border:none; border-radius:2px; box-shadow:0 0 0 #0000; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin-left:0; margin-right:0; padding:0 32px 0 8px; width:100%; } @media not (prefers-reduced-motion){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; line-height:normal; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ background:#fff; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{ color:#757575; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{ -webkit-appearance:none; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{ align-items:center; display:flex; justify-content:center; position:absolute; right:12px; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__container-visibility-toggle{ flex-shrink:0; position:relative; } .dataviews-filters-toggle__count{ background:var(--wp-admin-theme-color, #3858e9); border-radius:8px; box-sizing:border-box; color:#fff; font-size:11px; height:16px; line-height:16px; min-width:16px; outline:var(--wp-admin-border-width-focus) solid #fff; padding:0 4px; position:absolute; right:0; text-align:center; top:0; transform:translate(50%, -50%); } .dataviews-search{ width:fit-content; } .dataviews-footer{ background-color:#fff; border-top:1px solid #f0f0f0; bottom:0; flex-shrink:0; left:0; padding:12px 48px; position:sticky; z-index:2; } @media not (prefers-reduced-motion){ .dataviews-footer{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-footer{ padding:12px 24px; } } @container (max-width: 560px){ .dataviews-footer{ flex-direction:column !important; } .dataviews-footer .dataviews-bulk-actions-footer__container{ width:100%; } .dataviews-footer .dataviews-bulk-actions-footer__item-count{ flex-grow:1; } .dataviews-footer .dataviews-pagination{ justify-content:space-between; width:100%; } } .dataviews-pagination__page-select{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .dataviews-pagination__page-select .components-select-control__input{ font-size:11px !important; font-weight:500; } } .dataviews-action-modal{ z-index:1000001; } .dataviews-selection-checkbox{ --checkbox-input-size:24px; flex-shrink:0; line-height:0; } @media (min-width:600px){ .dataviews-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-selection-checkbox .components-checkbox-control__input-container{ margin:0; } .dataviews-view-config{ container-type:inline-size; font-size:13px; line-height:1.4; width:320px; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{ height:100%; overflow-y:scroll; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{ width:auto; } .dataviews-view-config__sort-direction .components-toggle-group-control-option-base{ text-transform:uppercase; } .dataviews-settings-section__title.dataviews-settings-section__title{ font-size:15px; line-height:24px; } .dataviews-settings-section__sidebar{ grid-column:span 4; } .dataviews-settings-section__content,.dataviews-settings-section__content>*{ grid-column:span 8; } .dataviews-settings-section__content .is-divided-in-two{ display:contents; } .dataviews-settings-section__content .is-divided-in-two>*{ grid-column:span 4; } .dataviews-settings-section:has(.dataviews-settings-section__content:empty){ display:none; } @container (max-width: 500px){ .dataviews-settings-section.dataviews-settings-section{ grid-template-columns:repeat(2, 1fr); } .dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{ grid-column:span 2; } } .dataviews-field-control__field{ height:32px; } .dataviews-field-control__actions{ position:absolute; top:-9999em; } .dataviews-field-control__actions.dataviews-field-control__actions{ gap:4px; } .dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{ position:unset; top:unset; } .dataviews-field-control__icon{ display:flex; width:24px; } .dataviews-field-control__label-sub-label-container{ flex-grow:1; } .dataviews-field-control__label{ display:block; } .dataviews-field-control__sub-label{ color:#757575; font-size:11px; font-style:normal; margin-bottom:0; margin-top:8px; } .dataviews-view-grid{ container-type:inline-size; grid-template-rows:max-content; margin-bottom:auto; padding:0 48px 24px; } @media not (prefers-reduced-motion){ .dataviews-view-grid{ transition:padding .1s ease-out; } } .dataviews-view-grid .dataviews-view-grid__card{ height:100%; justify-content:flex-start; position:relative; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{ padding:8px 0 4px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{ align-items:center; display:flex; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{ width:fit-content; } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ color:#1e1e1e; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__media{ aspect-ratio:1/1; background-color:#f0f0f0; border-radius:4px; min-height:200px; position:relative; width:100%; } .dataviews-view-grid .dataviews-view-grid__media img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-grid .dataviews-view-grid__media:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; pointer-events:none; position:absolute; top:0; width:100%; } .dataviews-view-grid .dataviews-view-grid__fields{ font-size:12px; line-height:16px; position:relative; } .dataviews-view-grid .dataviews-view-grid__fields:not(:empty){ padding:0 0 12px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){ line-height:20px; min-height:24px; padding-top:2px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{ align-items:center; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{ color:#757575; width:35%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:65%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){ display:none; } .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){ padding-bottom:12px; } @container (max-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(1, minmax(0, 1fr)); padding-left:24px; padding-right:24px; } } @container (min-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); } } @container (min-width: 780px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(3, minmax(0, 1fr)); } } @container (min-width: 1140px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(4, minmax(0, 1fr)); } } @container (min-width: 1520px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(5, minmax(0, 1fr)); } } .dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{ display:none; } .dataviews-view-grid__card .dataviews-selection-checkbox{ left:8px; position:absolute; top:-9999em; z-index:1; } .dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{ top:8px; } .dataviews-view-grid__media--clickable{ cursor:pointer; } div.dataviews-view-list{ list-style-type:none; } .dataviews-view-list{ margin:0 0 auto; } .dataviews-view-list div[role=row]{ border-top:1px solid #f0f0f0; margin:0; } .dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{ box-sizing:border-box; padding:16px 24px; position:relative; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions{ flex:0; overflow:hidden; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{ height:24px; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{ opacity:0; position:relative; z-index:1; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{ flex-basis:min-content; overflow:unset; padding-inline-end:4px; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{ opacity:1; } .dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{ color:#1e1e1e; } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{ background-color:#f8f8f8; color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#1e1e1e; } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list .dataviews-view-list__item{ appearance:none; background:none; border:none; cursor:pointer; inset:0; padding:0; position:absolute; scroll-margin:8px 0; z-index:1; } .dataviews-view-list .dataviews-view-list__item:focus-visible{ outline:none; } .dataviews-view-list .dataviews-view-list__item:focus-visible:before{ border-radius:2px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .dataviews-view-list .dataviews-view-list__title-field{ flex:1; line-height:24px; min-height:24px; overflow:hidden; } .dataviews-view-list .dataviews-view-list__title-field:has(a,button){ z-index:1; } .dataviews-view-list .dataviews-view-list__media-wrapper{ background-color:#f0f0f0; border-radius:4px; flex-shrink:0; height:52px; overflow:hidden; position:relative; width:52px; } .dataviews-view-list .dataviews-view-list__media-wrapper img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-list .dataviews-view-list__media-wrapper:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; position:absolute; top:0; width:100%; } .dataviews-view-list .dataviews-view-list__field-wrapper{ flex-grow:1; min-height:52px; } .dataviews-view-list .dataviews-view-list__fields{ color:#757575; display:flex; flex-wrap:wrap; font-size:12px; gap:12px; row-gap:4px; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{ display:none; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{ align-items:center; display:flex; line-height:20px; min-height:24px; } .dataviews-view-list+.dataviews-pagination{ justify-content:space-between; } .dataviews-view-table{ border-collapse:collapse; border-color:inherit; color:#757575; margin-bottom:auto; position:relative; text-indent:0; width:100%; } .dataviews-view-table th{ color:#1e1e1e; font-size:13px; font-weight:400; text-align:left; } .dataviews-view-table td,.dataviews-view-table th{ padding:12px; white-space:nowrap; } .dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{ text-align:right; } .dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{ padding-right:0; width:1%; } .dataviews-view-table tr{ border-top:1px solid #f0f0f0; } .dataviews-view-table tr .dataviews-view-table-header-button{ gap:4px; } .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-left:48px; } .dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{ margin-left:-8px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-right:48px; } .dataviews-view-table tr:last-child{ border-bottom:0; } .dataviews-view-table tr.is-hovered{ background-color:#f8f8f8; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{ opacity:0; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{ opacity:1; } .dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:0; } .dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } @media (hover:none){ .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } } .dataviews-view-table tr.is-selected{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#757575; } .dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-table tr.is-selected:hover{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-table thead{ inset-block-start:0; position:sticky; z-index:1; } .dataviews-view-table thead tr{ border:0; } .dataviews-view-table thead th{ background-color:#fff; font-size:11px; font-weight:500; padding-bottom:8px; padding-left:12px; padding-top:8px; text-transform:uppercase; } .dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-left:4px; } .dataviews-view-table tbody td{ vertical-align:top; } .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{ align-items:center; display:flex; min-height:32px; } .dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){ min-height:0; } .dataviews-view-table .dataviews-view-table-header-button{ font-size:11px; font-weight:500; padding:4px 8px; text-transform:uppercase; } .dataviews-view-table .dataviews-view-table-header-button:not(:hover){ color:#1e1e1e; } .dataviews-view-table .dataviews-view-table-header-button span{ speak:none; } .dataviews-view-table .dataviews-view-table-header-button span:empty{ display:none; } .dataviews-view-table .dataviews-view-table-header{ padding-left:4px; } .dataviews-view-table .dataviews-view-table__actions-column{ width:1%; } .dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{ opacity:1; } .dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-left:0; } .dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{ padding:4px 8px; } .dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{ padding:16px 12px; } .dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{ padding-right:0; } @container (max-width: 430px){ .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-left:24px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-right:24px; } } .dataviews-view-table-selection-checkbox{ --checkbox-input-size:24px; } @media (min-width:600px){ .dataviews-view-table-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-column-primary__media{ max-width:60px; } .dataviews-controls__datetime{ border:none; padding:0; } .dataforms-layouts-panel__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-panel__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-panel__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .dataforms-layouts-panel__field-control .components-button{ max-width:100%; min-height:32px; text-align:left; text-wrap:balance; text-wrap:pretty; white-space:normal; } .dataforms-layouts-panel__field-control .components-dropdown{ max-width:100%; } .dataforms-layouts-panel__field-dropdown .components-popover__content{ min-width:320px; padding:16px; } .dataforms-layouts-panel__dropdown-header{ margin-bottom:16px; } .components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{ z-index:159990; } .dataforms-layouts-regular__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-regular__field .components-base-control__label{ font-size:inherit; font-weight:400; text-transform:none; } .dataforms-layouts-regular__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-regular__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .edit-site-layout{ color:#ccc; display:flex; flex-direction:column; height:100%; } .edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{ background:#1e1e1e; } .edit-site-layout__content{ display:flex; flex-grow:1; height:100%; } .edit-site-layout__sidebar-region{ flex-shrink:0; width:100vw; z-index:1; } @media (min-width:782px){ .edit-site-layout__sidebar-region{ width:300px; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{ height:100vh; left:0; position:fixed !important; top:0; } .edit-site-layout__sidebar-region .edit-site-layout__sidebar{ display:flex; flex-direction:column; height:100%; } .edit-site-layout__sidebar-region .resizable-editor__drag-handle{ right:0; } .edit-site-layout__main{ display:flex; flex-direction:column; flex-grow:1; overflow:hidden; } .edit-site-layout__mobile{ display:flex; flex-direction:column; position:relative; width:100%; z-index:2; } .edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{ padding:0; } .edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{ padding:0 12px; } .edit-site-layout__canvas-container{ flex-grow:1; overflow:visible; position:relative; z-index:2; } .edit-site-layout__canvas-container.is-resizing:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:100; } .edit-site-layout__canvas{ align-items:center; bottom:0; display:flex; justify-content:center; left:0; position:absolute; top:0; width:100%; } .edit-site-layout__canvas.is-right-aligned{ justify-content:flex-end; } .edit-site-layout__canvas .edit-site-resizable-frame__inner{ color:#1e1e1e; } @media (min-width:782px){ .edit-site-layout__canvas{ bottom:16px; top:16px; width:calc(100% - 16px); } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; overflow:hidden; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ transition:border-radius,box-shadow .4s; } } @media (min-width:782px){ .edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ border-radius:8px; } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; } } .edit-site-layout.is-full-canvas .edit-site-layout__canvas{ bottom:0; top:0; width:100%; } .edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{ min-height:100% !important; position:relative !important; } .edit-site-template-pages-preview{ height:100%; } html.canvas-mode-edit-transition::view-transition-group(toggle){ animation-delay:255ms; } @media (prefers-reduced-motion){ ::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){ animation:none !important; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{ display:none; } .edit-site-layout__view-mode-toggle.components-button{ view-transition-name:toggle; align-items:center; background:#1e1e1e; border-radius:0; color:#fff; display:flex; height:60px; justify-content:center; overflow:hidden; padding:0; position:relative; width:60px; } .edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{ color:#fff; } .edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{ box-shadow:0 0 0 3px #1e1e1e, 0 0 0 6px var(--wp-admin-theme-color); outline:4px solid #0000; outline-offset:4px; } .edit-site-layout__view-mode-toggle.components-button:before{ border-radius:4px; bottom:9px; box-shadow:none; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } @media not (prefers-reduced-motion){ .edit-site-layout__view-mode-toggle.components-button:before{ transition:box-shadow .1s ease; } } .edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{ align-items:center; display:flex; height:60px; justify-content:center; width:60px; } .edit-site-layout__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:auto; position:fixed !important; right:0; top:-9999em; width:280px; z-index:100000; } .edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{ bottom:0; top:auto; } .edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{ top:0; } @media (min-width:782px){ .edit-site-layout__actions{ border-left:1px solid #ddd; } } .edit-site-layout__area{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; flex-grow:1; margin:0; overflow:hidden; } @media (min-width:782px){ .edit-site-layout__area{ border-radius:8px; margin:16px 16px 16px 0; } } .edit-site .components-editor-notices__snackbar{ bottom:16px; padding-left:16px; padding-right:16px; position:fixed; right:0; } .edit-site-page{ background:#fff; color:#2f2f2f; container:edit-site-page/inline-size; height:100%; } @media not (prefers-reduced-motion){ .edit-site-page{ transition:width .2s ease-out; } } .edit-site-page-header{ background:#fff; border-bottom:1px solid #f0f0f0; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-page-header{ transition:padding .1s ease-out; } } .edit-site-page-header .components-heading{ color:#1e1e1e; } .edit-site-page-header .edit-site-page-header__page-title{ min-height:40px; } .edit-site-page-header .edit-site-page-header__page-title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-page-header .edit-site-page-header__sub-title{ margin-bottom:8px; } @container (max-width: 430px){ .edit-site-page-header{ padding:16px 24px; } } .edit-site-page-content{ display:flex; flex-flow:column; height:100%; position:relative; z-index:1; } .edit-site-save-hub{ border-top:1px solid #2f2f2f; color:#949494; flex-shrink:0; margin:0; padding:16px; } .edit-site-save-hub__button{ color:inherit; justify-content:center; width:100%; } .edit-site-save-hub__button[aria-disabled=true]{ opacity:1; } .edit-site-save-hub__button[aria-disabled=true]:hover{ color:inherit; } .edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{ color:#1e1e1e; } @media (min-width:600px){ .edit-site-save-panel__modal{ width:600px; } } .edit-site-sidebar__content{ contain:content; flex-grow:1; overflow-x:hidden; overflow-y:auto; } @keyframes _fwjws_slide-from-right{ 0%{ opacity:0; transform:translateX(50px); } to{ opacity:1; transform:none; } } @keyframes _fwjws_slide-from-left{ 0%{ opacity:0; transform:translateX(-50px); } to{ opacity:1; transform:none; } } .edit-site-sidebar__screen-wrapper{ animation-duration:.14s; animation-timing-function:ease-in-out; display:flex; flex-direction:column; height:100%; max-height:100%; overflow-x:auto; padding:0 12px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:stable; scrollbar-width:thin; will-change:transform; will-change:transform, opacity; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar{ height:12px; width:12px; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{ background-color:initial; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{ background-color:#757575; } .edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{ scrollbar-color:#757575 #0000; } @media (hover:none){ .edit-site-sidebar__screen-wrapper{ scrollbar-color:#757575 #0000; } } @media (prefers-reduced-motion:reduce){ .edit-site-sidebar__screen-wrapper{ animation-duration:0s; } } .edit-site-sidebar__screen-wrapper.slide-from-left{ animation-name:_fwjws_slide-from-left; } .edit-site-sidebar__screen-wrapper.slide-from-right{ animation-name:_fwjws_slide-from-right; } .edit-site-site-hub{ align-items:center; display:flex; gap:8px; height:60px; justify-content:space-between; margin-right:12px; } .edit-site-site-hub__actions{ flex-shrink:0; } .edit-site-site-hub__view-mode-toggle-container{ flex-shrink:0; height:60px; width:60px; } .edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{ background:#0000; } .edit-site-site-hub__title .components-button{ color:#e0e0e0; display:block; flex-grow:1; font-size:15px; font-weight:500; margin-left:-4px; overflow:hidden; padding-right:16px; position:relative; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{ color:#e0e0e0; } .edit-site-site-hub__title .components-button:focus{ box-shadow:none; outline:none; } .edit-site-site-hub__title .components-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .edit-site-site-hub__title .components-button:after{ content:"↗"; font-weight:400; opacity:0; position:absolute; right:0; } @media not (prefers-reduced-motion){ .edit-site-site-hub__title .components-button:after{ transition:opacity .1s linear; } } .edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{ opacity:1; } .edit-site-site-hub_toggle-command-center{ color:#e0e0e0; } .edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{ fill:#f0f0f0; } .edit-site-site-icon__icon{ fill:currentColor; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__icon{ padding:12px; } .edit-site-site-icon__image{ aspect-ratio:1/1; background:#333; height:100%; object-fit:cover; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__image{ border-radius:0; } .edit-site-editor__view-mode-toggle button:focus{ position:relative; } .edit-site-editor__view-mode-toggle button:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff; content:""; display:block; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-site-editor-canvas-container{ background-color:#ddd; height:100%; } .edit-site-editor-canvas-container iframe{ display:block; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{ padding:24px 24px 0; } .edit-site-editor-canvas-container__section{ background:#fff; border-radius:8px; bottom:0; left:0; overflow:hidden; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .edit-site-editor-canvas-container__section{ transition:all .3s; } } .edit-site-editor-canvas-container__close-button{ background:#fff; position:absolute; right:8px; top:8px; z-index:2; } .edit-site-post-list__featured-image{ height:100%; object-fit:cover; width:100%; } .edit-site-post-list__featured-image-wrapper{ border-radius:4px; height:100%; width:100%; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){ background-color:#f0f0f0; border-radius:4px; display:block; flex-grow:0 !important; height:32px; overflow:hidden; position:relative; width:32px; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; position:absolute; top:0; width:100%; } .edit-site-post-list__featured-image-button{ background-color:unset; border:none; border-radius:4px; box-shadow:none; box-sizing:border-box; cursor:pointer; height:100%; overflow:hidden; padding:0; width:100%; } .edit-site-post-list__featured-image-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{ background:rgba(var(--wp-admin-theme-color--rgb), .04); box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .edit-site-post-list__status-icon{ height:24px; width:24px; } .edit-site-post-list__status-icon svg{ fill:currentColor; margin-left:-4px; } .edit-site-resizable-frame__inner{ position:relative; } body:has(.edit-site-resizable-frame__inner.is-resizing){ cursor:col-resize; user-select:none; -webkit-user-select:none; } .edit-site-resizable-frame__inner.is-resizing:before{ content:""; inset:0; position:absolute; z-index:1; } .edit-site-resizable-frame__inner-content{ inset:0; position:absolute; z-index:0; } .edit-site-resizable-frame__handle{ align-items:center; background-color:#75757566; border:0; border-radius:4px; cursor:col-resize; display:flex; height:64px; justify-content:flex-end; padding:0; position:absolute; top:calc(50% - 32px); width:4px; z-index:100; } .edit-site-resizable-frame__handle:before{ content:""; height:100%; left:100%; position:absolute; width:32px; } .edit-site-resizable-frame__handle:after{ content:""; height:100%; position:absolute; right:100%; width:32px; } .edit-site-resizable-frame__handle:focus-visible{ outline:2px solid #0000; } .edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{ background-color:var(--wp-admin-theme-color); } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } } #adminmenumain,#wpadminbar{ display:none; } #wpcontent{ margin-left:0; } body.js #wpbody{ padding-top:0; } body{ background:#fff; } body #wpcontent{ padding-left:0; } body #wpbody-content{ padding-bottom:0; } body #wpbody-content>div:not(#gutenberg-posts-dashboard):not(#screen-meta),body #wpfooter{ display:none; } body .a11y-speak-region{ left:-1px; top:-1px; } body ul#adminmenu a.wp-has-current-submenu:after,body ul#adminmenu>li.current>a.current:after{ border-right-color:#fff; } body .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } #gutenberg-posts-dashboard{ box-sizing:border-box; height:100vh; } #gutenberg-posts-dashboard *,#gutenberg-posts-dashboard :after,#gutenberg-posts-dashboard :before{ box-sizing:inherit; } @media (min-width:600px){ #gutenberg-posts-dashboard{ bottom:0; left:0; min-height:100vh; position:fixed; right:0; top:0; } } .no-js #gutenberg-posts-dashboard{ min-height:0; position:static; } #gutenberg-posts-dashboard .components-editor-notices__snackbar{ bottom:16px; padding-left:16px; padding-right:16px; position:fixed; right:0; }@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .dataviews-wrapper{ box-sizing:border-box; container:dataviews-wrapper/inline-size; display:flex; flex-direction:column; font-size:13px; height:100%; line-height:1.4; overflow:auto; scroll-padding-bottom:64px; } .dataviews-filters__container,.dataviews__view-actions{ box-sizing:border-box; flex-shrink:0; padding:16px 48px; position:sticky; right:0; } @media not (prefers-reduced-motion){ .dataviews-filters__container,.dataviews__view-actions{ transition:padding .1s ease-out; } } .dataviews-loading,.dataviews-no-results{ align-items:center; display:flex; flex-grow:1; justify-content:center; padding:0 48px; } @media not (prefers-reduced-motion){ .dataviews-loading,.dataviews-no-results{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-filters__container,.dataviews__view-actions{ padding:12px 24px; } .dataviews-loading,.dataviews-no-results{ padding-left:24px; padding-right:24px; } } .dataviews-title-field{ font-size:13px; font-weight:500; width:100%; } .dataviews-title-field,.dataviews-title-field a{ color:#2f2f2f; text-overflow:ellipsis; white-space:nowrap; } .dataviews-title-field a{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; } .dataviews-title-field a:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field a:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-title-field button.components-button.is-link{ color:#1e1e1e; display:block; font-weight:inherit; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; width:100%; } .dataviews-title-field button.components-button.is-link:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable{ color:#2f2f2f; cursor:pointer; } .dataviews-title-field--clickable:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-bulk-actions-footer__item-count{ color:#1e1e1e; font-size:11px; font-weight:500; text-transform:uppercase; } .dataviews-bulk-actions-footer__container{ margin-left:auto; min-height:32px; } .dataviews-filters__button{ position:relative; } .dataviews-filters__container{ padding-top:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{ opacity:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{ opacity:1; } .dataviews-filters__summary-popover{ font-size:13px; line-height:1.4; } .dataviews-filters__summary-popover .components-popover__content{ border-radius:4px; width:230px; } .dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{ padding:0; } .dataviews-filters__summary-operators-container{ padding:8px 8px 0; } .dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){ border-bottom:1px solid #e0e0e0; padding-bottom:8px; } .dataviews-filters__summary-operators-container:empty{ display:none; } .dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{ color:#757575; } .dataviews-filters__summary-chip-container{ position:relative; white-space:pre-wrap; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{ align-items:center; background:#f0f0f0; border:1px solid #0000; border-radius:16px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:flex; min-height:32px; padding:4px 12px; position:relative; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{ padding-inline-end:28px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{ background:#e0e0e0; color:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{ background:rgba(var(--wp-admin-theme-color--rgb), .04); color:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{ background:rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{ font-weight:500; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{ align-items:center; background:#0000; border:0; border-radius:50%; cursor:pointer; display:flex; height:24px; justify-content:center; left:4px; padding:0; position:absolute; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{ fill:#757575; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{ background:#e0e0e0; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{ fill:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{ fill:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__search-widget-filter-combobox-list{ border-top:1px solid #e0e0e0; max-height:184px; overflow:auto; padding:4px; } .dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{ font-weight:600; } .dataviews-filters__search-widget-listbox{ overflow:auto; padding:4px; } .dataviews-filters__search-widget-listitem{ align-items:center; border-radius:2px; box-sizing:border-box; cursor:default; display:flex; gap:8px; margin-block-end:2px; padding:8px 12px; } .dataviews-filters__search-widget-listitem:last-child{ margin-block-end:0; } .dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{ background-color:var(--wp-admin-theme-color); color:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{ fill:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{ color:#fff; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{ flex-shrink:0; height:24px; width:24px; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{ color:#757575; display:block; font-size:12px; line-height:16px; overflow:hidden; text-overflow:ellipsis; } .dataviews-filters__search-widget-filter-combobox__wrapper{ padding:8px; position:relative; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ background:#f0f0f0; border:none; border-radius:2px; box-shadow:0 0 0 #0000; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin-left:0; margin-right:0; padding:0 8px 0 32px; width:100%; } @media not (prefers-reduced-motion){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; line-height:normal; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ background:#fff; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{ color:#757575; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{ -webkit-appearance:none; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{ align-items:center; display:flex; justify-content:center; left:12px; position:absolute; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__container-visibility-toggle{ flex-shrink:0; position:relative; } .dataviews-filters-toggle__count{ background:var(--wp-admin-theme-color, #3858e9); border-radius:8px; box-sizing:border-box; color:#fff; font-size:11px; height:16px; left:0; line-height:16px; min-width:16px; outline:var(--wp-admin-border-width-focus) solid #fff; padding:0 4px; position:absolute; text-align:center; top:0; transform:translate(-50%, -50%); } .dataviews-search{ width:fit-content; } .dataviews-footer{ background-color:#fff; border-top:1px solid #f0f0f0; bottom:0; flex-shrink:0; padding:12px 48px; position:sticky; right:0; z-index:2; } @media not (prefers-reduced-motion){ .dataviews-footer{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-footer{ padding:12px 24px; } } @container (max-width: 560px){ .dataviews-footer{ flex-direction:column !important; } .dataviews-footer .dataviews-bulk-actions-footer__container{ width:100%; } .dataviews-footer .dataviews-bulk-actions-footer__item-count{ flex-grow:1; } .dataviews-footer .dataviews-pagination{ justify-content:space-between; width:100%; } } .dataviews-pagination__page-select{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .dataviews-pagination__page-select .components-select-control__input{ font-size:11px !important; font-weight:500; } } .dataviews-action-modal{ z-index:1000001; } .dataviews-selection-checkbox{ --checkbox-input-size:24px; flex-shrink:0; line-height:0; } @media (min-width:600px){ .dataviews-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-selection-checkbox .components-checkbox-control__input-container{ margin:0; } .dataviews-view-config{ container-type:inline-size; font-size:13px; line-height:1.4; width:320px; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{ height:100%; overflow-y:scroll; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{ width:auto; } .dataviews-view-config__sort-direction .components-toggle-group-control-option-base{ text-transform:uppercase; } .dataviews-settings-section__title.dataviews-settings-section__title{ font-size:15px; line-height:24px; } .dataviews-settings-section__sidebar{ grid-column:span 4; } .dataviews-settings-section__content,.dataviews-settings-section__content>*{ grid-column:span 8; } .dataviews-settings-section__content .is-divided-in-two{ display:contents; } .dataviews-settings-section__content .is-divided-in-two>*{ grid-column:span 4; } .dataviews-settings-section:has(.dataviews-settings-section__content:empty){ display:none; } @container (max-width: 500px){ .dataviews-settings-section.dataviews-settings-section{ grid-template-columns:repeat(2, 1fr); } .dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{ grid-column:span 2; } } .dataviews-field-control__field{ height:32px; } .dataviews-field-control__actions{ position:absolute; top:-9999em; } .dataviews-field-control__actions.dataviews-field-control__actions{ gap:4px; } .dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{ position:unset; top:unset; } .dataviews-field-control__icon{ display:flex; width:24px; } .dataviews-field-control__label-sub-label-container{ flex-grow:1; } .dataviews-field-control__label{ display:block; } .dataviews-field-control__sub-label{ color:#757575; font-size:11px; font-style:normal; margin-bottom:0; margin-top:8px; } .dataviews-view-grid{ container-type:inline-size; grid-template-rows:max-content; margin-bottom:auto; padding:0 48px 24px; } @media not (prefers-reduced-motion){ .dataviews-view-grid{ transition:padding .1s ease-out; } } .dataviews-view-grid .dataviews-view-grid__card{ height:100%; justify-content:flex-start; position:relative; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{ padding:8px 0 4px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{ align-items:center; display:flex; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{ width:fit-content; } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ color:#1e1e1e; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__media{ aspect-ratio:1/1; background-color:#f0f0f0; border-radius:4px; min-height:200px; position:relative; width:100%; } .dataviews-view-grid .dataviews-view-grid__media img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-grid .dataviews-view-grid__media:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; pointer-events:none; position:absolute; right:0; top:0; width:100%; } .dataviews-view-grid .dataviews-view-grid__fields{ font-size:12px; line-height:16px; position:relative; } .dataviews-view-grid .dataviews-view-grid__fields:not(:empty){ padding:0 0 12px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){ line-height:20px; min-height:24px; padding-top:2px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{ align-items:center; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{ color:#757575; width:35%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:65%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){ display:none; } .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){ padding-bottom:12px; } @container (max-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(1, minmax(0, 1fr)); padding-left:24px; padding-right:24px; } } @container (min-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); } } @container (min-width: 780px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(3, minmax(0, 1fr)); } } @container (min-width: 1140px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(4, minmax(0, 1fr)); } } @container (min-width: 1520px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(5, minmax(0, 1fr)); } } .dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{ display:none; } .dataviews-view-grid__card .dataviews-selection-checkbox{ position:absolute; right:8px; top:-9999em; z-index:1; } .dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{ top:8px; } .dataviews-view-grid__media--clickable{ cursor:pointer; } div.dataviews-view-list{ list-style-type:none; } .dataviews-view-list{ margin:0 0 auto; } .dataviews-view-list div[role=row]{ border-top:1px solid #f0f0f0; margin:0; } .dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{ box-sizing:border-box; padding:16px 24px; position:relative; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions{ flex:0; overflow:hidden; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{ height:24px; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{ opacity:0; position:relative; z-index:1; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{ flex-basis:min-content; overflow:unset; padding-inline-end:4px; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{ opacity:1; } .dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{ color:#1e1e1e; } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{ background-color:#f8f8f8; color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#1e1e1e; } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list .dataviews-view-list__item{ appearance:none; background:none; border:none; cursor:pointer; inset:0; padding:0; position:absolute; scroll-margin:8px 0; z-index:1; } .dataviews-view-list .dataviews-view-list__item:focus-visible{ outline:none; } .dataviews-view-list .dataviews-view-list__item:focus-visible:before{ border-radius:2px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .dataviews-view-list .dataviews-view-list__title-field{ flex:1; line-height:24px; min-height:24px; overflow:hidden; } .dataviews-view-list .dataviews-view-list__title-field:has(a,button){ z-index:1; } .dataviews-view-list .dataviews-view-list__media-wrapper{ background-color:#f0f0f0; border-radius:4px; flex-shrink:0; height:52px; overflow:hidden; position:relative; width:52px; } .dataviews-view-list .dataviews-view-list__media-wrapper img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-list .dataviews-view-list__media-wrapper:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; position:absolute; right:0; top:0; width:100%; } .dataviews-view-list .dataviews-view-list__field-wrapper{ flex-grow:1; min-height:52px; } .dataviews-view-list .dataviews-view-list__fields{ color:#757575; display:flex; flex-wrap:wrap; font-size:12px; gap:12px; row-gap:4px; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{ display:none; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{ align-items:center; display:flex; line-height:20px; min-height:24px; } .dataviews-view-list+.dataviews-pagination{ justify-content:space-between; } .dataviews-view-table{ border-collapse:collapse; border-color:inherit; color:#757575; margin-bottom:auto; position:relative; text-indent:0; width:100%; } .dataviews-view-table th{ color:#1e1e1e; font-size:13px; font-weight:400; text-align:right; } .dataviews-view-table td,.dataviews-view-table th{ padding:12px; white-space:nowrap; } .dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{ text-align:left; } .dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{ padding-left:0; width:1%; } .dataviews-view-table tr{ border-top:1px solid #f0f0f0; } .dataviews-view-table tr .dataviews-view-table-header-button{ gap:4px; } .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-right:48px; } .dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{ margin-right:-8px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-left:48px; } .dataviews-view-table tr:last-child{ border-bottom:0; } .dataviews-view-table tr.is-hovered{ background-color:#f8f8f8; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{ opacity:0; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{ opacity:1; } .dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:0; } .dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } @media (hover:none){ .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } } .dataviews-view-table tr.is-selected{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#757575; } .dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-table tr.is-selected:hover{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-table thead{ inset-block-start:0; position:sticky; z-index:1; } .dataviews-view-table thead tr{ border:0; } .dataviews-view-table thead th{ background-color:#fff; font-size:11px; font-weight:500; padding-bottom:8px; padding-right:12px; padding-top:8px; text-transform:uppercase; } .dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-right:4px; } .dataviews-view-table tbody td{ vertical-align:top; } .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{ align-items:center; display:flex; min-height:32px; } .dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){ min-height:0; } .dataviews-view-table .dataviews-view-table-header-button{ font-size:11px; font-weight:500; padding:4px 8px; text-transform:uppercase; } .dataviews-view-table .dataviews-view-table-header-button:not(:hover){ color:#1e1e1e; } .dataviews-view-table .dataviews-view-table-header-button span{ speak:none; } .dataviews-view-table .dataviews-view-table-header-button span:empty{ display:none; } .dataviews-view-table .dataviews-view-table-header{ padding-right:4px; } .dataviews-view-table .dataviews-view-table__actions-column{ width:1%; } .dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{ opacity:1; } .dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-right:0; } .dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{ padding:4px 8px; } .dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{ padding:16px 12px; } .dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{ padding-left:0; } @container (max-width: 430px){ .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-right:24px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-left:24px; } } .dataviews-view-table-selection-checkbox{ --checkbox-input-size:24px; } @media (min-width:600px){ .dataviews-view-table-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-column-primary__media{ max-width:60px; } .dataviews-controls__datetime{ border:none; padding:0; } .dataforms-layouts-panel__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-panel__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-panel__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .dataforms-layouts-panel__field-control .components-button{ max-width:100%; min-height:32px; text-align:right; text-wrap:balance; text-wrap:pretty; white-space:normal; } .dataforms-layouts-panel__field-control .components-dropdown{ max-width:100%; } .dataforms-layouts-panel__field-dropdown .components-popover__content{ min-width:320px; padding:16px; } .dataforms-layouts-panel__dropdown-header{ margin-bottom:16px; } .components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{ z-index:159990; } .dataforms-layouts-regular__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-regular__field .components-base-control__label{ font-size:inherit; font-weight:400; text-transform:none; } .dataforms-layouts-regular__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-regular__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .edit-site-layout{ color:#ccc; display:flex; flex-direction:column; height:100%; } .edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{ background:#1e1e1e; } .edit-site-layout__content{ display:flex; flex-grow:1; height:100%; } .edit-site-layout__sidebar-region{ flex-shrink:0; width:100vw; z-index:1; } @media (min-width:782px){ .edit-site-layout__sidebar-region{ width:300px; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{ height:100vh; position:fixed !important; right:0; top:0; } .edit-site-layout__sidebar-region .edit-site-layout__sidebar{ display:flex; flex-direction:column; height:100%; } .edit-site-layout__sidebar-region .resizable-editor__drag-handle{ left:0; } .edit-site-layout__main{ display:flex; flex-direction:column; flex-grow:1; overflow:hidden; } .edit-site-layout__mobile{ display:flex; flex-direction:column; position:relative; width:100%; z-index:2; } .edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{ padding:0; } .edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{ padding:0 12px; } .edit-site-layout__canvas-container{ flex-grow:1; overflow:visible; position:relative; z-index:2; } .edit-site-layout__canvas-container.is-resizing:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:100; } .edit-site-layout__canvas{ align-items:center; bottom:0; display:flex; justify-content:center; position:absolute; right:0; top:0; width:100%; } .edit-site-layout__canvas.is-right-aligned{ justify-content:flex-end; } .edit-site-layout__canvas .edit-site-resizable-frame__inner{ color:#1e1e1e; } @media (min-width:782px){ .edit-site-layout__canvas{ bottom:16px; top:16px; width:calc(100% - 16px); } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; overflow:hidden; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ transition:border-radius,box-shadow .4s; } } @media (min-width:782px){ .edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ border-radius:8px; } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; } } .edit-site-layout.is-full-canvas .edit-site-layout__canvas{ bottom:0; top:0; width:100%; } .edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{ min-height:100% !important; position:relative !important; } .edit-site-template-pages-preview{ height:100%; } html.canvas-mode-edit-transition::view-transition-group(toggle){ animation-delay:255ms; } @media (prefers-reduced-motion){ ::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){ animation:none !important; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{ display:none; } .edit-site-layout__view-mode-toggle.components-button{ view-transition-name:toggle; align-items:center; background:#1e1e1e; border-radius:0; color:#fff; display:flex; height:60px; justify-content:center; overflow:hidden; padding:0; position:relative; width:60px; } .edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{ color:#fff; } .edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{ box-shadow:0 0 0 3px #1e1e1e, 0 0 0 6px var(--wp-admin-theme-color); outline:4px solid #0000; outline-offset:4px; } .edit-site-layout__view-mode-toggle.components-button:before{ border-radius:4px; bottom:9px; box-shadow:none; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } @media not (prefers-reduced-motion){ .edit-site-layout__view-mode-toggle.components-button:before{ transition:box-shadow .1s ease; } } .edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{ align-items:center; display:flex; height:60px; justify-content:center; width:60px; } .edit-site-layout__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:0; position:fixed !important; right:auto; top:-9999em; width:280px; z-index:100000; } .edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{ bottom:0; top:auto; } .edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{ top:0; } @media (min-width:782px){ .edit-site-layout__actions{ border-right:1px solid #ddd; } } .edit-site-layout__area{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; flex-grow:1; margin:0; overflow:hidden; } @media (min-width:782px){ .edit-site-layout__area{ border-radius:8px; margin:16px 0 16px 16px; } } .edit-site .components-editor-notices__snackbar{ bottom:16px; left:0; padding-left:16px; padding-right:16px; position:fixed; } .edit-site-page{ background:#fff; color:#2f2f2f; container:edit-site-page/inline-size; height:100%; } @media not (prefers-reduced-motion){ .edit-site-page{ transition:width .2s ease-out; } } .edit-site-page-header{ background:#fff; border-bottom:1px solid #f0f0f0; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-page-header{ transition:padding .1s ease-out; } } .edit-site-page-header .components-heading{ color:#1e1e1e; } .edit-site-page-header .edit-site-page-header__page-title{ min-height:40px; } .edit-site-page-header .edit-site-page-header__page-title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-page-header .edit-site-page-header__sub-title{ margin-bottom:8px; } @container (max-width: 430px){ .edit-site-page-header{ padding:16px 24px; } } .edit-site-page-content{ display:flex; flex-flow:column; height:100%; position:relative; z-index:1; } .edit-site-save-hub{ border-top:1px solid #2f2f2f; color:#949494; flex-shrink:0; margin:0; padding:16px; } .edit-site-save-hub__button{ color:inherit; justify-content:center; width:100%; } .edit-site-save-hub__button[aria-disabled=true]{ opacity:1; } .edit-site-save-hub__button[aria-disabled=true]:hover{ color:inherit; } .edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{ color:#1e1e1e; } @media (min-width:600px){ .edit-site-save-panel__modal{ width:600px; } } .edit-site-sidebar__content{ contain:content; flex-grow:1; overflow-x:hidden; overflow-y:auto; } @keyframes _fwjws_slide-from-right{ 0%{ opacity:0; transform:translateX(-50px); } to{ opacity:1; transform:none; } } @keyframes _fwjws_slide-from-left{ 0%{ opacity:0; transform:translateX(50px); } to{ opacity:1; transform:none; } } .edit-site-sidebar__screen-wrapper{ animation-duration:.14s; animation-timing-function:ease-in-out; display:flex; flex-direction:column; height:100%; max-height:100%; overflow-x:auto; padding:0 12px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:stable; scrollbar-width:thin; will-change:transform; will-change:transform, opacity; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar{ height:12px; width:12px; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{ background-color:initial; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{ background-color:#757575; } .edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{ scrollbar-color:#757575 #0000; } @media (hover:none){ .edit-site-sidebar__screen-wrapper{ scrollbar-color:#757575 #0000; } } @media (prefers-reduced-motion:reduce){ .edit-site-sidebar__screen-wrapper{ animation-duration:0s; } } .edit-site-sidebar__screen-wrapper.slide-from-left{ animation-name:_fwjws_slide-from-left; } .edit-site-sidebar__screen-wrapper.slide-from-right{ animation-name:_fwjws_slide-from-right; } .edit-site-site-hub{ align-items:center; display:flex; gap:8px; height:60px; justify-content:space-between; margin-left:12px; } .edit-site-site-hub__actions{ flex-shrink:0; } .edit-site-site-hub__view-mode-toggle-container{ flex-shrink:0; height:60px; width:60px; } .edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{ background:#0000; } .edit-site-site-hub__title .components-button{ color:#e0e0e0; display:block; flex-grow:1; font-size:15px; font-weight:500; margin-right:-4px; overflow:hidden; padding-left:16px; position:relative; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{ color:#e0e0e0; } .edit-site-site-hub__title .components-button:focus{ box-shadow:none; outline:none; } .edit-site-site-hub__title .components-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .edit-site-site-hub__title .components-button:after{ content:"↗"; font-weight:400; left:0; opacity:0; position:absolute; } @media not (prefers-reduced-motion){ .edit-site-site-hub__title .components-button:after{ transition:opacity .1s linear; } } .edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{ opacity:1; } .edit-site-site-hub_toggle-command-center{ color:#e0e0e0; } .edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{ fill:#f0f0f0; } .edit-site-site-icon__icon{ fill:currentColor; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__icon{ padding:12px; } .edit-site-site-icon__image{ aspect-ratio:1/1; background:#333; height:100%; object-fit:cover; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__image{ border-radius:0; } .edit-site-editor__view-mode-toggle button:focus{ position:relative; } .edit-site-editor__view-mode-toggle button:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff; content:""; display:block; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-site-editor-canvas-container{ background-color:#ddd; height:100%; } .edit-site-editor-canvas-container iframe{ display:block; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{ padding:24px 24px 0; } .edit-site-editor-canvas-container__section{ background:#fff; border-radius:8px; bottom:0; left:0; overflow:hidden; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .edit-site-editor-canvas-container__section{ transition:all .3s; } } .edit-site-editor-canvas-container__close-button{ background:#fff; left:8px; position:absolute; top:8px; z-index:2; } .edit-site-post-list__featured-image{ height:100%; object-fit:cover; width:100%; } .edit-site-post-list__featured-image-wrapper{ border-radius:4px; height:100%; width:100%; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){ background-color:#f0f0f0; border-radius:4px; display:block; flex-grow:0 !important; height:32px; overflow:hidden; position:relative; width:32px; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; position:absolute; right:0; top:0; width:100%; } .edit-site-post-list__featured-image-button{ background-color:unset; border:none; border-radius:4px; box-shadow:none; box-sizing:border-box; cursor:pointer; height:100%; overflow:hidden; padding:0; width:100%; } .edit-site-post-list__featured-image-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{ background:rgba(var(--wp-admin-theme-color--rgb), .04); box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .edit-site-post-list__status-icon{ height:24px; width:24px; } .edit-site-post-list__status-icon svg{ fill:currentColor; margin-right:-4px; } .edit-site-resizable-frame__inner{ position:relative; } body:has(.edit-site-resizable-frame__inner.is-resizing){ cursor:col-resize; user-select:none; -webkit-user-select:none; } .edit-site-resizable-frame__inner.is-resizing:before{ content:""; inset:0; position:absolute; z-index:1; } .edit-site-resizable-frame__inner-content{ inset:0; position:absolute; z-index:0; } .edit-site-resizable-frame__handle{ align-items:center; background-color:#75757566; border:0; border-radius:4px; cursor:col-resize; display:flex; height:64px; justify-content:flex-end; padding:0; position:absolute; top:calc(50% - 32px); width:4px; z-index:100; } .edit-site-resizable-frame__handle:before{ content:""; height:100%; position:absolute; right:100%; width:32px; } .edit-site-resizable-frame__handle:after{ content:""; height:100%; left:100%; position:absolute; width:32px; } .edit-site-resizable-frame__handle:focus-visible{ outline:2px solid #0000; } .edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{ background-color:var(--wp-admin-theme-color); } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } } #adminmenumain,#wpadminbar{ display:none; } #wpcontent{ margin-right:0; } body.js #wpbody{ padding-top:0; } body{ background:#fff; } body #wpcontent{ padding-right:0; } body #wpbody-content{ padding-bottom:0; } body #wpbody-content>div:not(#gutenberg-posts-dashboard):not(#screen-meta),body #wpfooter{ display:none; } body .a11y-speak-region{ right:-1px; top:-1px; } body ul#adminmenu a.wp-has-current-submenu:after,body ul#adminmenu>li.current>a.current:after{ border-left-color:#fff; } body .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } #gutenberg-posts-dashboard{ box-sizing:border-box; height:100vh; } #gutenberg-posts-dashboard *,#gutenberg-posts-dashboard :after,#gutenberg-posts-dashboard :before{ box-sizing:inherit; } @media (min-width:600px){ #gutenberg-posts-dashboard{ bottom:0; left:0; min-height:100vh; position:fixed; right:0; top:0; } } .no-js #gutenberg-posts-dashboard{ min-height:0; position:static; } #gutenberg-posts-dashboard .components-editor-notices__snackbar{ bottom:16px; left:0; padding-left:16px; padding-right:16px; position:fixed; }@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.dataviews-wrapper{box-sizing:border-box;container:dataviews-wrapper/inline-size;display:flex;flex-direction:column;font-size:13px;height:100%;line-height:1.4;overflow:auto;scroll-padding-bottom:64px}.dataviews-filters__container,.dataviews__view-actions{box-sizing:border-box;flex-shrink:0;padding:16px 48px;position:sticky;right:0}@media not (prefers-reduced-motion){.dataviews-filters__container,.dataviews__view-actions{transition:padding .1s ease-out}}.dataviews-loading,.dataviews-no-results{align-items:center;display:flex;flex-grow:1;justify-content:center;padding:0 48px}@media not (prefers-reduced-motion){.dataviews-loading,.dataviews-no-results{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-filters__container,.dataviews__view-actions{padding:12px 24px}.dataviews-loading,.dataviews-no-results{padding-left:24px;padding-right:24px}}.dataviews-title-field{font-size:13px;font-weight:500;width:100%}.dataviews-title-field,.dataviews-title-field a{color:#2f2f2f;text-overflow:ellipsis;white-space:nowrap}.dataviews-title-field a{display:block;flex-grow:0;overflow:hidden;text-decoration:none}.dataviews-title-field a:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field a:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-title-field button.components-button.is-link{color:#1e1e1e;display:block;font-weight:inherit;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.dataviews-title-field button.components-button.is-link:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable{color:#2f2f2f;cursor:pointer}.dataviews-title-field--clickable:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-bulk-actions-footer__item-count{color:#1e1e1e;font-size:11px;font-weight:500;text-transform:uppercase}.dataviews-bulk-actions-footer__container{margin-left:auto;min-height:32px}.dataviews-filters__button{position:relative}.dataviews-filters__container{padding-top:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{opacity:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{opacity:1}.dataviews-filters__summary-popover{font-size:13px;line-height:1.4}.dataviews-filters__summary-popover .components-popover__content{border-radius:4px;width:230px}.dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{padding:0}.dataviews-filters__summary-operators-container{padding:8px 8px 0}.dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){border-bottom:1px solid #e0e0e0;padding-bottom:8px}.dataviews-filters__summary-operators-container:empty{display:none}.dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{color:#757575}.dataviews-filters__summary-chip-container{position:relative;white-space:pre-wrap}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{align-items:center;background:#f0f0f0;border:1px solid #0000;border-radius:16px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;min-height:32px;padding:4px 12px;position:relative}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{padding-inline-end:28px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{background:#e0e0e0;color:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{background:rgba(var(--wp-admin-theme-color--rgb),.04);color:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{background:rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{font-weight:500}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{align-items:center;background:#0000;border:0;border-radius:50%;cursor:pointer;display:flex;height:24px;justify-content:center;left:4px;padding:0;position:absolute;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{fill:#757575}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{background:#e0e0e0}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{fill:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{fill:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{background:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__search-widget-filter-combobox-list{border-top:1px solid #e0e0e0;max-height:184px;overflow:auto;padding:4px}.dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{font-weight:600}.dataviews-filters__search-widget-listbox{overflow:auto;padding:4px}.dataviews-filters__search-widget-listitem{align-items:center;border-radius:2px;box-sizing:border-box;cursor:default;display:flex;gap:8px;margin-block-end:2px;padding:8px 12px}.dataviews-filters__search-widget-listitem:last-child{margin-block-end:0}.dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{background-color:var(--wp-admin-theme-color);color:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{fill:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{color:#fff}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{flex-shrink:0;height:24px;width:24px}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{color:#757575;display:block;font-size:12px;line-height:16px;overflow:hidden;text-overflow:ellipsis}.dataviews-filters__search-widget-filter-combobox__wrapper{padding:8px;position:relative}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{background:#f0f0f0;border:none;border-radius:2px;box-shadow:0 0 0 #0000;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin-left:0;margin-right:0;padding:0 8px 0 32px;width:100%}@media not (prefers-reduced-motion){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{transition:box-shadow .1s linear}}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px;line-height:normal}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{background:#fff;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{color:#757575}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{-webkit-appearance:none}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{align-items:center;display:flex;justify-content:center;left:12px;position:absolute;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__container-visibility-toggle{flex-shrink:0;position:relative}.dataviews-filters-toggle__count{background:var(--wp-admin-theme-color,#3858e9);border-radius:8px;box-sizing:border-box;color:#fff;font-size:11px;height:16px;left:0;line-height:16px;min-width:16px;outline:var(--wp-admin-border-width-focus) solid #fff;padding:0 4px;position:absolute;text-align:center;top:0;transform:translate(-50%,-50%)}.dataviews-search{width:fit-content}.dataviews-footer{background-color:#fff;border-top:1px solid #f0f0f0;bottom:0;flex-shrink:0;padding:12px 48px;position:sticky;right:0;z-index:2}@media not (prefers-reduced-motion){.dataviews-footer{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-footer{padding:12px 24px}}@container (max-width: 560px){.dataviews-footer{flex-direction:column!important}.dataviews-footer .dataviews-bulk-actions-footer__container{width:100%}.dataviews-footer .dataviews-bulk-actions-footer__item-count{flex-grow:1}.dataviews-footer .dataviews-pagination{justify-content:space-between;width:100%}}.dataviews-pagination__page-select{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.dataviews-pagination__page-select .components-select-control__input{font-size:11px!important;font-weight:500}}.dataviews-action-modal{z-index:1000001}.dataviews-selection-checkbox{--checkbox-input-size:24px;flex-shrink:0;line-height:0}@media (min-width:600px){.dataviews-selection-checkbox{--checkbox-input-size:16px}}.dataviews-selection-checkbox .components-checkbox-control__input-container{margin:0}.dataviews-view-config{container-type:inline-size;font-size:13px;line-height:1.4;width:320px}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{height:100%;overflow-y:scroll}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{width:auto}.dataviews-view-config__sort-direction .components-toggle-group-control-option-base{text-transform:uppercase}.dataviews-settings-section__title.dataviews-settings-section__title{font-size:15px;line-height:24px}.dataviews-settings-section__sidebar{grid-column:span 4}.dataviews-settings-section__content,.dataviews-settings-section__content>*{grid-column:span 8}.dataviews-settings-section__content .is-divided-in-two{display:contents}.dataviews-settings-section__content .is-divided-in-two>*{grid-column:span 4}.dataviews-settings-section:has(.dataviews-settings-section__content:empty){display:none}@container (max-width: 500px){.dataviews-settings-section.dataviews-settings-section{grid-template-columns:repeat(2,1fr)}.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{grid-column:span 2}}.dataviews-field-control__field{height:32px}.dataviews-field-control__actions{position:absolute;top:-9999em}.dataviews-field-control__actions.dataviews-field-control__actions{gap:4px}.dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{position:unset;top:unset}.dataviews-field-control__icon{display:flex;width:24px}.dataviews-field-control__label-sub-label-container{flex-grow:1}.dataviews-field-control__label{display:block}.dataviews-field-control__sub-label{color:#757575;font-size:11px;font-style:normal;margin-bottom:0;margin-top:8px}.dataviews-view-grid{container-type:inline-size;grid-template-rows:max-content;margin-bottom:auto;padding:0 48px 24px}@media not (prefers-reduced-motion){.dataviews-view-grid{transition:padding .1s ease-out}}.dataviews-view-grid .dataviews-view-grid__card{height:100%;justify-content:flex-start;position:relative}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{padding:8px 0 4px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{align-items:center;display:flex;min-height:24px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{width:fit-content}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{color:#1e1e1e}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__media{aspect-ratio:1/1;background-color:#f0f0f0;border-radius:4px;min-height:200px;position:relative;width:100%}.dataviews-view-grid .dataviews-view-grid__media img{height:100%;object-fit:cover;width:100%}.dataviews-view-grid .dataviews-view-grid__media:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;pointer-events:none;position:absolute;right:0;top:0;width:100%}.dataviews-view-grid .dataviews-view-grid__fields{font-size:12px;line-height:16px;position:relative}.dataviews-view-grid .dataviews-view-grid__fields:not(:empty){padding:0 0 12px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){line-height:20px;min-height:24px;padding-top:2px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{align-items:center;min-height:24px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{color:#757575;width:35%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:65%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){display:none}.dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){padding-bottom:12px}@container (max-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(1,minmax(0,1fr));padding-left:24px;padding-right:24px}}@container (min-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (min-width: 780px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 1140px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@container (min-width: 1520px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{display:none}.dataviews-view-grid__card .dataviews-selection-checkbox{position:absolute;right:8px;top:-9999em;z-index:1}.dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{top:8px}.dataviews-view-grid__media--clickable{cursor:pointer}div.dataviews-view-list{list-style-type:none}.dataviews-view-list{margin:0 0 auto}.dataviews-view-list div[role=row]{border-top:1px solid #f0f0f0;margin:0}.dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{box-sizing:border-box;padding:16px 24px;position:relative}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions{flex:0;overflow:hidden}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{height:24px}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{opacity:0;position:relative;z-index:1}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{flex-basis:min-content;overflow:unset;padding-inline-end:4px}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{opacity:1}.dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{color:#1e1e1e}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{background-color:#f8f8f8;color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#1e1e1e}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list .dataviews-view-list__item{appearance:none;background:none;border:none;cursor:pointer;inset:0;padding:0;position:absolute;scroll-margin:8px 0;z-index:1}.dataviews-view-list .dataviews-view-list__item:focus-visible{outline:none}.dataviews-view-list .dataviews-view-list__item:focus-visible:before{border-radius:2px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.dataviews-view-list .dataviews-view-list__title-field{flex:1;line-height:24px;min-height:24px;overflow:hidden}.dataviews-view-list .dataviews-view-list__title-field:has(a,button){z-index:1}.dataviews-view-list .dataviews-view-list__media-wrapper{background-color:#f0f0f0;border-radius:4px;flex-shrink:0;height:52px;overflow:hidden;position:relative;width:52px}.dataviews-view-list .dataviews-view-list__media-wrapper img{height:100%;object-fit:cover;width:100%}.dataviews-view-list .dataviews-view-list__media-wrapper:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;position:absolute;right:0;top:0;width:100%}.dataviews-view-list .dataviews-view-list__field-wrapper{flex-grow:1;min-height:52px}.dataviews-view-list .dataviews-view-list__fields{color:#757575;display:flex;flex-wrap:wrap;font-size:12px;gap:12px;row-gap:4px}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{display:none}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{align-items:center;display:flex;line-height:20px;min-height:24px}.dataviews-view-list+.dataviews-pagination{justify-content:space-between}.dataviews-view-table{border-collapse:collapse;border-color:inherit;color:#757575;margin-bottom:auto;position:relative;text-indent:0;width:100%}.dataviews-view-table th{color:#1e1e1e;font-size:13px;font-weight:400;text-align:right}.dataviews-view-table td,.dataviews-view-table th{padding:12px;white-space:nowrap}.dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{text-align:left}.dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{padding-left:0;width:1%}.dataviews-view-table tr{border-top:1px solid #f0f0f0}.dataviews-view-table tr .dataviews-view-table-header-button{gap:4px}.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-right:48px}.dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{margin-right:-8px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-left:48px}.dataviews-view-table tr:last-child{border-bottom:0}.dataviews-view-table tr.is-hovered{background-color:#f8f8f8}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{opacity:0}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{opacity:1}.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:0}.dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}@media (hover:none){.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}}.dataviews-view-table tr.is-selected{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#757575}.dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-table tr.is-selected:hover{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-table thead{inset-block-start:0;position:sticky;z-index:1}.dataviews-view-table thead tr{border:0}.dataviews-view-table thead th{background-color:#fff;font-size:11px;font-weight:500;padding-bottom:8px;padding-right:12px;padding-top:8px;text-transform:uppercase}.dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-right:4px}.dataviews-view-table tbody td{vertical-align:top}.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{align-items:center;display:flex;min-height:32px}.dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){min-height:0}.dataviews-view-table .dataviews-view-table-header-button{font-size:11px;font-weight:500;padding:4px 8px;text-transform:uppercase}.dataviews-view-table .dataviews-view-table-header-button:not(:hover){color:#1e1e1e}.dataviews-view-table .dataviews-view-table-header-button span{speak:none}.dataviews-view-table .dataviews-view-table-header-button span:empty{display:none}.dataviews-view-table .dataviews-view-table-header{padding-right:4px}.dataviews-view-table .dataviews-view-table__actions-column{width:1%}.dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{opacity:1}.dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-right:0}.dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{padding:4px 8px}.dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{padding:16px 12px}.dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{padding-left:0}@container (max-width: 430px){.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-right:24px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-left:24px}}.dataviews-view-table-selection-checkbox{--checkbox-input-size:24px}@media (min-width:600px){.dataviews-view-table-selection-checkbox{--checkbox-input-size:16px}}.dataviews-column-primary__media{max-width:60px}.dataviews-controls__datetime{border:none;padding:0}.dataforms-layouts-panel__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-panel__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-panel__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.dataforms-layouts-panel__field-control .components-button{max-width:100%;min-height:32px;text-align:right;text-wrap:balance;text-wrap:pretty;white-space:normal}.dataforms-layouts-panel__field-control .components-dropdown{max-width:100%}.dataforms-layouts-panel__field-dropdown .components-popover__content{min-width:320px;padding:16px}.dataforms-layouts-panel__dropdown-header{margin-bottom:16px}.components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{z-index:159990}.dataforms-layouts-regular__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-regular__field .components-base-control__label{font-size:inherit;font-weight:400;text-transform:none}.dataforms-layouts-regular__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-regular__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.fields-create-template-part-modal{z-index:1000001}.fields-create-template-part-modal__area-radio-group{border:1px solid #949494;border-radius:2px}.fields-create-template-part-modal__area-radio-wrapper{align-items:center;display:grid;grid-template-columns:min-content 1fr min-content;padding:12px;position:relative;grid-gap:4px 8px;color:#1e1e1e}.fields-create-template-part-modal__area-radio-wrapper+.fields-create-template-part-modal__area-radio-wrapper{border-top:1px solid #949494}.fields-create-template-part-modal__area-radio-wrapper input[type=radio]{opacity:0;position:absolute}.fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:checked){z-index:1}.fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:not(:checked)):hover{color:var(--wp-admin-theme-color)}.fields-create-template-part-modal__area-radio-wrapper>:not(.fields-create-template-part-modal__area-radio-label){pointer-events:none}.fields-create-template-part-modal__area-radio-label:before{content:"";inset:0;position:absolute}input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-label:before{cursor:pointer}input[type=radio]:focus-visible~.fields-create-template-part-modal__area-radio-label:before{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:4px solid #0000}.fields-create-template-part-modal__area-radio-checkmark,.fields-create-template-part-modal__area-radio-icon{fill:currentColor}input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-checkmark{opacity:0}.fields-create-template-part-modal__area-radio-description{color:#757575;font-size:12px;grid-column:2/3;line-height:normal;margin:0;text-wrap:pretty}input[type=radio]:not(:checked):hover~.fields-create-template-part-modal__area-radio-description{color:inherit}.fields-controls__slug .fields-controls__slug-external-icon{margin-right:5ch}.fields-controls__slug .fields-controls__slug-input input.components-input-control__input{padding-inline-start:0!important}.fields-controls__slug .fields-controls__slug-help-link{word-break:break-word}.fields-controls__slug .fields-controls__slug-help{display:flex;flex-direction:column}.fields-controls__slug .fields-controls__slug-help .fields-controls__slug-help-slug{font-weight:600}.fields-controls__featured-image-placeholder{background:#fff linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);border-radius:2px;box-shadow:inset 0 0 0 1px #0003;display:inline-block;padding:0}.fields-controls__featured-image-title{color:#1e1e1e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.fields-controls__featured-image-image{align-self:center;border-radius:2px;height:100%;width:100%}.fields-controls__featured-image-container .fields-controls__featured-image-placeholder{margin:0}.fields-controls__featured-image-container span{margin-left:auto}fieldset.fields-controls__featured-image .fields-controls__featured-image-container{border:1px solid #ddd;border-radius:2px;cursor:pointer;padding:8px 12px}fieldset.fields-controls__featured-image .fields-controls__featured-image-container:hover{background-color:#f0f0f0}fieldset.fields-controls__featured-image .fields-controls__featured-image-placeholder{height:24px;width:24px}fieldset.fields-controls__featured-image span{align-self:center;text-align:start;white-space:nowrap}fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button{height:fit-content;padding:0}fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:focus,fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:hover{border:0;color:unset}fieldset.fields-controls__featured-image .fields-controls__featured-image-remove-button{place-self:end}.dataforms-layouts-panel__field-control .fields-controls__featured-image-image,.dataforms-layouts-panel__field-control .fields-controls__featured-image-placeholder{height:16px;width:16px}.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-image,.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-placeholder{display:block;height:32px;width:32px}.fields-controls__template-modal{z-index:1000001}.fields-controls__template-content .block-editor-block-patterns-list{column-count:2;column-gap:24px;padding-top:2px}@media (min-width:782px){.fields-controls__template-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.fields-controls__template-content .block-editor-block-patterns-list{column-count:4}}.fields-controls__template-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.fields-field__title span:first-child{display:block;flex-grow:0;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fields-field__pattern-title span:first-child{flex:1}.edit-site-custom-template-modal__contents-wrapper{height:100%;justify-content:flex-start!important}.edit-site-custom-template-modal__contents-wrapper>*{width:100%}.edit-site-custom-template-modal__contents-wrapper__suggestions_list{margin-left:-12px;margin-right:-12px;width:calc(100% + 24px)}.edit-site-custom-template-modal__contents>.components-button{height:auto;justify-content:center}@media (min-width:782px){.edit-site-custom-template-modal{width:456px}}@media (min-width:600px){.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list{max-height:224px;overflow-y:auto}}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item{display:block;height:auto;overflow-wrap:break-word;padding:8px 12px;text-align:right;white-space:pre-wrap;width:100%}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item mark{background:none;font-weight:700}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover *,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover mark{color:var(--wp-admin-theme-color)}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus{background-color:#f0f0f0}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color) inset}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__title{display:block;overflow:hidden;text-overflow:ellipsis}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info{color:#757575;word-break:break-all}.edit-site-custom-template-modal__no-results{border:1px solid #ccc;border-radius:2px;padding:16px}.edit-site-custom-generic-template__modal .components-modal__header{border-bottom:none}.edit-site-custom-generic-template__modal .components-modal__content:before{margin-bottom:4px}@media (min-width:960px){.edit-site-add-new-template__modal{margin-top:64px;max-height:calc(100% - 128px);max-width:832px;width:calc(100% - 128px)}}.edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button svg,.edit-site-add-new-template__modal .edit-site-add-new-template__template-button svg{fill:var(--wp-admin-theme-color)}.edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button .edit-site-add-new-template__template-name{align-items:flex-start;flex-grow:1}.edit-site-add-new-template__modal .edit-site-add-new-template__template-icon{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:100%;max-height:40px;max-width:40px;padding:8px}.edit-site-add-new-template__template-list__contents>.components-button,.edit-site-custom-template-modal__contents>.components-button{border:1px solid #ddd;display:flex;flex-direction:column;justify-content:center;outline:1px solid #0000;padding:32px}.edit-site-add-new-template__template-list__contents>.components-button span:first-child,.edit-site-custom-template-modal__contents>.components-button span:first-child{color:#1e1e1e}.edit-site-add-new-template__template-list__contents>.components-button span,.edit-site-custom-template-modal__contents>.components-button span{color:#757575}.edit-site-add-new-template__template-list__contents>.components-button:hover,.edit-site-custom-template-modal__contents>.components-button:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-color:#0000;color:var(--wp-admin-theme-color-darker-10)}.edit-site-add-new-template__template-list__contents>.components-button:hover span,.edit-site-custom-template-modal__contents>.components-button:hover span{color:var(--wp-admin-theme-color)}.edit-site-add-new-template__template-list__contents>.components-button:focus,.edit-site-custom-template-modal__contents>.components-button:focus{border-color:#0000;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:3px solid #0000}.edit-site-add-new-template__template-list__contents>.components-button:focus span:first-child,.edit-site-custom-template-modal__contents>.components-button:focus span:first-child{color:var(--wp-admin-theme-color)}.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__custom-template-button,.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__template-list__prompt,.edit-site-custom-template-modal__contents .edit-site-add-new-template__custom-template-button,.edit-site-custom-template-modal__contents .edit-site-add-new-template__template-list__prompt{grid-column:1/-1}.edit-site-add-new-template__template-list__contents>.components-button{align-items:flex-start;height:100%;text-align:start}.edit-site-visual-editor__editor-canvas.is-focused{outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-2)}.edit-site-canvas-loader{align-items:center;display:flex;height:100%;justify-content:center;opacity:0;position:absolute;right:0;top:0;width:100%}@media not (prefers-reduced-motion){.edit-site-canvas-loader{animation:edit-site-canvas-loader__fade-in-animation .5s ease .2s;animation-fill-mode:forwards}}.edit-site-canvas-loader>div{width:160px}@keyframes edit-site-canvas-loader__fade-in-animation{0%{opacity:0}to{opacity:1}}.edit-site-global-styles-preview{align-items:center;cursor:pointer;display:flex;justify-content:center;line-height:1}.edit-site-global-styles-preview__wrapper{display:block;max-width:100%;width:100%}.edit-site-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:16px;min-height:100px;overflow:hidden}.edit-site-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.edit-site-font-size__item-value{color:#757575}.edit-site-global-styles-screen{margin:12px 16px 16px}.edit-site-global-styles-screen-typography__indicator{align-items:center;border-radius:1px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.edit-site-global-styles-screen-typography__font-variants-count{color:#757575}.edit-site-global-styles-font-families__manage-fonts{justify-content:center}.edit-site-global-styles-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.edit-site-global-styles-header__description{padding:0 16px}.edit-site-block-types-search{margin-bottom:8px;padding:0 16px}.edit-site-global-styles-header{margin-bottom:0!important}.edit-site-global-styles-subtitle{font-size:11px!important;font-weight:500!important;margin-bottom:0!important;text-transform:uppercase}.edit-site-global-styles-section-title{color:#2f2f2f;font-weight:600;line-height:1.2;margin:0;padding:16px 16px 0}.edit-site-global-styles-icon-with-current-color{fill:currentColor}.edit-site-global-styles__color-indicator-wrapper{flex-shrink:0;height:24px}.edit-site-global-styles__shadows-panel__options-container,.edit-site-global-styles__shadows-panel__title{height:24px}.edit-site-global-styles__block-preview-panel{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;position:relative;width:100%}.edit-site-global-styles__shadow-preview-panel{background-image:repeating-linear-gradient(-45deg,#f5f5f5 25%,#0000 0,#0000 75%,#f5f5f5 0,#f5f5f5),repeating-linear-gradient(-45deg,#f5f5f5 25%,#0000 0,#0000 75%,#f5f5f5 0,#f5f5f5);background-position:100% 0,right 8px top 8px;background-size:16px 16px;border:1px solid #e0e0e0;border-radius:4px;height:144px;overflow:auto}.edit-site-global-styles__shadow-preview-panel .edit-site-global-styles__shadow-preview-block{background-color:#fff;border:1px solid #e0e0e0;border-radius:2px;height:60px;width:60%}.edit-site-global-styles__shadow-editor__dropdown-content{width:280px}.edit-site-global-styles__shadow-editor-panel{margin-bottom:4px}.edit-site-global-styles__shadow-editor__dropdown{position:relative;width:100%}.edit-site-global-styles__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:right;width:100%}.edit-site-global-styles__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.edit-site-global-styles__shadow-editor__remove-button{left:8px;opacity:0;position:absolute;top:8px}.edit-site-global-styles__shadow-editor__remove-button.edit-site-global-styles__shadow-editor__remove-button{border:none}.edit-site-global-styles__shadow-editor__dropdown-toggle:hover+.edit-site-global-styles__shadow-editor__remove-button,.edit-site-global-styles__shadow-editor__remove-button:focus,.edit-site-global-styles__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.edit-site-global-styles__shadow-editor__remove-button{opacity:1}}.edit-site-global-styles-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.edit-site-global-styles-screen-css .components-v-stack{flex:1 1 auto}.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input,.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field .components-textarea-control__input{direction:ltr;flex:1 1 auto}.edit-site-global-styles-screen-css-help-link{display:inline-block;margin-top:8px}.edit-site-global-styles-screen-variations{border-top:1px solid #ddd;margin-top:16px}.edit-site-global-styles-screen-variations>*{margin:24px 16px}.edit-site-global-styles-sidebar__navigator-provider{height:100%}.edit-site-global-styles-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.edit-site-global-styles-sidebar__navigator-screen .single-column{grid-column:span 1}.edit-site-global-styles-screen-root.edit-site-global-styles-screen-root,.edit-site-global-styles-screen-style-variations.edit-site-global-styles-screen-style-variations{background:unset;color:inherit}.edit-site-global-styles-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile,.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile .edit-site-global-styles-screen-root__active-style-tile-preview{border-radius:2px}.edit-site-global-styles-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.edit-site-global-styles-screen-revisions__revisions-list li{margin-bottom:0}.edit-site-global-styles-screen-revisions__revision-item{cursor:pointer;display:flex;flex-direction:column;position:relative}.edit-site-global-styles-screen-revisions__revision-item[role=option]:active,.edit-site-global-styles-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 #0000}.edit-site-global-styles-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.edit-site-global-styles-screen-revisions__revision-item:hover .edit-site-global-styles-screen-revisions__date{color:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item:after,.edit-site-global-styles-screen-revisions__revision-item:before{content:"\a";display:block;position:absolute}.edit-site-global-styles-screen-revisions__revision-item:before{background:#ddd;border:4px solid #0000;border-radius:50%;height:8px;right:17px;top:18px;transform:translate(50%,-50%);width:8px;z-index:1}.edit-site-global-styles-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 #0000;outline-offset:-2px}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__date{color:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__changes>li,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__meta{color:#1e1e1e}.edit-site-global-styles-screen-revisions__revision-item:after{border:.5px solid #ddd;height:100%;right:16px;top:0;width:0}.edit-site-global-styles-screen-revisions__revision-item:first-child:after{top:18px}.edit-site-global-styles-screen-revisions__revision-item:last-child:after{height:18px}.edit-site-global-styles-screen-revisions__revision-item-wrapper{display:block;padding:12px 40px 4px 12px}.edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:4px 40px 12px 12px}.edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__changes,.edit-site-global-styles-screen-revisions__meta{color:#757575;font-size:12px}.edit-site-global-styles-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.edit-site-global-styles-screen-revisions__description .edit-site-global-styles-screen-revisions__date{font-size:12px;font-weight:600;text-transform:uppercase}.edit-site-global-styles-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:right;width:100%}.edit-site-global-styles-screen-revisions__meta img{border-radius:100%;height:16px;margin-left:8px;width:16px}.edit-site-global-styles-screen-revisions__loading{margin:24px auto!important}.edit-site-global-styles-screen-revisions__changes{line-height:1.4;list-style:disc;margin-right:12px;text-align:right}.edit-site-global-styles-screen-revisions__changes li{margin-bottom:4px}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination{gap:2px;justify-content:space-between}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .edit-site-pagination__total{height:1px;margin:-1px;overflow:hidden;position:absolute;right:-1000px}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary:disabled,.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.edit-site-global-styles-screen-revisions__footer{background:#fff;border-top:1px solid #ddd;bottom:0;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.editor-sidebar{width:280px}.editor-sidebar>.components-panel{border-left:0;border-right:0;margin-bottom:-1px;margin-top:-1px}.editor-sidebar>.components-panel>.components-panel__header{background:#f0f0f0}.editor-sidebar .block-editor-block-inspector__card{margin:0}.edit-site-global-styles-sidebar{display:flex;flex-direction:column;min-height:100%}.edit-site-global-styles-sidebar__panel{flex:1}.edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-title{margin:0}.edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-actions{flex:1}.edit-site-global-styles-sidebar .components-navigation__menu-title-heading{font-size:15.6px;font-weight:500}.edit-site-global-styles-sidebar .components-navigation__item>button span{font-weight:500}.edit-site-global-styles-sidebar .block-editor-panel-color-gradient-settings{border:0}.edit-site-global-styles-sidebar .single-column{grid-column:span 1}.edit-site-global-styles-sidebar .components-tools-panel .span-columns{grid-column:1/-1}.edit-site-global-styles-sidebar__blocks-group{border-top:1px solid #e0e0e0;padding-top:24px}.edit-site-global-styles-sidebar__blocks-group-help{padding:0 16px}.edit-site-global-styles-color-palette-panel,.edit-site-global-styles-gradient-palette-panel{padding:16px}.edit-site-global-styles-sidebar hr{margin:0}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon{width:auto}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon svg{display:none}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon:after{content:attr(aria-label);font-size:12px}.edit-site-page{background:#fff;color:#2f2f2f;container:edit-site-page/inline-size;height:100%}@media not (prefers-reduced-motion){.edit-site-page{transition:width .2s ease-out}}.edit-site-page-header{background:#fff;border-bottom:1px solid #f0f0f0;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-page-header{transition:padding .1s ease-out}}.edit-site-page-header .components-heading{color:#1e1e1e}.edit-site-page-header .edit-site-page-header__page-title{min-height:40px}.edit-site-page-header .edit-site-page-header__page-title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-page-header .edit-site-page-header__sub-title{margin-bottom:8px}@container (max-width: 430px){.edit-site-page-header{padding:16px 24px}}.edit-site-page-content{display:flex;flex-flow:column;height:100%;position:relative;z-index:1}.edit-site-patterns__delete-modal{width:384px}.page-patterns-preview-field{align-items:center;border-radius:4px;display:flex;flex-direction:column;height:100%;justify-content:center}.dataviews-view-grid .page-patterns-preview-field .block-editor-block-preview__container{height:100%}.dataviews-view-table .page-patterns-preview-field{flex-grow:0;text-wrap:balance;text-wrap:pretty;width:96px}.edit-site-patterns__pattern-icon{fill:var(--wp-block-synced-color);flex-shrink:0}.edit-site-patterns__section-header{border-bottom:1px solid #f0f0f0;flex-shrink:0;min-height:40px;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-patterns__section-header{transition:padding .1s ease-out}}.edit-site-patterns__section-header .edit-site-patterns__title{min-height:40px}.edit-site-patterns__section-header .edit-site-patterns__title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-patterns__section-header .edit-site-patterns__sub-title{margin-bottom:8px}.edit-site-patterns__section-header .screen-reader-shortcut:focus{top:0}.edit-site-page-patterns-dataviews .dataviews-view-grid__badge-fields .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully){background:rgba(var(--wp-block-synced-color--rgb),.04);color:var(--wp-block-synced-color)}.dataviews-action-modal__duplicate-pattern [role=dialog]>[role=document]{width:350px}.dataviews-action-modal__duplicate-pattern .patterns-menu-items__convert-modal-categories{position:relative}.dataviews-action-modal__duplicate-pattern .components-form-token-field__suggestions-list:not(:empty){background-color:#fff;border:1px solid var(--wp-admin-theme-color);border-bottom-left-radius:2px;border-bottom-right-radius:2px;box-shadow:0 0 .5px .5px var(--wp-admin-theme-color);box-sizing:border-box;max-height:96px;min-width:auto;position:absolute;right:-1px;width:calc(100% + 2px);z-index:1}@media (min-width:600px){.dataviews-action-modal__duplicate-template-part .components-modal__frame{max-width:500px}}@container (max-width: 430px){.edit-site-page-patterns-dataviews .edit-site-patterns__section-header{padding-left:24px;padding-right:24px}}.page-templates-preview-field{align-items:center;border-radius:4px;display:flex;flex-direction:column;height:100%;justify-content:center;width:100%}.dataviews-view-list .page-templates-preview-field .block-editor-block-preview__container{height:120px}.dataviews-view-grid .page-templates-preview-field .block-editor-block-preview__container{height:100%}.dataviews-view-table .page-templates-preview-field{max-height:160px;position:relative;text-wrap:balance;text-wrap:pretty;width:120px}.dataviews-view-table .page-templates-preview-field:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;position:absolute;right:0;top:0;width:100%}.page-templates-description{max-width:50em;text-wrap:balance;text-wrap:pretty}.dataviews-view-table .page-templates-description{display:block;margin-bottom:8px}.edit-site-page-templates .dataviews-pagination{z-index:2}.page-templates-author-field__avatar{align-items:center;display:flex;flex-shrink:0;height:24px;justify-content:right;overflow:hidden;width:24px}.page-templates-author-field__avatar img{border-radius:100%;height:16px;object-fit:cover;opacity:0;width:16px}@media not (prefers-reduced-motion){.page-templates-author-field__avatar img{transition:opacity .1s linear}}.page-templates-author-field__avatar.is-loaded img{opacity:1}.page-templates-author-field__icon{display:flex;flex-shrink:0;height:24px;width:24px}.page-templates-author-field__icon svg{margin-right:-4px;fill:currentColor}.page-templates-author-field__name{overflow:hidden;text-overflow:ellipsis}.edit-site-list__rename-modal{z-index:1000001}@media (min-width:782px){.edit-site-list__rename-modal .components-base-control{width:320px}}.edit-site-editor__editor-interface{opacity:1}@media not (prefers-reduced-motion){.edit-site-editor__editor-interface{transition:opacity .1s ease-out}}.edit-site-editor__editor-interface.is-loading{opacity:0}.edit-site-editor__toggle-save-panel{background-color:#fff;border:1px dotted #ddd;box-sizing:border-box;display:flex;justify-content:center;padding:24px;width:280px}.edit-site-editor__view-mode-toggle{view-transition-name:toggle;height:60px;right:0;top:0;width:60px;z-index:100}.edit-site-editor__view-mode-toggle .components-button{align-items:center;border-radius:0;color:#fff;display:flex;height:100%;justify-content:center;overflow:hidden;padding:0;width:100%}.edit-site-editor__view-mode-toggle .components-button:active,.edit-site-editor__view-mode-toggle .components-button:hover{color:#fff}.edit-site-editor__view-mode-toggle .components-button:focus{box-shadow:none}.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon img,.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon svg{background:#1e1e1e;display:block}.edit-site-editor__back-icon{align-items:center;background-color:#ccc;display:flex;height:60px;justify-content:center;pointer-events:none;position:absolute;right:0;top:0;width:60px}.edit-site-editor__back-icon svg{fill:currentColor}.edit-site-editor__back-icon.has-site-icon{-webkit-backdrop-filter:saturate(180%) blur(15px);backdrop-filter:saturate(180%) blur(15px);background-color:#fff9}.edit-site-welcome-guide{width:312px}.edit-site-welcome-guide.guide-editor .edit-site-welcome-guide__image,.edit-site-welcome-guide.guide-styles .edit-site-welcome-guide__image{background:#00a0d2}.edit-site-welcome-guide.guide-page .edit-site-welcome-guide__video{border-left:16px solid #3858e9;border-top:16px solid #3858e9}.edit-site-welcome-guide.guide-template .edit-site-welcome-guide__video{border-right:16px solid #3858e9;border-top:16px solid #3858e9}.edit-site-welcome-guide__image{margin:0 0 16px}.edit-site-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-site-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-site-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 16px;padding:0 32px}.edit-site-welcome-guide__text img{vertical-align:bottom}.edit-site-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-site-layout{color:#ccc;display:flex;flex-direction:column;height:100%}.edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{background:#1e1e1e}.edit-site-layout__content{display:flex;flex-grow:1;height:100%}.edit-site-layout__sidebar-region{flex-shrink:0;width:100vw;z-index:1}@media (min-width:782px){.edit-site-layout__sidebar-region{width:300px}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{height:100vh;position:fixed!important;right:0;top:0}.edit-site-layout__sidebar-region .edit-site-layout__sidebar{display:flex;flex-direction:column;height:100%}.edit-site-layout__sidebar-region .resizable-editor__drag-handle{left:0}.edit-site-layout__main{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.edit-site-layout__mobile{display:flex;flex-direction:column;position:relative;width:100%;z-index:2}.edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{padding:0}.edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{padding:0 12px}.edit-site-layout__canvas-container{flex-grow:1;overflow:visible;position:relative;z-index:2}.edit-site-layout__canvas-container.is-resizing:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:100}.edit-site-layout__canvas{align-items:center;bottom:0;display:flex;justify-content:center;position:absolute;right:0;top:0;width:100%}.edit-site-layout__canvas.is-right-aligned{justify-content:flex-end}.edit-site-layout__canvas .edit-site-resizable-frame__inner{color:#1e1e1e}@media (min-width:782px){.edit-site-layout__canvas{bottom:16px;top:16px;width:calc(100% - 16px)}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;overflow:hidden}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{transition:border-radius,box-shadow .4s}}@media (min-width:782px){.edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{border-radius:8px}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005}}.edit-site-layout.is-full-canvas .edit-site-layout__canvas{bottom:0;top:0;width:100%}.edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{min-height:100%!important;position:relative!important}.edit-site-template-pages-preview{height:100%}html.canvas-mode-edit-transition::view-transition-group(toggle){animation-delay:255ms}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){animation:none!important}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{display:none}.edit-site-layout__view-mode-toggle.components-button{view-transition-name:toggle;align-items:center;background:#1e1e1e;border-radius:0;color:#fff;display:flex;height:60px;justify-content:center;overflow:hidden;padding:0;position:relative;width:60px}.edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{color:#fff}.edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{box-shadow:0 0 0 3px #1e1e1e,0 0 0 6px var(--wp-admin-theme-color);outline:4px solid #0000;outline-offset:4px}.edit-site-layout__view-mode-toggle.components-button:before{border-radius:4px;bottom:9px;box-shadow:none;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}@media not (prefers-reduced-motion){.edit-site-layout__view-mode-toggle.components-button:before{transition:box-shadow .1s ease}}.edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{align-items:center;display:flex;height:60px;justify-content:center;width:60px}.edit-site-layout__actions{background:#fff;bottom:auto;color:#1e1e1e;left:0;position:fixed!important;right:auto;top:-9999em;width:280px;z-index:100000}.edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{bottom:0;top:auto}.edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{top:0}@media (min-width:782px){.edit-site-layout__actions{border-right:1px solid #ddd}}.edit-site-layout__area{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;flex-grow:1;margin:0;overflow:hidden}@media (min-width:782px){.edit-site-layout__area{border-radius:8px;margin:16px 0 16px 16px}}.edit-site .components-editor-notices__snackbar{bottom:16px;left:0;padding-left:16px;padding-right:16px;position:fixed}.edit-site-save-hub{border-top:1px solid #2f2f2f;color:#949494;flex-shrink:0;margin:0;padding:16px}.edit-site-save-hub__button{color:inherit;justify-content:center;width:100%}.edit-site-save-hub__button[aria-disabled=true]{opacity:1}.edit-site-save-hub__button[aria-disabled=true]:hover{color:inherit}.edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{color:#1e1e1e}@media (min-width:600px){.edit-site-save-panel__modal{width:600px}}.edit-site-sidebar__content{contain:content;flex-grow:1;overflow-x:hidden;overflow-y:auto}@keyframes _x51ri_slide-from-right{0%{opacity:0;transform:translateX(-50px)}to{opacity:1;transform:none}}@keyframes _x51ri_slide-from-left{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:none}}.edit-site-sidebar__screen-wrapper{animation-duration:.14s;animation-timing-function:ease-in-out;display:flex;flex-direction:column;height:100%;max-height:100%;overflow-x:auto;padding:0 12px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:stable;scrollbar-width:thin;will-change:transform;will-change:transform,opacity}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar{height:12px;width:12px}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{background-color:initial}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{background-color:#757575}.edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{scrollbar-color:#757575 #0000}@media (hover:none){.edit-site-sidebar__screen-wrapper{scrollbar-color:#757575 #0000}}@media (prefers-reduced-motion:reduce){.edit-site-sidebar__screen-wrapper{animation-duration:0s}}.edit-site-sidebar__screen-wrapper.slide-from-left{animation-name:_x51ri_slide-from-left}.edit-site-sidebar__screen-wrapper.slide-from-right{animation-name:_x51ri_slide-from-right}.edit-site-sidebar-button{color:#e0e0e0;flex-shrink:0}.edit-site-sidebar-button:focus:not(:disabled){box-shadow:none;outline:none}.edit-site-sidebar-button:focus-visible:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:3px solid #0000}.edit-site-sidebar-button:focus,.edit-site-sidebar-button:focus-visible,.edit-site-sidebar-button:hover:not(:disabled,[aria-disabled=true]),.edit-site-sidebar-button:not(:disabled,[aria-disabled=true]):active,.edit-site-sidebar-button[aria-expanded=true]{color:#f0f0f0}.edit-site-sidebar-navigation-item.components-item{border:none;color:#949494;min-height:40px;padding:8px 16px 8px 6px}.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-item.components-item[aria-current=true]{color:#e0e0e0}.edit-site-sidebar-navigation-item.components-item:focus .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item:hover .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item[aria-current=true] .edit-site-sidebar-navigation-item__drilldown-indicator{fill:#e0e0e0}.edit-site-sidebar-navigation-item.components-item[aria-current=true]{background:#2f2f2f;color:#fff;font-weight:500}.edit-site-sidebar-navigation-item.components-item:focus-visible{transform:translateZ(0)}.edit-site-sidebar-navigation-item.components-item .edit-site-sidebar-navigation-item__drilldown-indicator{fill:#949494}.edit-site-sidebar-navigation-item.components-item.with-suffix{padding-left:16px}.edit-site-sidebar-navigation-screen__content .block-editor-list-view-block-select-button{cursor:grab;padding:8px 0 8px 8px}.edit-site-sidebar-navigation-screen{display:flex;flex-direction:column;overflow-x:unset!important;position:relative}.edit-site-sidebar-navigation-screen__main{flex-grow:1;margin-bottom:16px}.edit-site-sidebar-navigation-screen__main.has-footer{margin-bottom:0}.edit-site-sidebar-navigation-screen__content{padding:0 16px}.edit-site-sidebar-navigation-screen__content .components-text{color:#ccc}.edit-site-sidebar-navigation-screen__content .components-heading{margin-bottom:8px}.edit-site-sidebar-navigation-screen__title-icon{background:#1e1e1e;margin-bottom:8px;padding-bottom:8px;padding-top:48px;position:sticky;top:0;z-index:1}.edit-site-sidebar-navigation-screen__title{flex-grow:1;overflow-wrap:break-word}.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title,.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title .edit-site-sidebar-navigation-screen__title{line-height:32px}.edit-site-sidebar-navigation-screen__actions{display:flex;flex-shrink:0}@media (min-width:782px){.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variation-container{max-width:292px}}.edit-site-global-styles-variation-title{color:#ddd;font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{outline-color:#ffffff0d}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{outline-color:#ffffff26}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview{outline-color:#fff}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.edit-site-sidebar-navigation-screen__footer{background-color:#1e1e1e;border-top:1px solid #2f2f2f;bottom:0;gap:0;margin:16px 0 0;padding:8px 16px;position:sticky}.edit-site-sidebar-navigation-screen__footer .edit-site-sidebar-navigation-screen-details-footer{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen__input-control{width:100%}.edit-site-sidebar-navigation-screen__input-control .components-input-control__container{background:#2f2f2f}.edit-site-sidebar-navigation-screen__input-control .components-input-control__container .components-button{color:#e0e0e0!important}.edit-site-sidebar-navigation-screen__input-control .components-input-control__input{background:#2f2f2f!important;color:#e0e0e0!important}.edit-site-sidebar-navigation-screen__input-control .components-input-control__backdrop{border:4px!important}.edit-site-sidebar-navigation-screen__input-control .components-base-control__help{color:#949494}.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item[aria-current]{background:none}.sidebar-navigation__more-menu .components-button{color:#e0e0e0}.sidebar-navigation__more-menu .components-button:focus,.sidebar-navigation__more-menu .components-button:hover,.sidebar-navigation__more-menu .components-button[aria-current]{color:#f0f0f0}.edit-site-sidebar-navigation-screen-patterns__group{margin-bottom:24px;margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-patterns__group:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.edit-site-sidebar-navigation-screen-patterns__group-header{margin-top:16px}.edit-site-sidebar-navigation-screen-patterns__group-header p{color:#949494}.edit-site-sidebar-navigation-screen-patterns__group-header h2{font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-navigation-screen-patterns__divider{border-top:1px solid #2f2f2f;margin:16px 0}.edit-site-sidebar-navigation-screen__description{margin:0 0 32px}.edit-site-sidebar-navigation-screen-navigation-menus{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell{width:100%}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{white-space:normal}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__title{margin-top:3px}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu-cell{padding-left:0}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button{color:#949494}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:hover,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button[aria-current]{color:#fff}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu{color:#949494}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:hover{color:#fff}.edit-site-sidebar-navigation-screen-navigation-menus__loading.components-spinner{display:block;margin-left:auto;margin-right:auto}.edit-site-sidebar-navigation-screen-navigation-menus__helper-block-editor{display:none}.edit-site-sidebar-navigation-screen-main,.edit-site-sidebar-navigation-screen-templates-browse{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-dataviews__group-header{margin-top:32px}.edit-site-sidebar-navigation-screen-dataviews__group-header h2{font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-dataviews{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-dataviews__custom-items .edit-site-sidebar-dataviews-dataview-item{padding-left:8px}.edit-site-sidebar-dataviews-dataview-item{border-radius:2px}.edit-site-sidebar-dataviews-dataview-item .edit-site-sidebar-dataviews-dataview-item__dropdown-menu{min-width:auto}.edit-site-sidebar-dataviews-dataview-item:focus,.edit-site-sidebar-dataviews-dataview-item:hover,.edit-site-sidebar-dataviews-dataview-item[aria-current]{color:#e0e0e0}.edit-site-sidebar-dataviews-dataview-item.is-selected{background:#2f2f2f;color:#fff;font-weight:500}.edit-site-site-hub{align-items:center;display:flex;gap:8px;height:60px;justify-content:space-between;margin-left:12px}.edit-site-site-hub__actions{flex-shrink:0}.edit-site-site-hub__view-mode-toggle-container{flex-shrink:0;height:60px;width:60px}.edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{background:#0000}.edit-site-site-hub__title .components-button{color:#e0e0e0;display:block;flex-grow:1;font-size:15px;font-weight:500;margin-right:-4px;overflow:hidden;padding-left:16px;position:relative;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{color:#e0e0e0}.edit-site-site-hub__title .components-button:focus{box-shadow:none;outline:none}.edit-site-site-hub__title .components-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.edit-site-site-hub__title .components-button:after{content:"↗";font-weight:400;left:0;opacity:0;position:absolute}@media not (prefers-reduced-motion){.edit-site-site-hub__title .components-button:after{transition:opacity .1s linear}}.edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{opacity:1}.edit-site-site-hub_toggle-command-center{color:#e0e0e0}.edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{fill:#f0f0f0}.edit-site-site-icon__icon{fill:currentColor;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__icon{padding:12px}.edit-site-site-icon__image{aspect-ratio:1/1;background:#333;height:100%;object-fit:cover;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__image{border-radius:0}.edit-site-editor__view-mode-toggle button:focus{position:relative}.edit-site-editor__view-mode-toggle button:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:1}.edit-site-style-book{align-items:stretch;display:flex;flex-direction:column;height:100%}.edit-site-style-book.is-button{border-radius:8px}.edit-site-style-book__iframe{display:block;height:100%;width:100%}.edit-site-style-book__iframe.is-button{border-radius:8px}.edit-site-style-book__iframe.is-focused{outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-2)}.edit-site-style-book__tablist-container{background:#fff;display:flex;flex:none;padding-left:56px;width:100%}.edit-site-style-book__tabpanel{flex:1 0 auto;overflow:auto}.edit-site-editor-canvas-container{background-color:#ddd;height:100%}.edit-site-editor-canvas-container iframe{display:block;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{padding:24px 24px 0}.edit-site-editor-canvas-container__section{background:#fff;border-radius:8px;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.edit-site-editor-canvas-container__section{transition:all .3s}}.edit-site-editor-canvas-container__close-button{background:#fff;left:8px;position:absolute;top:8px;z-index:2}.edit-site-post-edit{padding:24px}.edit-site-post-edit.is-empty .edit-site-page-content{align-items:center;display:flex;justify-content:center}.dataforms-layouts-panel__field-dropdown .fields-controls__password{border-top:1px solid #e0e0e0;padding-top:16px}.edit-site-post-list__featured-image{height:100%;object-fit:cover;width:100%}.edit-site-post-list__featured-image-wrapper{border-radius:4px;height:100%;width:100%}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){background-color:#f0f0f0;border-radius:4px;display:block;flex-grow:0!important;height:32px;overflow:hidden;position:relative;width:32px}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;position:absolute;right:0;top:0;width:100%}.edit-site-post-list__featured-image-button{background-color:unset;border:none;border-radius:4px;box-shadow:none;box-sizing:border-box;cursor:pointer;height:100%;overflow:hidden;padding:0;width:100%}.edit-site-post-list__featured-image-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{background:rgba(var(--wp-admin-theme-color--rgb),.04);box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.edit-site-post-list__status-icon{height:24px;width:24px}.edit-site-post-list__status-icon svg{fill:currentColor;margin-right:-4px}.edit-site-resizable-frame__inner{position:relative}body:has(.edit-site-resizable-frame__inner.is-resizing){cursor:col-resize;user-select:none;-webkit-user-select:none}.edit-site-resizable-frame__inner.is-resizing:before{content:"";inset:0;position:absolute;z-index:1}.edit-site-resizable-frame__inner-content{inset:0;position:absolute;z-index:0}.edit-site-resizable-frame__handle{align-items:center;background-color:#75757566;border:0;border-radius:4px;cursor:col-resize;display:flex;height:64px;justify-content:flex-end;padding:0;position:absolute;top:calc(50% - 32px);width:4px;z-index:100}.edit-site-resizable-frame__handle:before{content:"";height:100%;position:absolute;right:100%;width:32px}.edit-site-resizable-frame__handle:after{content:"";height:100%;left:100%;position:absolute;width:32px}.edit-site-resizable-frame__handle:focus-visible{outline:2px solid #0000}.edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{background-color:var(--wp-admin-theme-color)}.edit-site-push-changes-to-global-styles-control .components-button{justify-content:center;width:100%}@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:70px;padding-top:0}.font-library-modal .font-library-modal__subtitle{font-size:11px;font-weight:500;text-transform:uppercase}.font-library-modal .components-navigator-screen{padding:3px}.font-library-modal__tabpanel-layout{margin-top:32px}.font-library-modal__tabpanel-layout .font-library-modal__loading{align-items:center;display:flex;height:100%;justify-content:center;padding-top:120px;position:absolute;right:0;top:0;width:100%}.font-library-modal__footer{background-color:#fff;border-top:1px solid #ddd;bottom:32px;height:70px;margin:0 -32px -32px;padding:16px 32px;position:absolute;width:100%}.font-library-modal__page-selection{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.font-library-modal__page-selection .components-select-control__input{font-size:11px!important;font-weight:500}}.font-library-modal__tabpanel-layout .components-base-control__field{margin-bottom:0}.font-library-modal__fonts-title{font-size:11px;font-weight:600;margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library-modal__fonts-list{margin-bottom:0;margin-top:0}.font-library-modal__fonts-list-item{margin-bottom:0}.font-library-modal__font-card{border:1px solid #e0e0e0;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library-modal__font-card:hover{background-color:#f0f0f0}.font-library-modal__font-card .font-library-modal__font-card__name{font-weight:700}.font-library-modal__font-card .font-library-modal__font-card__count{color:#757575}.font-library-modal__font-card .font-library-modal__font-variant_demo-image{display:block;height:24px;width:auto}.font-library-modal__font-card .font-library-modal__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library-modal__font-card .font-library-modal__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__font-variant{border-bottom:1px solid #e0e0e0;padding-bottom:16px}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid #ddd;margin:0 -32px;padding:0 16px;position:sticky;top:0;z-index:1}.font-library-modal__tablist-container [role=tablist]{margin-bottom:-1px}.font-library-modal__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library-modal__upload-area{background-color:#f0f0f0}.font-library-modal__local-fonts{margin:0 auto;width:80%}.font-library-modal__local-fonts .font-library-modal__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-modal__select-all{padding:16px 17px 16px 16px}.font-library-modal__select-all .components-checkbox-control__label{padding-right:16px}.edit-site-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.edit-site-global-styles-variations_item{box-sizing:border-box;cursor:pointer}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{border-radius:2px;outline:1px solid #0000001a;outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{transition:outline .1s linear}}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill{height:32px}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{outline-color:#0000004d}.edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview,.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root{box-shadow:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root>div>hr{display:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider{overflow-y:auto;padding-left:0;padding-right:0}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .components-tools-panel{border-top:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .edit-site-global-styles-sidebar__navigator-screen{outline:none;padding:12px}.edit-site-styles .edit-site-page-content .edit-site-page-header{padding-left:48px;padding-right:48px}@container (max-width: 430px){.edit-site-styles .edit-site-page-content .edit-site-page-header{padding-left:24px;padding-right:24px}}.edit-site-styles .edit-site-page-content .edit-site-sidebar-button{color:#1e1e1e}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon{padding:0 8px;width:auto}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon svg{display:none}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon:after{content:attr(aria-label);font-size:12px}::view-transition-image-pair(root){isolation:auto}::view-transition-new(root),::view-transition-old(root){animation:none;display:block;mix-blend-mode:normal}body.js #wpadminbar{display:none}body.js #wpbody{padding-top:0}body.js.appearance_page_gutenberg-template-parts,body.js.site-editor-php{background:#fff}body.js.appearance_page_gutenberg-template-parts #wpcontent,body.js.site-editor-php #wpcontent{padding-right:0}body.js.appearance_page_gutenberg-template-parts #wpbody-content,body.js.site-editor-php #wpbody-content{padding-bottom:0}body.js.appearance_page_gutenberg-template-parts #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.appearance_page_gutenberg-template-parts #wpfooter,body.js.site-editor-php #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.site-editor-php #wpfooter{display:none}body.js.appearance_page_gutenberg-template-parts .a11y-speak-region,body.js.site-editor-php .a11y-speak-region{right:-1px;top:-1px}body.js.appearance_page_gutenberg-template-parts ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-template-parts ul#adminmenu>li.current>a.current:after,body.js.site-editor-php ul#adminmenu a.wp-has-current-submenu:after,body.js.site-editor-php ul#adminmenu>li.current>a.current:after{border-left-color:#fff}body.js.appearance_page_gutenberg-template-parts .media-frame select.attachment-filters:last-of-type,body.js.site-editor-php .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}body.js.site-editor-php{background:#1e1e1e}.edit-site{box-sizing:border-box;height:100vh}.edit-site *,.edit-site :after,.edit-site :before{box-sizing:inherit}@media (min-width:600px){.edit-site{bottom:0;left:0;min-height:100vh;position:fixed;right:0;top:0}}.no-js .edit-site{min-height:0;position:static}.edit-site .interface-interface-skeleton{top:0}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.dataviews-wrapper{box-sizing:border-box;container:dataviews-wrapper/inline-size;display:flex;flex-direction:column;font-size:13px;height:100%;line-height:1.4;overflow:auto;scroll-padding-bottom:64px}.dataviews-filters__container,.dataviews__view-actions{box-sizing:border-box;flex-shrink:0;padding:16px 48px;position:sticky;right:0}@media not (prefers-reduced-motion){.dataviews-filters__container,.dataviews__view-actions{transition:padding .1s ease-out}}.dataviews-loading,.dataviews-no-results{align-items:center;display:flex;flex-grow:1;justify-content:center;padding:0 48px}@media not (prefers-reduced-motion){.dataviews-loading,.dataviews-no-results{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-filters__container,.dataviews__view-actions{padding:12px 24px}.dataviews-loading,.dataviews-no-results{padding-left:24px;padding-right:24px}}.dataviews-title-field{font-size:13px;font-weight:500;width:100%}.dataviews-title-field,.dataviews-title-field a{color:#2f2f2f;text-overflow:ellipsis;white-space:nowrap}.dataviews-title-field a{display:block;flex-grow:0;overflow:hidden;text-decoration:none}.dataviews-title-field a:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field a:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-title-field button.components-button.is-link{color:#1e1e1e;display:block;font-weight:inherit;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.dataviews-title-field button.components-button.is-link:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable{color:#2f2f2f;cursor:pointer}.dataviews-title-field--clickable:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-bulk-actions-footer__item-count{color:#1e1e1e;font-size:11px;font-weight:500;text-transform:uppercase}.dataviews-bulk-actions-footer__container{margin-left:auto;min-height:32px}.dataviews-filters__button{position:relative}.dataviews-filters__container{padding-top:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{opacity:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{opacity:1}.dataviews-filters__summary-popover{font-size:13px;line-height:1.4}.dataviews-filters__summary-popover .components-popover__content{border-radius:4px;width:230px}.dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{padding:0}.dataviews-filters__summary-operators-container{padding:8px 8px 0}.dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){border-bottom:1px solid #e0e0e0;padding-bottom:8px}.dataviews-filters__summary-operators-container:empty{display:none}.dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{color:#757575}.dataviews-filters__summary-chip-container{position:relative;white-space:pre-wrap}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{align-items:center;background:#f0f0f0;border:1px solid #0000;border-radius:16px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;min-height:32px;padding:4px 12px;position:relative}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{padding-inline-end:28px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{background:#e0e0e0;color:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{background:rgba(var(--wp-admin-theme-color--rgb),.04);color:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{background:rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{font-weight:500}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{align-items:center;background:#0000;border:0;border-radius:50%;cursor:pointer;display:flex;height:24px;justify-content:center;left:4px;padding:0;position:absolute;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{fill:#757575}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{background:#e0e0e0}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{fill:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{fill:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{background:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__search-widget-filter-combobox-list{border-top:1px solid #e0e0e0;max-height:184px;overflow:auto;padding:4px}.dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{font-weight:600}.dataviews-filters__search-widget-listbox{overflow:auto;padding:4px}.dataviews-filters__search-widget-listitem{align-items:center;border-radius:2px;box-sizing:border-box;cursor:default;display:flex;gap:8px;margin-block-end:2px;padding:8px 12px}.dataviews-filters__search-widget-listitem:last-child{margin-block-end:0}.dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{background-color:var(--wp-admin-theme-color);color:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{fill:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{color:#fff}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{flex-shrink:0;height:24px;width:24px}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{color:#757575;display:block;font-size:12px;line-height:16px;overflow:hidden;text-overflow:ellipsis}.dataviews-filters__search-widget-filter-combobox__wrapper{padding:8px;position:relative}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{background:#f0f0f0;border:none;border-radius:2px;box-shadow:0 0 0 #0000;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin-left:0;margin-right:0;padding:0 8px 0 32px;width:100%}@media not (prefers-reduced-motion){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{transition:box-shadow .1s linear}}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px;line-height:normal}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{background:#fff;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{color:#757575}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{-webkit-appearance:none}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{align-items:center;display:flex;justify-content:center;left:12px;position:absolute;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__container-visibility-toggle{flex-shrink:0;position:relative}.dataviews-filters-toggle__count{background:var(--wp-admin-theme-color,#3858e9);border-radius:8px;box-sizing:border-box;color:#fff;font-size:11px;height:16px;left:0;line-height:16px;min-width:16px;outline:var(--wp-admin-border-width-focus) solid #fff;padding:0 4px;position:absolute;text-align:center;top:0;transform:translate(-50%,-50%)}.dataviews-search{width:fit-content}.dataviews-footer{background-color:#fff;border-top:1px solid #f0f0f0;bottom:0;flex-shrink:0;padding:12px 48px;position:sticky;right:0;z-index:2}@media not (prefers-reduced-motion){.dataviews-footer{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-footer{padding:12px 24px}}@container (max-width: 560px){.dataviews-footer{flex-direction:column!important}.dataviews-footer .dataviews-bulk-actions-footer__container{width:100%}.dataviews-footer .dataviews-bulk-actions-footer__item-count{flex-grow:1}.dataviews-footer .dataviews-pagination{justify-content:space-between;width:100%}}.dataviews-pagination__page-select{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.dataviews-pagination__page-select .components-select-control__input{font-size:11px!important;font-weight:500}}.dataviews-action-modal{z-index:1000001}.dataviews-selection-checkbox{--checkbox-input-size:24px;flex-shrink:0;line-height:0}@media (min-width:600px){.dataviews-selection-checkbox{--checkbox-input-size:16px}}.dataviews-selection-checkbox .components-checkbox-control__input-container{margin:0}.dataviews-view-config{container-type:inline-size;font-size:13px;line-height:1.4;width:320px}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{height:100%;overflow-y:scroll}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{width:auto}.dataviews-view-config__sort-direction .components-toggle-group-control-option-base{text-transform:uppercase}.dataviews-settings-section__title.dataviews-settings-section__title{font-size:15px;line-height:24px}.dataviews-settings-section__sidebar{grid-column:span 4}.dataviews-settings-section__content,.dataviews-settings-section__content>*{grid-column:span 8}.dataviews-settings-section__content .is-divided-in-two{display:contents}.dataviews-settings-section__content .is-divided-in-two>*{grid-column:span 4}.dataviews-settings-section:has(.dataviews-settings-section__content:empty){display:none}@container (max-width: 500px){.dataviews-settings-section.dataviews-settings-section{grid-template-columns:repeat(2,1fr)}.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{grid-column:span 2}}.dataviews-field-control__field{height:32px}.dataviews-field-control__actions{position:absolute;top:-9999em}.dataviews-field-control__actions.dataviews-field-control__actions{gap:4px}.dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{position:unset;top:unset}.dataviews-field-control__icon{display:flex;width:24px}.dataviews-field-control__label-sub-label-container{flex-grow:1}.dataviews-field-control__label{display:block}.dataviews-field-control__sub-label{color:#757575;font-size:11px;font-style:normal;margin-bottom:0;margin-top:8px}.dataviews-view-grid{container-type:inline-size;grid-template-rows:max-content;margin-bottom:auto;padding:0 48px 24px}@media not (prefers-reduced-motion){.dataviews-view-grid{transition:padding .1s ease-out}}.dataviews-view-grid .dataviews-view-grid__card{height:100%;justify-content:flex-start;position:relative}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{padding:8px 0 4px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{align-items:center;display:flex;min-height:24px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{width:fit-content}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{color:#1e1e1e}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__media{aspect-ratio:1/1;background-color:#f0f0f0;border-radius:4px;min-height:200px;position:relative;width:100%}.dataviews-view-grid .dataviews-view-grid__media img{height:100%;object-fit:cover;width:100%}.dataviews-view-grid .dataviews-view-grid__media:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;pointer-events:none;position:absolute;right:0;top:0;width:100%}.dataviews-view-grid .dataviews-view-grid__fields{font-size:12px;line-height:16px;position:relative}.dataviews-view-grid .dataviews-view-grid__fields:not(:empty){padding:0 0 12px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){line-height:20px;min-height:24px;padding-top:2px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{align-items:center;min-height:24px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{color:#757575;width:35%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:65%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){display:none}.dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){padding-bottom:12px}@container (max-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(1,minmax(0,1fr));padding-left:24px;padding-right:24px}}@container (min-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (min-width: 780px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 1140px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@container (min-width: 1520px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{display:none}.dataviews-view-grid__card .dataviews-selection-checkbox{position:absolute;right:8px;top:-9999em;z-index:1}.dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{top:8px}.dataviews-view-grid__media--clickable{cursor:pointer}div.dataviews-view-list{list-style-type:none}.dataviews-view-list{margin:0 0 auto}.dataviews-view-list div[role=row]{border-top:1px solid #f0f0f0;margin:0}.dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{box-sizing:border-box;padding:16px 24px;position:relative}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions{flex:0;overflow:hidden}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{height:24px}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{opacity:0;position:relative;z-index:1}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{flex-basis:min-content;overflow:unset;padding-inline-end:4px}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{opacity:1}.dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{color:#1e1e1e}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{background-color:#f8f8f8;color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#1e1e1e}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list .dataviews-view-list__item{appearance:none;background:none;border:none;cursor:pointer;inset:0;padding:0;position:absolute;scroll-margin:8px 0;z-index:1}.dataviews-view-list .dataviews-view-list__item:focus-visible{outline:none}.dataviews-view-list .dataviews-view-list__item:focus-visible:before{border-radius:2px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.dataviews-view-list .dataviews-view-list__title-field{flex:1;line-height:24px;min-height:24px;overflow:hidden}.dataviews-view-list .dataviews-view-list__title-field:has(a,button){z-index:1}.dataviews-view-list .dataviews-view-list__media-wrapper{background-color:#f0f0f0;border-radius:4px;flex-shrink:0;height:52px;overflow:hidden;position:relative;width:52px}.dataviews-view-list .dataviews-view-list__media-wrapper img{height:100%;object-fit:cover;width:100%}.dataviews-view-list .dataviews-view-list__media-wrapper:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;position:absolute;right:0;top:0;width:100%}.dataviews-view-list .dataviews-view-list__field-wrapper{flex-grow:1;min-height:52px}.dataviews-view-list .dataviews-view-list__fields{color:#757575;display:flex;flex-wrap:wrap;font-size:12px;gap:12px;row-gap:4px}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{display:none}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{align-items:center;display:flex;line-height:20px;min-height:24px}.dataviews-view-list+.dataviews-pagination{justify-content:space-between}.dataviews-view-table{border-collapse:collapse;border-color:inherit;color:#757575;margin-bottom:auto;position:relative;text-indent:0;width:100%}.dataviews-view-table th{color:#1e1e1e;font-size:13px;font-weight:400;text-align:right}.dataviews-view-table td,.dataviews-view-table th{padding:12px;white-space:nowrap}.dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{text-align:left}.dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{padding-left:0;width:1%}.dataviews-view-table tr{border-top:1px solid #f0f0f0}.dataviews-view-table tr .dataviews-view-table-header-button{gap:4px}.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-right:48px}.dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{margin-right:-8px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-left:48px}.dataviews-view-table tr:last-child{border-bottom:0}.dataviews-view-table tr.is-hovered{background-color:#f8f8f8}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{opacity:0}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{opacity:1}.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:0}.dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}@media (hover:none){.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}}.dataviews-view-table tr.is-selected{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#757575}.dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-table tr.is-selected:hover{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-table thead{inset-block-start:0;position:sticky;z-index:1}.dataviews-view-table thead tr{border:0}.dataviews-view-table thead th{background-color:#fff;font-size:11px;font-weight:500;padding-bottom:8px;padding-right:12px;padding-top:8px;text-transform:uppercase}.dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-right:4px}.dataviews-view-table tbody td{vertical-align:top}.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{align-items:center;display:flex;min-height:32px}.dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){min-height:0}.dataviews-view-table .dataviews-view-table-header-button{font-size:11px;font-weight:500;padding:4px 8px;text-transform:uppercase}.dataviews-view-table .dataviews-view-table-header-button:not(:hover){color:#1e1e1e}.dataviews-view-table .dataviews-view-table-header-button span{speak:none}.dataviews-view-table .dataviews-view-table-header-button span:empty{display:none}.dataviews-view-table .dataviews-view-table-header{padding-right:4px}.dataviews-view-table .dataviews-view-table__actions-column{width:1%}.dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{opacity:1}.dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-right:0}.dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{padding:4px 8px}.dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{padding:16px 12px}.dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{padding-left:0}@container (max-width: 430px){.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-right:24px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-left:24px}}.dataviews-view-table-selection-checkbox{--checkbox-input-size:24px}@media (min-width:600px){.dataviews-view-table-selection-checkbox{--checkbox-input-size:16px}}.dataviews-column-primary__media{max-width:60px}.dataviews-controls__datetime{border:none;padding:0}.dataforms-layouts-panel__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-panel__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-panel__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.dataforms-layouts-panel__field-control .components-button{max-width:100%;min-height:32px;text-align:right;text-wrap:balance;text-wrap:pretty;white-space:normal}.dataforms-layouts-panel__field-control .components-dropdown{max-width:100%}.dataforms-layouts-panel__field-dropdown .components-popover__content{min-width:320px;padding:16px}.dataforms-layouts-panel__dropdown-header{margin-bottom:16px}.components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{z-index:159990}.dataforms-layouts-regular__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-regular__field .components-base-control__label{font-size:inherit;font-weight:400;text-transform:none}.dataforms-layouts-regular__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-regular__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.edit-site-layout{color:#ccc;display:flex;flex-direction:column;height:100%}.edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{background:#1e1e1e}.edit-site-layout__content{display:flex;flex-grow:1;height:100%}.edit-site-layout__sidebar-region{flex-shrink:0;width:100vw;z-index:1}@media (min-width:782px){.edit-site-layout__sidebar-region{width:300px}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{height:100vh;position:fixed!important;right:0;top:0}.edit-site-layout__sidebar-region .edit-site-layout__sidebar{display:flex;flex-direction:column;height:100%}.edit-site-layout__sidebar-region .resizable-editor__drag-handle{left:0}.edit-site-layout__main{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.edit-site-layout__mobile{display:flex;flex-direction:column;position:relative;width:100%;z-index:2}.edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{padding:0}.edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{padding:0 12px}.edit-site-layout__canvas-container{flex-grow:1;overflow:visible;position:relative;z-index:2}.edit-site-layout__canvas-container.is-resizing:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:100}.edit-site-layout__canvas{align-items:center;bottom:0;display:flex;justify-content:center;position:absolute;right:0;top:0;width:100%}.edit-site-layout__canvas.is-right-aligned{justify-content:flex-end}.edit-site-layout__canvas .edit-site-resizable-frame__inner{color:#1e1e1e}@media (min-width:782px){.edit-site-layout__canvas{bottom:16px;top:16px;width:calc(100% - 16px)}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;overflow:hidden}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{transition:border-radius,box-shadow .4s}}@media (min-width:782px){.edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{border-radius:8px}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005}}.edit-site-layout.is-full-canvas .edit-site-layout__canvas{bottom:0;top:0;width:100%}.edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{min-height:100%!important;position:relative!important}.edit-site-template-pages-preview{height:100%}html.canvas-mode-edit-transition::view-transition-group(toggle){animation-delay:255ms}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){animation:none!important}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{display:none}.edit-site-layout__view-mode-toggle.components-button{view-transition-name:toggle;align-items:center;background:#1e1e1e;border-radius:0;color:#fff;display:flex;height:60px;justify-content:center;overflow:hidden;padding:0;position:relative;width:60px}.edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{color:#fff}.edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{box-shadow:0 0 0 3px #1e1e1e,0 0 0 6px var(--wp-admin-theme-color);outline:4px solid #0000;outline-offset:4px}.edit-site-layout__view-mode-toggle.components-button:before{border-radius:4px;bottom:9px;box-shadow:none;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}@media not (prefers-reduced-motion){.edit-site-layout__view-mode-toggle.components-button:before{transition:box-shadow .1s ease}}.edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{align-items:center;display:flex;height:60px;justify-content:center;width:60px}.edit-site-layout__actions{background:#fff;bottom:auto;color:#1e1e1e;left:0;position:fixed!important;right:auto;top:-9999em;width:280px;z-index:100000}.edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{bottom:0;top:auto}.edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{top:0}@media (min-width:782px){.edit-site-layout__actions{border-right:1px solid #ddd}}.edit-site-layout__area{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;flex-grow:1;margin:0;overflow:hidden}@media (min-width:782px){.edit-site-layout__area{border-radius:8px;margin:16px 0 16px 16px}}.edit-site .components-editor-notices__snackbar{bottom:16px;left:0;padding-left:16px;padding-right:16px;position:fixed}.edit-site-page{background:#fff;color:#2f2f2f;container:edit-site-page/inline-size;height:100%}@media not (prefers-reduced-motion){.edit-site-page{transition:width .2s ease-out}}.edit-site-page-header{background:#fff;border-bottom:1px solid #f0f0f0;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-page-header{transition:padding .1s ease-out}}.edit-site-page-header .components-heading{color:#1e1e1e}.edit-site-page-header .edit-site-page-header__page-title{min-height:40px}.edit-site-page-header .edit-site-page-header__page-title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-page-header .edit-site-page-header__sub-title{margin-bottom:8px}@container (max-width: 430px){.edit-site-page-header{padding:16px 24px}}.edit-site-page-content{display:flex;flex-flow:column;height:100%;position:relative;z-index:1}.edit-site-save-hub{border-top:1px solid #2f2f2f;color:#949494;flex-shrink:0;margin:0;padding:16px}.edit-site-save-hub__button{color:inherit;justify-content:center;width:100%}.edit-site-save-hub__button[aria-disabled=true]{opacity:1}.edit-site-save-hub__button[aria-disabled=true]:hover{color:inherit}.edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{color:#1e1e1e}@media (min-width:600px){.edit-site-save-panel__modal{width:600px}}.edit-site-sidebar__content{contain:content;flex-grow:1;overflow-x:hidden;overflow-y:auto}@keyframes _fwjws_slide-from-right{0%{opacity:0;transform:translateX(-50px)}to{opacity:1;transform:none}}@keyframes _fwjws_slide-from-left{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:none}}.edit-site-sidebar__screen-wrapper{animation-duration:.14s;animation-timing-function:ease-in-out;display:flex;flex-direction:column;height:100%;max-height:100%;overflow-x:auto;padding:0 12px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:stable;scrollbar-width:thin;will-change:transform;will-change:transform,opacity}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar{height:12px;width:12px}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{background-color:initial}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{background-color:#757575}.edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{scrollbar-color:#757575 #0000}@media (hover:none){.edit-site-sidebar__screen-wrapper{scrollbar-color:#757575 #0000}}@media (prefers-reduced-motion:reduce){.edit-site-sidebar__screen-wrapper{animation-duration:0s}}.edit-site-sidebar__screen-wrapper.slide-from-left{animation-name:_fwjws_slide-from-left}.edit-site-sidebar__screen-wrapper.slide-from-right{animation-name:_fwjws_slide-from-right}.edit-site-site-hub{align-items:center;display:flex;gap:8px;height:60px;justify-content:space-between;margin-left:12px}.edit-site-site-hub__actions{flex-shrink:0}.edit-site-site-hub__view-mode-toggle-container{flex-shrink:0;height:60px;width:60px}.edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{background:#0000}.edit-site-site-hub__title .components-button{color:#e0e0e0;display:block;flex-grow:1;font-size:15px;font-weight:500;margin-right:-4px;overflow:hidden;padding-left:16px;position:relative;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{color:#e0e0e0}.edit-site-site-hub__title .components-button:focus{box-shadow:none;outline:none}.edit-site-site-hub__title .components-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.edit-site-site-hub__title .components-button:after{content:"↗";font-weight:400;left:0;opacity:0;position:absolute}@media not (prefers-reduced-motion){.edit-site-site-hub__title .components-button:after{transition:opacity .1s linear}}.edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{opacity:1}.edit-site-site-hub_toggle-command-center{color:#e0e0e0}.edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{fill:#f0f0f0}.edit-site-site-icon__icon{fill:currentColor;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__icon{padding:12px}.edit-site-site-icon__image{aspect-ratio:1/1;background:#333;height:100%;object-fit:cover;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__image{border-radius:0}.edit-site-editor__view-mode-toggle button:focus{position:relative}.edit-site-editor__view-mode-toggle button:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:1}.edit-site-editor-canvas-container{background-color:#ddd;height:100%}.edit-site-editor-canvas-container iframe{display:block;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{padding:24px 24px 0}.edit-site-editor-canvas-container__section{background:#fff;border-radius:8px;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.edit-site-editor-canvas-container__section{transition:all .3s}}.edit-site-editor-canvas-container__close-button{background:#fff;left:8px;position:absolute;top:8px;z-index:2}.edit-site-post-list__featured-image{height:100%;object-fit:cover;width:100%}.edit-site-post-list__featured-image-wrapper{border-radius:4px;height:100%;width:100%}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){background-color:#f0f0f0;border-radius:4px;display:block;flex-grow:0!important;height:32px;overflow:hidden;position:relative;width:32px}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;position:absolute;right:0;top:0;width:100%}.edit-site-post-list__featured-image-button{background-color:unset;border:none;border-radius:4px;box-shadow:none;box-sizing:border-box;cursor:pointer;height:100%;overflow:hidden;padding:0;width:100%}.edit-site-post-list__featured-image-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{background:rgba(var(--wp-admin-theme-color--rgb),.04);box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.edit-site-post-list__status-icon{height:24px;width:24px}.edit-site-post-list__status-icon svg{fill:currentColor;margin-right:-4px}.edit-site-resizable-frame__inner{position:relative}body:has(.edit-site-resizable-frame__inner.is-resizing){cursor:col-resize;user-select:none;-webkit-user-select:none}.edit-site-resizable-frame__inner.is-resizing:before{content:"";inset:0;position:absolute;z-index:1}.edit-site-resizable-frame__inner-content{inset:0;position:absolute;z-index:0}.edit-site-resizable-frame__handle{align-items:center;background-color:#75757566;border:0;border-radius:4px;cursor:col-resize;display:flex;height:64px;justify-content:flex-end;padding:0;position:absolute;top:calc(50% - 32px);width:4px;z-index:100}.edit-site-resizable-frame__handle:before{content:"";height:100%;position:absolute;right:100%;width:32px}.edit-site-resizable-frame__handle:after{content:"";height:100%;left:100%;position:absolute;width:32px}.edit-site-resizable-frame__handle:focus-visible{outline:2px solid #0000}.edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{background-color:var(--wp-admin-theme-color)}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}#adminmenumain,#wpadminbar{display:none}#wpcontent{margin-right:0}body.js #wpbody{padding-top:0}body{background:#fff}body #wpcontent{padding-right:0}body #wpbody-content{padding-bottom:0}body #wpbody-content>div:not(#gutenberg-posts-dashboard):not(#screen-meta),body #wpfooter{display:none}body .a11y-speak-region{right:-1px;top:-1px}body ul#adminmenu a.wp-has-current-submenu:after,body ul#adminmenu>li.current>a.current:after{border-left-color:#fff}body .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}#gutenberg-posts-dashboard{box-sizing:border-box;height:100vh}#gutenberg-posts-dashboard *,#gutenberg-posts-dashboard :after,#gutenberg-posts-dashboard :before{box-sizing:inherit}@media (min-width:600px){#gutenberg-posts-dashboard{bottom:0;left:0;min-height:100vh;position:fixed;right:0;top:0}}.no-js #gutenberg-posts-dashboard{min-height:0;position:static}#gutenberg-posts-dashboard .components-editor-notices__snackbar{bottom:16px;left:0;padding-left:16px;padding-right:16px;position:fixed}@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.dataviews-wrapper{box-sizing:border-box;container:dataviews-wrapper/inline-size;display:flex;flex-direction:column;font-size:13px;height:100%;line-height:1.4;overflow:auto;scroll-padding-bottom:64px}.dataviews-filters__container,.dataviews__view-actions{box-sizing:border-box;flex-shrink:0;left:0;padding:16px 48px;position:sticky}@media not (prefers-reduced-motion){.dataviews-filters__container,.dataviews__view-actions{transition:padding .1s ease-out}}.dataviews-loading,.dataviews-no-results{align-items:center;display:flex;flex-grow:1;justify-content:center;padding:0 48px}@media not (prefers-reduced-motion){.dataviews-loading,.dataviews-no-results{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-filters__container,.dataviews__view-actions{padding:12px 24px}.dataviews-loading,.dataviews-no-results{padding-left:24px;padding-right:24px}}.dataviews-title-field{font-size:13px;font-weight:500;width:100%}.dataviews-title-field,.dataviews-title-field a{color:#2f2f2f;text-overflow:ellipsis;white-space:nowrap}.dataviews-title-field a{display:block;flex-grow:0;overflow:hidden;text-decoration:none}.dataviews-title-field a:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field a:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-title-field button.components-button.is-link{color:#1e1e1e;display:block;font-weight:inherit;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.dataviews-title-field button.components-button.is-link:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable{color:#2f2f2f;cursor:pointer}.dataviews-title-field--clickable:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-bulk-actions-footer__item-count{color:#1e1e1e;font-size:11px;font-weight:500;text-transform:uppercase}.dataviews-bulk-actions-footer__container{margin-right:auto;min-height:32px}.dataviews-filters__button{position:relative}.dataviews-filters__container{padding-top:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{opacity:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{opacity:1}.dataviews-filters__summary-popover{font-size:13px;line-height:1.4}.dataviews-filters__summary-popover .components-popover__content{border-radius:4px;width:230px}.dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{padding:0}.dataviews-filters__summary-operators-container{padding:8px 8px 0}.dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){border-bottom:1px solid #e0e0e0;padding-bottom:8px}.dataviews-filters__summary-operators-container:empty{display:none}.dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{color:#757575}.dataviews-filters__summary-chip-container{position:relative;white-space:pre-wrap}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{align-items:center;background:#f0f0f0;border:1px solid #0000;border-radius:16px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;min-height:32px;padding:4px 12px;position:relative}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{padding-inline-end:28px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{background:#e0e0e0;color:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{background:rgba(var(--wp-admin-theme-color--rgb),.04);color:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{background:rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{font-weight:500}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{align-items:center;background:#0000;border:0;border-radius:50%;cursor:pointer;display:flex;height:24px;justify-content:center;padding:0;position:absolute;right:4px;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{fill:#757575}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{background:#e0e0e0}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{fill:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{fill:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{background:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__search-widget-filter-combobox-list{border-top:1px solid #e0e0e0;max-height:184px;overflow:auto;padding:4px}.dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{font-weight:600}.dataviews-filters__search-widget-listbox{overflow:auto;padding:4px}.dataviews-filters__search-widget-listitem{align-items:center;border-radius:2px;box-sizing:border-box;cursor:default;display:flex;gap:8px;margin-block-end:2px;padding:8px 12px}.dataviews-filters__search-widget-listitem:last-child{margin-block-end:0}.dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{background-color:var(--wp-admin-theme-color);color:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{fill:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{color:#fff}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{flex-shrink:0;height:24px;width:24px}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{color:#757575;display:block;font-size:12px;line-height:16px;overflow:hidden;text-overflow:ellipsis}.dataviews-filters__search-widget-filter-combobox__wrapper{padding:8px;position:relative}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{background:#f0f0f0;border:none;border-radius:2px;box-shadow:0 0 0 #0000;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin-left:0;margin-right:0;padding:0 32px 0 8px;width:100%}@media not (prefers-reduced-motion){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{transition:box-shadow .1s linear}}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px;line-height:normal}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{background:#fff;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{color:#757575}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{-webkit-appearance:none}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{align-items:center;display:flex;justify-content:center;position:absolute;right:12px;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__container-visibility-toggle{flex-shrink:0;position:relative}.dataviews-filters-toggle__count{background:var(--wp-admin-theme-color,#3858e9);border-radius:8px;box-sizing:border-box;color:#fff;font-size:11px;height:16px;line-height:16px;min-width:16px;outline:var(--wp-admin-border-width-focus) solid #fff;padding:0 4px;position:absolute;right:0;text-align:center;top:0;transform:translate(50%,-50%)}.dataviews-search{width:fit-content}.dataviews-footer{background-color:#fff;border-top:1px solid #f0f0f0;bottom:0;flex-shrink:0;left:0;padding:12px 48px;position:sticky;z-index:2}@media not (prefers-reduced-motion){.dataviews-footer{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-footer{padding:12px 24px}}@container (max-width: 560px){.dataviews-footer{flex-direction:column!important}.dataviews-footer .dataviews-bulk-actions-footer__container{width:100%}.dataviews-footer .dataviews-bulk-actions-footer__item-count{flex-grow:1}.dataviews-footer .dataviews-pagination{justify-content:space-between;width:100%}}.dataviews-pagination__page-select{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.dataviews-pagination__page-select .components-select-control__input{font-size:11px!important;font-weight:500}}.dataviews-action-modal{z-index:1000001}.dataviews-selection-checkbox{--checkbox-input-size:24px;flex-shrink:0;line-height:0}@media (min-width:600px){.dataviews-selection-checkbox{--checkbox-input-size:16px}}.dataviews-selection-checkbox .components-checkbox-control__input-container{margin:0}.dataviews-view-config{container-type:inline-size;font-size:13px;line-height:1.4;width:320px}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{height:100%;overflow-y:scroll}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{width:auto}.dataviews-view-config__sort-direction .components-toggle-group-control-option-base{text-transform:uppercase}.dataviews-settings-section__title.dataviews-settings-section__title{font-size:15px;line-height:24px}.dataviews-settings-section__sidebar{grid-column:span 4}.dataviews-settings-section__content,.dataviews-settings-section__content>*{grid-column:span 8}.dataviews-settings-section__content .is-divided-in-two{display:contents}.dataviews-settings-section__content .is-divided-in-two>*{grid-column:span 4}.dataviews-settings-section:has(.dataviews-settings-section__content:empty){display:none}@container (max-width: 500px){.dataviews-settings-section.dataviews-settings-section{grid-template-columns:repeat(2,1fr)}.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{grid-column:span 2}}.dataviews-field-control__field{height:32px}.dataviews-field-control__actions{position:absolute;top:-9999em}.dataviews-field-control__actions.dataviews-field-control__actions{gap:4px}.dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{position:unset;top:unset}.dataviews-field-control__icon{display:flex;width:24px}.dataviews-field-control__label-sub-label-container{flex-grow:1}.dataviews-field-control__label{display:block}.dataviews-field-control__sub-label{color:#757575;font-size:11px;font-style:normal;margin-bottom:0;margin-top:8px}.dataviews-view-grid{container-type:inline-size;grid-template-rows:max-content;margin-bottom:auto;padding:0 48px 24px}@media not (prefers-reduced-motion){.dataviews-view-grid{transition:padding .1s ease-out}}.dataviews-view-grid .dataviews-view-grid__card{height:100%;justify-content:flex-start;position:relative}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{padding:8px 0 4px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{align-items:center;display:flex;min-height:24px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{width:fit-content}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{color:#1e1e1e}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__media{aspect-ratio:1/1;background-color:#f0f0f0;border-radius:4px;min-height:200px;position:relative;width:100%}.dataviews-view-grid .dataviews-view-grid__media img{height:100%;object-fit:cover;width:100%}.dataviews-view-grid .dataviews-view-grid__media:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%}.dataviews-view-grid .dataviews-view-grid__fields{font-size:12px;line-height:16px;position:relative}.dataviews-view-grid .dataviews-view-grid__fields:not(:empty){padding:0 0 12px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){line-height:20px;min-height:24px;padding-top:2px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{align-items:center;min-height:24px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{color:#757575;width:35%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:65%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){display:none}.dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){padding-bottom:12px}@container (max-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(1,minmax(0,1fr));padding-left:24px;padding-right:24px}}@container (min-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (min-width: 780px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 1140px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@container (min-width: 1520px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{display:none}.dataviews-view-grid__card .dataviews-selection-checkbox{left:8px;position:absolute;top:-9999em;z-index:1}.dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{top:8px}.dataviews-view-grid__media--clickable{cursor:pointer}div.dataviews-view-list{list-style-type:none}.dataviews-view-list{margin:0 0 auto}.dataviews-view-list div[role=row]{border-top:1px solid #f0f0f0;margin:0}.dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{box-sizing:border-box;padding:16px 24px;position:relative}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions{flex:0;overflow:hidden}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{height:24px}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{opacity:0;position:relative;z-index:1}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{flex-basis:min-content;overflow:unset;padding-inline-end:4px}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{opacity:1}.dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{color:#1e1e1e}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{background-color:#f8f8f8;color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#1e1e1e}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list .dataviews-view-list__item{appearance:none;background:none;border:none;cursor:pointer;inset:0;padding:0;position:absolute;scroll-margin:8px 0;z-index:1}.dataviews-view-list .dataviews-view-list__item:focus-visible{outline:none}.dataviews-view-list .dataviews-view-list__item:focus-visible:before{border-radius:2px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.dataviews-view-list .dataviews-view-list__title-field{flex:1;line-height:24px;min-height:24px;overflow:hidden}.dataviews-view-list .dataviews-view-list__title-field:has(a,button){z-index:1}.dataviews-view-list .dataviews-view-list__media-wrapper{background-color:#f0f0f0;border-radius:4px;flex-shrink:0;height:52px;overflow:hidden;position:relative;width:52px}.dataviews-view-list .dataviews-view-list__media-wrapper img{height:100%;object-fit:cover;width:100%}.dataviews-view-list .dataviews-view-list__media-wrapper:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;position:absolute;top:0;width:100%}.dataviews-view-list .dataviews-view-list__field-wrapper{flex-grow:1;min-height:52px}.dataviews-view-list .dataviews-view-list__fields{color:#757575;display:flex;flex-wrap:wrap;font-size:12px;gap:12px;row-gap:4px}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{display:none}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{align-items:center;display:flex;line-height:20px;min-height:24px}.dataviews-view-list+.dataviews-pagination{justify-content:space-between}.dataviews-view-table{border-collapse:collapse;border-color:inherit;color:#757575;margin-bottom:auto;position:relative;text-indent:0;width:100%}.dataviews-view-table th{color:#1e1e1e;font-size:13px;font-weight:400;text-align:left}.dataviews-view-table td,.dataviews-view-table th{padding:12px;white-space:nowrap}.dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{text-align:right}.dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{padding-right:0;width:1%}.dataviews-view-table tr{border-top:1px solid #f0f0f0}.dataviews-view-table tr .dataviews-view-table-header-button{gap:4px}.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-left:48px}.dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{margin-left:-8px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-right:48px}.dataviews-view-table tr:last-child{border-bottom:0}.dataviews-view-table tr.is-hovered{background-color:#f8f8f8}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{opacity:0}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{opacity:1}.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:0}.dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}@media (hover:none){.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}}.dataviews-view-table tr.is-selected{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#757575}.dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-table tr.is-selected:hover{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-table thead{inset-block-start:0;position:sticky;z-index:1}.dataviews-view-table thead tr{border:0}.dataviews-view-table thead th{background-color:#fff;font-size:11px;font-weight:500;padding-bottom:8px;padding-left:12px;padding-top:8px;text-transform:uppercase}.dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-left:4px}.dataviews-view-table tbody td{vertical-align:top}.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{align-items:center;display:flex;min-height:32px}.dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){min-height:0}.dataviews-view-table .dataviews-view-table-header-button{font-size:11px;font-weight:500;padding:4px 8px;text-transform:uppercase}.dataviews-view-table .dataviews-view-table-header-button:not(:hover){color:#1e1e1e}.dataviews-view-table .dataviews-view-table-header-button span{speak:none}.dataviews-view-table .dataviews-view-table-header-button span:empty{display:none}.dataviews-view-table .dataviews-view-table-header{padding-left:4px}.dataviews-view-table .dataviews-view-table__actions-column{width:1%}.dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{opacity:1}.dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-left:0}.dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{padding:4px 8px}.dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{padding:16px 12px}.dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{padding-right:0}@container (max-width: 430px){.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-left:24px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-right:24px}}.dataviews-view-table-selection-checkbox{--checkbox-input-size:24px}@media (min-width:600px){.dataviews-view-table-selection-checkbox{--checkbox-input-size:16px}}.dataviews-column-primary__media{max-width:60px}.dataviews-controls__datetime{border:none;padding:0}.dataforms-layouts-panel__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-panel__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-panel__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.dataforms-layouts-panel__field-control .components-button{max-width:100%;min-height:32px;text-align:left;text-wrap:balance;text-wrap:pretty;white-space:normal}.dataforms-layouts-panel__field-control .components-dropdown{max-width:100%}.dataforms-layouts-panel__field-dropdown .components-popover__content{min-width:320px;padding:16px}.dataforms-layouts-panel__dropdown-header{margin-bottom:16px}.components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{z-index:159990}.dataforms-layouts-regular__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-regular__field .components-base-control__label{font-size:inherit;font-weight:400;text-transform:none}.dataforms-layouts-regular__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-regular__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.fields-create-template-part-modal{z-index:1000001}.fields-create-template-part-modal__area-radio-group{border:1px solid #949494;border-radius:2px}.fields-create-template-part-modal__area-radio-wrapper{align-items:center;display:grid;grid-template-columns:min-content 1fr min-content;padding:12px;position:relative;grid-gap:4px 8px;color:#1e1e1e}.fields-create-template-part-modal__area-radio-wrapper+.fields-create-template-part-modal__area-radio-wrapper{border-top:1px solid #949494}.fields-create-template-part-modal__area-radio-wrapper input[type=radio]{opacity:0;position:absolute}.fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:checked){z-index:1}.fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:not(:checked)):hover{color:var(--wp-admin-theme-color)}.fields-create-template-part-modal__area-radio-wrapper>:not(.fields-create-template-part-modal__area-radio-label){pointer-events:none}.fields-create-template-part-modal__area-radio-label:before{content:"";inset:0;position:absolute}input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-label:before{cursor:pointer}input[type=radio]:focus-visible~.fields-create-template-part-modal__area-radio-label:before{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:4px solid #0000}.fields-create-template-part-modal__area-radio-checkmark,.fields-create-template-part-modal__area-radio-icon{fill:currentColor}input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-checkmark{opacity:0}.fields-create-template-part-modal__area-radio-description{color:#757575;font-size:12px;grid-column:2/3;line-height:normal;margin:0;text-wrap:pretty}input[type=radio]:not(:checked):hover~.fields-create-template-part-modal__area-radio-description{color:inherit}.fields-controls__slug .fields-controls__slug-external-icon{margin-left:5ch}.fields-controls__slug .fields-controls__slug-input input.components-input-control__input{padding-inline-start:0!important}.fields-controls__slug .fields-controls__slug-help-link{word-break:break-word}.fields-controls__slug .fields-controls__slug-help{display:flex;flex-direction:column}.fields-controls__slug .fields-controls__slug-help .fields-controls__slug-help-slug{font-weight:600}.fields-controls__featured-image-placeholder{background:#fff linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);border-radius:2px;box-shadow:inset 0 0 0 1px #0003;display:inline-block;padding:0}.fields-controls__featured-image-title{color:#1e1e1e;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.fields-controls__featured-image-image{align-self:center;border-radius:2px;height:100%;width:100%}.fields-controls__featured-image-container .fields-controls__featured-image-placeholder{margin:0}.fields-controls__featured-image-container span{margin-right:auto}fieldset.fields-controls__featured-image .fields-controls__featured-image-container{border:1px solid #ddd;border-radius:2px;cursor:pointer;padding:8px 12px}fieldset.fields-controls__featured-image .fields-controls__featured-image-container:hover{background-color:#f0f0f0}fieldset.fields-controls__featured-image .fields-controls__featured-image-placeholder{height:24px;width:24px}fieldset.fields-controls__featured-image span{align-self:center;text-align:start;white-space:nowrap}fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button{height:fit-content;padding:0}fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:focus,fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:hover{border:0;color:unset}fieldset.fields-controls__featured-image .fields-controls__featured-image-remove-button{place-self:end}.dataforms-layouts-panel__field-control .fields-controls__featured-image-image,.dataforms-layouts-panel__field-control .fields-controls__featured-image-placeholder{height:16px;width:16px}.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-image,.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-placeholder{display:block;height:32px;width:32px}.fields-controls__template-modal{z-index:1000001}.fields-controls__template-content .block-editor-block-patterns-list{column-count:2;column-gap:24px;padding-top:2px}@media (min-width:782px){.fields-controls__template-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.fields-controls__template-content .block-editor-block-patterns-list{column-count:4}}.fields-controls__template-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.fields-field__title span:first-child{display:block;flex-grow:0;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.fields-field__pattern-title span:first-child{flex:1}.edit-site-custom-template-modal__contents-wrapper{height:100%;justify-content:flex-start!important}.edit-site-custom-template-modal__contents-wrapper>*{width:100%}.edit-site-custom-template-modal__contents-wrapper__suggestions_list{margin-left:-12px;margin-right:-12px;width:calc(100% + 24px)}.edit-site-custom-template-modal__contents>.components-button{height:auto;justify-content:center}@media (min-width:782px){.edit-site-custom-template-modal{width:456px}}@media (min-width:600px){.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list{max-height:224px;overflow-y:auto}}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item{display:block;height:auto;overflow-wrap:break-word;padding:8px 12px;text-align:left;white-space:pre-wrap;width:100%}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item mark{background:none;font-weight:700}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover *,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover mark{color:var(--wp-admin-theme-color)}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus{background-color:#f0f0f0}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color) inset}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__title{display:block;overflow:hidden;text-overflow:ellipsis}.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info{color:#757575;word-break:break-all}.edit-site-custom-template-modal__no-results{border:1px solid #ccc;border-radius:2px;padding:16px}.edit-site-custom-generic-template__modal .components-modal__header{border-bottom:none}.edit-site-custom-generic-template__modal .components-modal__content:before{margin-bottom:4px}@media (min-width:960px){.edit-site-add-new-template__modal{margin-top:64px;max-height:calc(100% - 128px);max-width:832px;width:calc(100% - 128px)}}.edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button svg,.edit-site-add-new-template__modal .edit-site-add-new-template__template-button svg{fill:var(--wp-admin-theme-color)}.edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button .edit-site-add-new-template__template-name{align-items:flex-start;flex-grow:1}.edit-site-add-new-template__modal .edit-site-add-new-template__template-icon{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:100%;max-height:40px;max-width:40px;padding:8px}.edit-site-add-new-template__template-list__contents>.components-button,.edit-site-custom-template-modal__contents>.components-button{border:1px solid #ddd;display:flex;flex-direction:column;justify-content:center;outline:1px solid #0000;padding:32px}.edit-site-add-new-template__template-list__contents>.components-button span:first-child,.edit-site-custom-template-modal__contents>.components-button span:first-child{color:#1e1e1e}.edit-site-add-new-template__template-list__contents>.components-button span,.edit-site-custom-template-modal__contents>.components-button span{color:#757575}.edit-site-add-new-template__template-list__contents>.components-button:hover,.edit-site-custom-template-modal__contents>.components-button:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-color:#0000;color:var(--wp-admin-theme-color-darker-10)}.edit-site-add-new-template__template-list__contents>.components-button:hover span,.edit-site-custom-template-modal__contents>.components-button:hover span{color:var(--wp-admin-theme-color)}.edit-site-add-new-template__template-list__contents>.components-button:focus,.edit-site-custom-template-modal__contents>.components-button:focus{border-color:#0000;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:3px solid #0000}.edit-site-add-new-template__template-list__contents>.components-button:focus span:first-child,.edit-site-custom-template-modal__contents>.components-button:focus span:first-child{color:var(--wp-admin-theme-color)}.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__custom-template-button,.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__template-list__prompt,.edit-site-custom-template-modal__contents .edit-site-add-new-template__custom-template-button,.edit-site-custom-template-modal__contents .edit-site-add-new-template__template-list__prompt{grid-column:1/-1}.edit-site-add-new-template__template-list__contents>.components-button{align-items:flex-start;height:100%;text-align:start}.edit-site-visual-editor__editor-canvas.is-focused{outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-2)}.edit-site-canvas-loader{align-items:center;display:flex;height:100%;justify-content:center;left:0;opacity:0;position:absolute;top:0;width:100%}@media not (prefers-reduced-motion){.edit-site-canvas-loader{animation:edit-site-canvas-loader__fade-in-animation .5s ease .2s;animation-fill-mode:forwards}}.edit-site-canvas-loader>div{width:160px}@keyframes edit-site-canvas-loader__fade-in-animation{0%{opacity:0}to{opacity:1}}.edit-site-global-styles-preview{align-items:center;cursor:pointer;display:flex;justify-content:center;line-height:1}.edit-site-global-styles-preview__wrapper{display:block;max-width:100%;width:100%}.edit-site-typography-preview{align-items:center;background:#f0f0f0;border-radius:2px;display:flex;justify-content:center;margin-bottom:16px;min-height:100px;overflow:hidden}.edit-site-font-size__item{line-break:anywhere;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.edit-site-font-size__item-value{color:#757575}.edit-site-global-styles-screen{margin:12px 16px 16px}.edit-site-global-styles-screen-typography__indicator{align-items:center;border-radius:1px;display:flex!important;font-size:14px;height:24px;justify-content:center;width:24px}.edit-site-global-styles-screen-typography__font-variants-count{color:#757575}.edit-site-global-styles-font-families__manage-fonts{justify-content:center}.edit-site-global-styles-screen .color-block-support-panel{border-top:none;padding-left:0;padding-right:0;padding-top:0;row-gap:12px}.edit-site-global-styles-header__description{padding:0 16px}.edit-site-block-types-search{margin-bottom:8px;padding:0 16px}.edit-site-global-styles-header{margin-bottom:0!important}.edit-site-global-styles-subtitle{font-size:11px!important;font-weight:500!important;margin-bottom:0!important;text-transform:uppercase}.edit-site-global-styles-section-title{color:#2f2f2f;font-weight:600;line-height:1.2;margin:0;padding:16px 16px 0}.edit-site-global-styles-icon-with-current-color{fill:currentColor}.edit-site-global-styles__color-indicator-wrapper{flex-shrink:0;height:24px}.edit-site-global-styles__shadows-panel__options-container,.edit-site-global-styles__shadows-panel__title{height:24px}.edit-site-global-styles__block-preview-panel{border:1px solid #e0e0e0;border-radius:4px;overflow:hidden;position:relative;width:100%}.edit-site-global-styles__shadow-preview-panel{background-image:repeating-linear-gradient(45deg,#f5f5f5 25%,#0000 0,#0000 75%,#f5f5f5 0,#f5f5f5),repeating-linear-gradient(45deg,#f5f5f5 25%,#0000 0,#0000 75%,#f5f5f5 0,#f5f5f5);background-position:0 0,8px 8px;background-size:16px 16px;border:1px solid #e0e0e0;border-radius:4px;height:144px;overflow:auto}.edit-site-global-styles__shadow-preview-panel .edit-site-global-styles__shadow-preview-block{background-color:#fff;border:1px solid #e0e0e0;border-radius:2px;height:60px;width:60%}.edit-site-global-styles__shadow-editor__dropdown-content{width:280px}.edit-site-global-styles__shadow-editor-panel{margin-bottom:4px}.edit-site-global-styles__shadow-editor__dropdown{position:relative;width:100%}.edit-site-global-styles__shadow-editor__dropdown-toggle{border-radius:inherit;height:auto;padding-bottom:8px;padding-top:8px;text-align:left;width:100%}.edit-site-global-styles__shadow-editor__dropdown-toggle.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.edit-site-global-styles__shadow-editor__remove-button{opacity:0;position:absolute;right:8px;top:8px}.edit-site-global-styles__shadow-editor__remove-button.edit-site-global-styles__shadow-editor__remove-button{border:none}.edit-site-global-styles__shadow-editor__dropdown-toggle:hover+.edit-site-global-styles__shadow-editor__remove-button,.edit-site-global-styles__shadow-editor__remove-button:focus,.edit-site-global-styles__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.edit-site-global-styles__shadow-editor__remove-button{opacity:1}}.edit-site-global-styles-screen-css{display:flex;flex:1 1 auto;flex-direction:column;margin:16px}.edit-site-global-styles-screen-css .components-v-stack{flex:1 1 auto}.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input,.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{display:flex;flex:1 1 auto;flex-direction:column}.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field .components-textarea-control__input{direction:ltr;flex:1 1 auto}.edit-site-global-styles-screen-css-help-link{display:inline-block;margin-top:8px}.edit-site-global-styles-screen-variations{border-top:1px solid #ddd;margin-top:16px}.edit-site-global-styles-screen-variations>*{margin:24px 16px}.edit-site-global-styles-sidebar__navigator-provider{height:100%}.edit-site-global-styles-sidebar__navigator-screen{display:flex;flex-direction:column;height:100%}.edit-site-global-styles-sidebar__navigator-screen .single-column{grid-column:span 1}.edit-site-global-styles-screen-root.edit-site-global-styles-screen-root,.edit-site-global-styles-screen-style-variations.edit-site-global-styles-screen-style-variations{background:unset;color:inherit}.edit-site-global-styles-sidebar__panel .block-editor-block-icon svg{fill:currentColor}.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile,.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile .edit-site-global-styles-screen-root__active-style-tile-preview{border-radius:2px}.edit-site-global-styles-screen-revisions__revisions-list{flex-grow:1;list-style:none;margin:0 16px 16px}.edit-site-global-styles-screen-revisions__revisions-list li{margin-bottom:0}.edit-site-global-styles-screen-revisions__revision-item{cursor:pointer;display:flex;flex-direction:column;position:relative}.edit-site-global-styles-screen-revisions__revision-item[role=option]:active,.edit-site-global-styles-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 #0000}.edit-site-global-styles-screen-revisions__revision-item:hover{background:rgba(var(--wp-admin-theme-color--rgb),.04)}.edit-site-global-styles-screen-revisions__revision-item:hover .edit-site-global-styles-screen-revisions__date{color:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item:after,.edit-site-global-styles-screen-revisions__revision-item:before{content:"\a";display:block;position:absolute}.edit-site-global-styles-screen-revisions__revision-item:before{background:#ddd;border:4px solid #0000;border-radius:50%;height:8px;left:17px;top:18px;transform:translate(-50%,-50%);width:8px;z-index:1}.edit-site-global-styles-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 #0000;outline-offset:-2px}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__date{color:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true]:before{background:var(--wp-admin-theme-color)}.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__changes>li,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__meta{color:#1e1e1e}.edit-site-global-styles-screen-revisions__revision-item:after{border:.5px solid #ddd;height:100%;left:16px;top:0;width:0}.edit-site-global-styles-screen-revisions__revision-item:first-child:after{top:18px}.edit-site-global-styles-screen-revisions__revision-item:last-child:after{height:18px}.edit-site-global-styles-screen-revisions__revision-item-wrapper{display:block;padding:12px 12px 4px 40px}.edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__apply-button.is-primary{align-self:flex-start;margin:4px 12px 12px 40px}.edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__changes,.edit-site-global-styles-screen-revisions__meta{color:#757575;font-size:12px}.edit-site-global-styles-screen-revisions__description{align-items:flex-start;display:flex;flex-direction:column;gap:8px}.edit-site-global-styles-screen-revisions__description .edit-site-global-styles-screen-revisions__date{font-size:12px;font-weight:600;text-transform:uppercase}.edit-site-global-styles-screen-revisions__meta{align-items:flex-start;display:flex;justify-content:start;margin-bottom:4px;text-align:left;width:100%}.edit-site-global-styles-screen-revisions__meta img{border-radius:100%;height:16px;margin-right:8px;width:16px}.edit-site-global-styles-screen-revisions__loading{margin:24px auto!important}.edit-site-global-styles-screen-revisions__changes{line-height:1.4;list-style:disc;margin-left:12px;text-align:left}.edit-site-global-styles-screen-revisions__changes li{margin-bottom:4px}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination{gap:2px;justify-content:space-between}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .edit-site-pagination__total{height:1px;left:-1000px;margin:-1px;overflow:hidden;position:absolute}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-text{font-size:12px;will-change:opacity}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary{color:#1e1e1e}.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary:disabled,.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{color:#949494}.edit-site-global-styles-screen-revisions__footer{background:#fff;border-top:1px solid #ddd;bottom:0;height:56px;min-width:100%;padding:12px;position:sticky;z-index:1}.editor-sidebar{width:280px}.editor-sidebar>.components-panel{border-left:0;border-right:0;margin-bottom:-1px;margin-top:-1px}.editor-sidebar>.components-panel>.components-panel__header{background:#f0f0f0}.editor-sidebar .block-editor-block-inspector__card{margin:0}.edit-site-global-styles-sidebar{display:flex;flex-direction:column;min-height:100%}.edit-site-global-styles-sidebar__panel{flex:1}.edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-title{margin:0}.edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-actions{flex:1}.edit-site-global-styles-sidebar .components-navigation__menu-title-heading{font-size:15.6px;font-weight:500}.edit-site-global-styles-sidebar .components-navigation__item>button span{font-weight:500}.edit-site-global-styles-sidebar .block-editor-panel-color-gradient-settings{border:0}.edit-site-global-styles-sidebar .single-column{grid-column:span 1}.edit-site-global-styles-sidebar .components-tools-panel .span-columns{grid-column:1/-1}.edit-site-global-styles-sidebar__blocks-group{border-top:1px solid #e0e0e0;padding-top:24px}.edit-site-global-styles-sidebar__blocks-group-help{padding:0 16px}.edit-site-global-styles-color-palette-panel,.edit-site-global-styles-gradient-palette-panel{padding:16px}.edit-site-global-styles-sidebar hr{margin:0}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon{width:auto}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon svg{display:none}.show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon:after{content:attr(aria-label);font-size:12px}.edit-site-page{background:#fff;color:#2f2f2f;container:edit-site-page/inline-size;height:100%}@media not (prefers-reduced-motion){.edit-site-page{transition:width .2s ease-out}}.edit-site-page-header{background:#fff;border-bottom:1px solid #f0f0f0;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-page-header{transition:padding .1s ease-out}}.edit-site-page-header .components-heading{color:#1e1e1e}.edit-site-page-header .edit-site-page-header__page-title{min-height:40px}.edit-site-page-header .edit-site-page-header__page-title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-page-header .edit-site-page-header__sub-title{margin-bottom:8px}@container (max-width: 430px){.edit-site-page-header{padding:16px 24px}}.edit-site-page-content{display:flex;flex-flow:column;height:100%;position:relative;z-index:1}.edit-site-patterns__delete-modal{width:384px}.page-patterns-preview-field{align-items:center;border-radius:4px;display:flex;flex-direction:column;height:100%;justify-content:center}.dataviews-view-grid .page-patterns-preview-field .block-editor-block-preview__container{height:100%}.dataviews-view-table .page-patterns-preview-field{flex-grow:0;text-wrap:balance;text-wrap:pretty;width:96px}.edit-site-patterns__pattern-icon{fill:var(--wp-block-synced-color);flex-shrink:0}.edit-site-patterns__section-header{border-bottom:1px solid #f0f0f0;flex-shrink:0;min-height:40px;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-patterns__section-header{transition:padding .1s ease-out}}.edit-site-patterns__section-header .edit-site-patterns__title{min-height:40px}.edit-site-patterns__section-header .edit-site-patterns__title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-patterns__section-header .edit-site-patterns__sub-title{margin-bottom:8px}.edit-site-patterns__section-header .screen-reader-shortcut:focus{top:0}.edit-site-page-patterns-dataviews .dataviews-view-grid__badge-fields .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully){background:rgba(var(--wp-block-synced-color--rgb),.04);color:var(--wp-block-synced-color)}.dataviews-action-modal__duplicate-pattern [role=dialog]>[role=document]{width:350px}.dataviews-action-modal__duplicate-pattern .patterns-menu-items__convert-modal-categories{position:relative}.dataviews-action-modal__duplicate-pattern .components-form-token-field__suggestions-list:not(:empty){background-color:#fff;border:1px solid var(--wp-admin-theme-color);border-bottom-left-radius:2px;border-bottom-right-radius:2px;box-shadow:0 0 .5px .5px var(--wp-admin-theme-color);box-sizing:border-box;left:-1px;max-height:96px;min-width:auto;position:absolute;width:calc(100% + 2px);z-index:1}@media (min-width:600px){.dataviews-action-modal__duplicate-template-part .components-modal__frame{max-width:500px}}@container (max-width: 430px){.edit-site-page-patterns-dataviews .edit-site-patterns__section-header{padding-left:24px;padding-right:24px}}.page-templates-preview-field{align-items:center;border-radius:4px;display:flex;flex-direction:column;height:100%;justify-content:center;width:100%}.dataviews-view-list .page-templates-preview-field .block-editor-block-preview__container{height:120px}.dataviews-view-grid .page-templates-preview-field .block-editor-block-preview__container{height:100%}.dataviews-view-table .page-templates-preview-field{max-height:160px;position:relative;text-wrap:balance;text-wrap:pretty;width:120px}.dataviews-view-table .page-templates-preview-field:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;position:absolute;top:0;width:100%}.page-templates-description{max-width:50em;text-wrap:balance;text-wrap:pretty}.dataviews-view-table .page-templates-description{display:block;margin-bottom:8px}.edit-site-page-templates .dataviews-pagination{z-index:2}.page-templates-author-field__avatar{align-items:center;display:flex;flex-shrink:0;height:24px;justify-content:left;overflow:hidden;width:24px}.page-templates-author-field__avatar img{border-radius:100%;height:16px;object-fit:cover;opacity:0;width:16px}@media not (prefers-reduced-motion){.page-templates-author-field__avatar img{transition:opacity .1s linear}}.page-templates-author-field__avatar.is-loaded img{opacity:1}.page-templates-author-field__icon{display:flex;flex-shrink:0;height:24px;width:24px}.page-templates-author-field__icon svg{margin-left:-4px;fill:currentColor}.page-templates-author-field__name{overflow:hidden;text-overflow:ellipsis}.edit-site-list__rename-modal{z-index:1000001}@media (min-width:782px){.edit-site-list__rename-modal .components-base-control{width:320px}}.edit-site-editor__editor-interface{opacity:1}@media not (prefers-reduced-motion){.edit-site-editor__editor-interface{transition:opacity .1s ease-out}}.edit-site-editor__editor-interface.is-loading{opacity:0}.edit-site-editor__toggle-save-panel{background-color:#fff;border:1px dotted #ddd;box-sizing:border-box;display:flex;justify-content:center;padding:24px;width:280px}.edit-site-editor__view-mode-toggle{view-transition-name:toggle;height:60px;left:0;top:0;width:60px;z-index:100}.edit-site-editor__view-mode-toggle .components-button{align-items:center;border-radius:0;color:#fff;display:flex;height:100%;justify-content:center;overflow:hidden;padding:0;width:100%}.edit-site-editor__view-mode-toggle .components-button:active,.edit-site-editor__view-mode-toggle .components-button:hover{color:#fff}.edit-site-editor__view-mode-toggle .components-button:focus{box-shadow:none}.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon img,.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon svg{background:#1e1e1e;display:block}.edit-site-editor__back-icon{align-items:center;background-color:#ccc;display:flex;height:60px;justify-content:center;left:0;pointer-events:none;position:absolute;top:0;width:60px}.edit-site-editor__back-icon svg{fill:currentColor}.edit-site-editor__back-icon.has-site-icon{-webkit-backdrop-filter:saturate(180%) blur(15px);backdrop-filter:saturate(180%) blur(15px);background-color:#fff9}.edit-site-welcome-guide{width:312px}.edit-site-welcome-guide.guide-editor .edit-site-welcome-guide__image,.edit-site-welcome-guide.guide-styles .edit-site-welcome-guide__image{background:#00a0d2}.edit-site-welcome-guide.guide-page .edit-site-welcome-guide__video{border-right:16px solid #3858e9;border-top:16px solid #3858e9}.edit-site-welcome-guide.guide-template .edit-site-welcome-guide__video{border-left:16px solid #3858e9;border-top:16px solid #3858e9}.edit-site-welcome-guide__image{margin:0 0 16px}.edit-site-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-site-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-site-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 16px;padding:0 32px}.edit-site-welcome-guide__text img{vertical-align:bottom}.edit-site-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-site-layout{color:#ccc;display:flex;flex-direction:column;height:100%}.edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{background:#1e1e1e}.edit-site-layout__content{display:flex;flex-grow:1;height:100%}.edit-site-layout__sidebar-region{flex-shrink:0;width:100vw;z-index:1}@media (min-width:782px){.edit-site-layout__sidebar-region{width:300px}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{height:100vh;left:0;position:fixed!important;top:0}.edit-site-layout__sidebar-region .edit-site-layout__sidebar{display:flex;flex-direction:column;height:100%}.edit-site-layout__sidebar-region .resizable-editor__drag-handle{right:0}.edit-site-layout__main{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.edit-site-layout__mobile{display:flex;flex-direction:column;position:relative;width:100%;z-index:2}.edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{padding:0}.edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{padding:0 12px}.edit-site-layout__canvas-container{flex-grow:1;overflow:visible;position:relative;z-index:2}.edit-site-layout__canvas-container.is-resizing:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:100}.edit-site-layout__canvas{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;top:0;width:100%}.edit-site-layout__canvas.is-right-aligned{justify-content:flex-end}.edit-site-layout__canvas .edit-site-resizable-frame__inner{color:#1e1e1e}@media (min-width:782px){.edit-site-layout__canvas{bottom:16px;top:16px;width:calc(100% - 16px)}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;overflow:hidden}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{transition:border-radius,box-shadow .4s}}@media (min-width:782px){.edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{border-radius:8px}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005}}.edit-site-layout.is-full-canvas .edit-site-layout__canvas{bottom:0;top:0;width:100%}.edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{min-height:100%!important;position:relative!important}.edit-site-template-pages-preview{height:100%}html.canvas-mode-edit-transition::view-transition-group(toggle){animation-delay:255ms}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){animation:none!important}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{display:none}.edit-site-layout__view-mode-toggle.components-button{view-transition-name:toggle;align-items:center;background:#1e1e1e;border-radius:0;color:#fff;display:flex;height:60px;justify-content:center;overflow:hidden;padding:0;position:relative;width:60px}.edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{color:#fff}.edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{box-shadow:0 0 0 3px #1e1e1e,0 0 0 6px var(--wp-admin-theme-color);outline:4px solid #0000;outline-offset:4px}.edit-site-layout__view-mode-toggle.components-button:before{border-radius:4px;bottom:9px;box-shadow:none;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}@media not (prefers-reduced-motion){.edit-site-layout__view-mode-toggle.components-button:before{transition:box-shadow .1s ease}}.edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{align-items:center;display:flex;height:60px;justify-content:center;width:60px}.edit-site-layout__actions{background:#fff;bottom:auto;color:#1e1e1e;left:auto;position:fixed!important;right:0;top:-9999em;width:280px;z-index:100000}.edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{bottom:0;top:auto}.edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{top:0}@media (min-width:782px){.edit-site-layout__actions{border-left:1px solid #ddd}}.edit-site-layout__area{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;flex-grow:1;margin:0;overflow:hidden}@media (min-width:782px){.edit-site-layout__area{border-radius:8px;margin:16px 16px 16px 0}}.edit-site .components-editor-notices__snackbar{bottom:16px;padding-left:16px;padding-right:16px;position:fixed;right:0}.edit-site-save-hub{border-top:1px solid #2f2f2f;color:#949494;flex-shrink:0;margin:0;padding:16px}.edit-site-save-hub__button{color:inherit;justify-content:center;width:100%}.edit-site-save-hub__button[aria-disabled=true]{opacity:1}.edit-site-save-hub__button[aria-disabled=true]:hover{color:inherit}.edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{color:#1e1e1e}@media (min-width:600px){.edit-site-save-panel__modal{width:600px}}.edit-site-sidebar__content{contain:content;flex-grow:1;overflow-x:hidden;overflow-y:auto}@keyframes _x51ri_slide-from-right{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:none}}@keyframes _x51ri_slide-from-left{0%{opacity:0;transform:translateX(-50px)}to{opacity:1;transform:none}}.edit-site-sidebar__screen-wrapper{animation-duration:.14s;animation-timing-function:ease-in-out;display:flex;flex-direction:column;height:100%;max-height:100%;overflow-x:auto;padding:0 12px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:stable;scrollbar-width:thin;will-change:transform;will-change:transform,opacity}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar{height:12px;width:12px}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{background-color:initial}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{background-color:#757575}.edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{scrollbar-color:#757575 #0000}@media (hover:none){.edit-site-sidebar__screen-wrapper{scrollbar-color:#757575 #0000}}@media (prefers-reduced-motion:reduce){.edit-site-sidebar__screen-wrapper{animation-duration:0s}}.edit-site-sidebar__screen-wrapper.slide-from-left{animation-name:_x51ri_slide-from-left}.edit-site-sidebar__screen-wrapper.slide-from-right{animation-name:_x51ri_slide-from-right}.edit-site-sidebar-button{color:#e0e0e0;flex-shrink:0}.edit-site-sidebar-button:focus:not(:disabled){box-shadow:none;outline:none}.edit-site-sidebar-button:focus-visible:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:3px solid #0000}.edit-site-sidebar-button:focus,.edit-site-sidebar-button:focus-visible,.edit-site-sidebar-button:hover:not(:disabled,[aria-disabled=true]),.edit-site-sidebar-button:not(:disabled,[aria-disabled=true]):active,.edit-site-sidebar-button[aria-expanded=true]{color:#f0f0f0}.edit-site-sidebar-navigation-item.components-item{border:none;color:#949494;min-height:40px;padding:8px 6px 8px 16px}.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-item.components-item[aria-current=true]{color:#e0e0e0}.edit-site-sidebar-navigation-item.components-item:focus .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item:hover .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item[aria-current=true] .edit-site-sidebar-navigation-item__drilldown-indicator{fill:#e0e0e0}.edit-site-sidebar-navigation-item.components-item[aria-current=true]{background:#2f2f2f;color:#fff;font-weight:500}.edit-site-sidebar-navigation-item.components-item:focus-visible{transform:translateZ(0)}.edit-site-sidebar-navigation-item.components-item .edit-site-sidebar-navigation-item__drilldown-indicator{fill:#949494}.edit-site-sidebar-navigation-item.components-item.with-suffix{padding-right:16px}.edit-site-sidebar-navigation-screen__content .block-editor-list-view-block-select-button{cursor:grab;padding:8px 8px 8px 0}.edit-site-sidebar-navigation-screen{display:flex;flex-direction:column;overflow-x:unset!important;position:relative}.edit-site-sidebar-navigation-screen__main{flex-grow:1;margin-bottom:16px}.edit-site-sidebar-navigation-screen__main.has-footer{margin-bottom:0}.edit-site-sidebar-navigation-screen__content{padding:0 16px}.edit-site-sidebar-navigation-screen__content .components-text{color:#ccc}.edit-site-sidebar-navigation-screen__content .components-heading{margin-bottom:8px}.edit-site-sidebar-navigation-screen__title-icon{background:#1e1e1e;margin-bottom:8px;padding-bottom:8px;padding-top:48px;position:sticky;top:0;z-index:1}.edit-site-sidebar-navigation-screen__title{flex-grow:1;overflow-wrap:break-word}.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title,.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title .edit-site-sidebar-navigation-screen__title{line-height:32px}.edit-site-sidebar-navigation-screen__actions{display:flex;flex-shrink:0}@media (min-width:782px){.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variation-container{max-width:292px}}.edit-site-global-styles-variation-title{color:#ddd;font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{outline-color:#ffffff0d}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{outline-color:#ffffff26}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview{outline-color:#fff}.edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.edit-site-sidebar-navigation-screen__footer{background-color:#1e1e1e;border-top:1px solid #2f2f2f;bottom:0;gap:0;margin:16px 0 0;padding:8px 16px;position:sticky}.edit-site-sidebar-navigation-screen__footer .edit-site-sidebar-navigation-screen-details-footer{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen__input-control{width:100%}.edit-site-sidebar-navigation-screen__input-control .components-input-control__container{background:#2f2f2f}.edit-site-sidebar-navigation-screen__input-control .components-input-control__container .components-button{color:#e0e0e0!important}.edit-site-sidebar-navigation-screen__input-control .components-input-control__input{background:#2f2f2f!important;color:#e0e0e0!important}.edit-site-sidebar-navigation-screen__input-control .components-input-control__backdrop{border:4px!important}.edit-site-sidebar-navigation-screen__input-control .components-base-control__help{color:#949494}.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item[aria-current]{background:none}.sidebar-navigation__more-menu .components-button{color:#e0e0e0}.sidebar-navigation__more-menu .components-button:focus,.sidebar-navigation__more-menu .components-button:hover,.sidebar-navigation__more-menu .components-button[aria-current]{color:#f0f0f0}.edit-site-sidebar-navigation-screen-patterns__group{margin-bottom:24px;margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-patterns__group:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.edit-site-sidebar-navigation-screen-patterns__group-header{margin-top:16px}.edit-site-sidebar-navigation-screen-patterns__group-header p{color:#949494}.edit-site-sidebar-navigation-screen-patterns__group-header h2{font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-navigation-screen-patterns__divider{border-top:1px solid #2f2f2f;margin:16px 0}.edit-site-sidebar-navigation-screen__description{margin:0 0 32px}.edit-site-sidebar-navigation-screen-navigation-menus{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell{width:100%}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{white-space:normal}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__title{margin-top:3px}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu-cell{padding-right:0}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button{color:#949494}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:hover,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button[aria-current]{color:#fff}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu{color:#949494}.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:hover{color:#fff}.edit-site-sidebar-navigation-screen-navigation-menus__loading.components-spinner{display:block;margin-left:auto;margin-right:auto}.edit-site-sidebar-navigation-screen-navigation-menus__helper-block-editor{display:none}.edit-site-sidebar-navigation-screen-main,.edit-site-sidebar-navigation-screen-templates-browse{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-dataviews__group-header{margin-top:32px}.edit-site-sidebar-navigation-screen-dataviews__group-header h2{font-size:11px;font-weight:500;text-transform:uppercase}.edit-site-sidebar-dataviews{margin-left:-16px;margin-right:-16px}.edit-site-sidebar-navigation-screen-dataviews__custom-items .edit-site-sidebar-dataviews-dataview-item{padding-right:8px}.edit-site-sidebar-dataviews-dataview-item{border-radius:2px}.edit-site-sidebar-dataviews-dataview-item .edit-site-sidebar-dataviews-dataview-item__dropdown-menu{min-width:auto}.edit-site-sidebar-dataviews-dataview-item:focus,.edit-site-sidebar-dataviews-dataview-item:hover,.edit-site-sidebar-dataviews-dataview-item[aria-current]{color:#e0e0e0}.edit-site-sidebar-dataviews-dataview-item.is-selected{background:#2f2f2f;color:#fff;font-weight:500}.edit-site-site-hub{align-items:center;display:flex;gap:8px;height:60px;justify-content:space-between;margin-right:12px}.edit-site-site-hub__actions{flex-shrink:0}.edit-site-site-hub__view-mode-toggle-container{flex-shrink:0;height:60px;width:60px}.edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{background:#0000}.edit-site-site-hub__title .components-button{color:#e0e0e0;display:block;flex-grow:1;font-size:15px;font-weight:500;margin-left:-4px;overflow:hidden;padding-right:16px;position:relative;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{color:#e0e0e0}.edit-site-site-hub__title .components-button:focus{box-shadow:none;outline:none}.edit-site-site-hub__title .components-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.edit-site-site-hub__title .components-button:after{content:"↗";font-weight:400;opacity:0;position:absolute;right:0}@media not (prefers-reduced-motion){.edit-site-site-hub__title .components-button:after{transition:opacity .1s linear}}.edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{opacity:1}.edit-site-site-hub_toggle-command-center{color:#e0e0e0}.edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{fill:#f0f0f0}.edit-site-site-icon__icon{fill:currentColor;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__icon{padding:12px}.edit-site-site-icon__image{aspect-ratio:1/1;background:#333;height:100%;object-fit:cover;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__image{border-radius:0}.edit-site-editor__view-mode-toggle button:focus{position:relative}.edit-site-editor__view-mode-toggle button:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:1}.edit-site-style-book{align-items:stretch;display:flex;flex-direction:column;height:100%}.edit-site-style-book.is-button{border-radius:8px}.edit-site-style-book__iframe{display:block;height:100%;width:100%}.edit-site-style-book__iframe.is-button{border-radius:8px}.edit-site-style-book__iframe.is-focused{outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-2)}.edit-site-style-book__tablist-container{background:#fff;display:flex;flex:none;padding-right:56px;width:100%}.edit-site-style-book__tabpanel{flex:1 0 auto;overflow:auto}.edit-site-editor-canvas-container{background-color:#ddd;height:100%}.edit-site-editor-canvas-container iframe{display:block;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{padding:24px 24px 0}.edit-site-editor-canvas-container__section{background:#fff;border-radius:8px;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.edit-site-editor-canvas-container__section{transition:all .3s}}.edit-site-editor-canvas-container__close-button{background:#fff;position:absolute;right:8px;top:8px;z-index:2}.edit-site-post-edit{padding:24px}.edit-site-post-edit.is-empty .edit-site-page-content{align-items:center;display:flex;justify-content:center}.dataforms-layouts-panel__field-dropdown .fields-controls__password{border-top:1px solid #e0e0e0;padding-top:16px}.edit-site-post-list__featured-image{height:100%;object-fit:cover;width:100%}.edit-site-post-list__featured-image-wrapper{border-radius:4px;height:100%;width:100%}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){background-color:#f0f0f0;border-radius:4px;display:block;flex-grow:0!important;height:32px;overflow:hidden;position:relative;width:32px}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;position:absolute;top:0;width:100%}.edit-site-post-list__featured-image-button{background-color:unset;border:none;border-radius:4px;box-shadow:none;box-sizing:border-box;cursor:pointer;height:100%;overflow:hidden;padding:0;width:100%}.edit-site-post-list__featured-image-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{background:rgba(var(--wp-admin-theme-color--rgb),.04);box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.edit-site-post-list__status-icon{height:24px;width:24px}.edit-site-post-list__status-icon svg{fill:currentColor;margin-left:-4px}.edit-site-resizable-frame__inner{position:relative}body:has(.edit-site-resizable-frame__inner.is-resizing){cursor:col-resize;user-select:none;-webkit-user-select:none}.edit-site-resizable-frame__inner.is-resizing:before{content:"";inset:0;position:absolute;z-index:1}.edit-site-resizable-frame__inner-content{inset:0;position:absolute;z-index:0}.edit-site-resizable-frame__handle{align-items:center;background-color:#75757566;border:0;border-radius:4px;cursor:col-resize;display:flex;height:64px;justify-content:flex-end;padding:0;position:absolute;top:calc(50% - 32px);width:4px;z-index:100}.edit-site-resizable-frame__handle:before{content:"";height:100%;left:100%;position:absolute;width:32px}.edit-site-resizable-frame__handle:after{content:"";height:100%;position:absolute;right:100%;width:32px}.edit-site-resizable-frame__handle:focus-visible{outline:2px solid #0000}.edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{background-color:var(--wp-admin-theme-color)}.edit-site-push-changes-to-global-styles-control .components-button{justify-content:center;width:100%}@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:70px;padding-top:0}.font-library-modal .font-library-modal__subtitle{font-size:11px;font-weight:500;text-transform:uppercase}.font-library-modal .components-navigator-screen{padding:3px}.font-library-modal__tabpanel-layout{margin-top:32px}.font-library-modal__tabpanel-layout .font-library-modal__loading{align-items:center;display:flex;height:100%;justify-content:center;left:0;padding-top:120px;position:absolute;top:0;width:100%}.font-library-modal__footer{background-color:#fff;border-top:1px solid #ddd;bottom:32px;height:70px;margin:0 -32px -32px;padding:16px 32px;position:absolute;width:100%}.font-library-modal__page-selection{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.font-library-modal__page-selection .components-select-control__input{font-size:11px!important;font-weight:500}}.font-library-modal__tabpanel-layout .components-base-control__field{margin-bottom:0}.font-library-modal__fonts-title{font-size:11px;font-weight:600;margin-bottom:0;margin-top:0;text-transform:uppercase}.font-library-modal__fonts-list{margin-bottom:0;margin-top:0}.font-library-modal__fonts-list-item{margin-bottom:0}.font-library-modal__font-card{border:1px solid #e0e0e0;height:auto!important;margin-top:-1px;padding:16px;width:100%}.font-library-modal__font-card:hover{background-color:#f0f0f0}.font-library-modal__font-card .font-library-modal__font-card__name{font-weight:700}.font-library-modal__font-card .font-library-modal__font-card__count{color:#757575}.font-library-modal__font-card .font-library-modal__font-variant_demo-image{display:block;height:24px;width:auto}.font-library-modal__font-card .font-library-modal__font-variant_demo-text{flex-shrink:0;white-space:nowrap}@media not (prefers-reduced-motion){.font-library-modal__font-card .font-library-modal__font-variant_demo-text{transition:opacity .3s ease-in-out}}.font-library-modal__font-variant{border-bottom:1px solid #e0e0e0;padding-bottom:16px}.font-library-modal__tablist-container{background:#fff;border-bottom:1px solid #ddd;margin:0 -32px;padding:0 16px;position:sticky;top:0;z-index:1}.font-library-modal__tablist-container [role=tablist]{margin-bottom:-1px}.font-library-modal__upload-area{align-items:center;display:flex;height:256px!important;justify-content:center;width:100%}button.font-library-modal__upload-area{background-color:#f0f0f0}.font-library-modal__local-fonts{margin:0 auto;width:80%}.font-library-modal__local-fonts .font-library-modal__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-modal__select-all{padding:16px 16px 16px 17px}.font-library-modal__select-all .components-checkbox-control__label{padding-left:16px}.edit-site-pagination .components-button.is-tertiary{height:32px;justify-content:center;width:32px}.edit-site-global-styles-variations_item{box-sizing:border-box;cursor:pointer}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{border-radius:2px;outline:1px solid #0000001a;outline-offset:-1px;overflow:hidden;position:relative}@media not (prefers-reduced-motion){.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{transition:outline .1s linear}}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill{height:32px}.edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill .block-editor-iframe__scale-container{overflow:hidden}.edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{outline-color:#0000004d}.edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview,.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:#1e1e1e;outline-offset:1px;outline-width:var(--wp-admin-border-width-focus)}.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{outline-color:var(--wp-admin-theme-color)}.edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root{box-shadow:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root>div>hr{display:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider{overflow-y:auto;padding-left:0;padding-right:0}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .components-tools-panel{border-top:none}.edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .edit-site-global-styles-sidebar__navigator-screen{outline:none;padding:12px}.edit-site-styles .edit-site-page-content .edit-site-page-header{padding-left:48px;padding-right:48px}@container (max-width: 430px){.edit-site-styles .edit-site-page-content .edit-site-page-header{padding-left:24px;padding-right:24px}}.edit-site-styles .edit-site-page-content .edit-site-sidebar-button{color:#1e1e1e}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon{padding:0 8px;width:auto}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon svg{display:none}.show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon:after{content:attr(aria-label);font-size:12px}::view-transition-image-pair(root){isolation:auto}::view-transition-new(root),::view-transition-old(root){animation:none;display:block;mix-blend-mode:normal}body.js #wpadminbar{display:none}body.js #wpbody{padding-top:0}body.js.appearance_page_gutenberg-template-parts,body.js.site-editor-php{background:#fff}body.js.appearance_page_gutenberg-template-parts #wpcontent,body.js.site-editor-php #wpcontent{padding-left:0}body.js.appearance_page_gutenberg-template-parts #wpbody-content,body.js.site-editor-php #wpbody-content{padding-bottom:0}body.js.appearance_page_gutenberg-template-parts #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.appearance_page_gutenberg-template-parts #wpfooter,body.js.site-editor-php #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.site-editor-php #wpfooter{display:none}body.js.appearance_page_gutenberg-template-parts .a11y-speak-region,body.js.site-editor-php .a11y-speak-region{left:-1px;top:-1px}body.js.appearance_page_gutenberg-template-parts ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-template-parts ul#adminmenu>li.current>a.current:after,body.js.site-editor-php ul#adminmenu a.wp-has-current-submenu:after,body.js.site-editor-php ul#adminmenu>li.current>a.current:after{border-right-color:#fff}body.js.appearance_page_gutenberg-template-parts .media-frame select.attachment-filters:last-of-type,body.js.site-editor-php .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}body.js.site-editor-php{background:#1e1e1e}.edit-site{box-sizing:border-box;height:100vh}.edit-site *,.edit-site :after,.edit-site :before{box-sizing:inherit}@media (min-width:600px){.edit-site{bottom:0;left:0;min-height:100vh;position:fixed;right:0;top:0}}.no-js .edit-site{min-height:0;position:static}.edit-site .interface-interface-skeleton{top:0}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.dataviews-wrapper{box-sizing:border-box;container:dataviews-wrapper/inline-size;display:flex;flex-direction:column;font-size:13px;height:100%;line-height:1.4;overflow:auto;scroll-padding-bottom:64px}.dataviews-filters__container,.dataviews__view-actions{box-sizing:border-box;flex-shrink:0;left:0;padding:16px 48px;position:sticky}@media not (prefers-reduced-motion){.dataviews-filters__container,.dataviews__view-actions{transition:padding .1s ease-out}}.dataviews-loading,.dataviews-no-results{align-items:center;display:flex;flex-grow:1;justify-content:center;padding:0 48px}@media not (prefers-reduced-motion){.dataviews-loading,.dataviews-no-results{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-filters__container,.dataviews__view-actions{padding:12px 24px}.dataviews-loading,.dataviews-no-results{padding-left:24px;padding-right:24px}}.dataviews-title-field{font-size:13px;font-weight:500;width:100%}.dataviews-title-field,.dataviews-title-field a{color:#2f2f2f;text-overflow:ellipsis;white-space:nowrap}.dataviews-title-field a{display:block;flex-grow:0;overflow:hidden;text-decoration:none}.dataviews-title-field a:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field a:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-title-field button.components-button.is-link{color:#1e1e1e;display:block;font-weight:inherit;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.dataviews-title-field button.components-button.is-link:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable{color:#2f2f2f;cursor:pointer}.dataviews-title-field--clickable:hover{color:var(--wp-admin-theme-color)}.dataviews-title-field--clickable:focus{border-radius:2px;box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color,#007cba);color:var(--wp-admin-theme-color--rgb)}.dataviews-bulk-actions-footer__item-count{color:#1e1e1e;font-size:11px;font-weight:500;text-transform:uppercase}.dataviews-bulk-actions-footer__container{margin-right:auto;min-height:32px}.dataviews-filters__button{position:relative}.dataviews-filters__container{padding-top:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{opacity:0}.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{opacity:1}.dataviews-filters__summary-popover{font-size:13px;line-height:1.4}.dataviews-filters__summary-popover .components-popover__content{border-radius:4px;width:230px}.dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{padding:0}.dataviews-filters__summary-operators-container{padding:8px 8px 0}.dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){border-bottom:1px solid #e0e0e0;padding-bottom:8px}.dataviews-filters__summary-operators-container:empty{display:none}.dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{color:#757575}.dataviews-filters__summary-chip-container{position:relative;white-space:pre-wrap}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{align-items:center;background:#f0f0f0;border:1px solid #0000;border-radius:16px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:flex;min-height:32px;padding:4px 12px;position:relative}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{padding-inline-end:28px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{background:#e0e0e0;color:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{background:rgba(var(--wp-admin-theme-color--rgb),.04);color:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{background:rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{font-weight:500}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{align-items:center;background:#0000;border:0;border-radius:50%;cursor:pointer;display:flex;height:24px;justify-content:center;padding:0;position:absolute;right:4px;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{fill:#757575}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{background:#e0e0e0}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{fill:#1e1e1e}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{fill:var(--wp-admin-theme-color)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{background:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:none}.dataviews-filters__search-widget-filter-combobox-list{border-top:1px solid #e0e0e0;max-height:184px;overflow:auto;padding:4px}.dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{font-weight:600}.dataviews-filters__search-widget-listbox{overflow:auto;padding:4px}.dataviews-filters__search-widget-listitem{align-items:center;border-radius:2px;box-sizing:border-box;cursor:default;display:flex;gap:8px;margin-block-end:2px;padding:8px 12px}.dataviews-filters__search-widget-listitem:last-child{margin-block-end:0}.dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{background-color:var(--wp-admin-theme-color);color:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{fill:#fff}.dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{color:#fff}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{flex-shrink:0;height:24px;width:24px}.dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{color:#757575;display:block;font-size:12px;line-height:16px;overflow:hidden;text-overflow:ellipsis}.dataviews-filters__search-widget-filter-combobox__wrapper{padding:8px;position:relative}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{background:#f0f0f0;border:none;border-radius:2px;box-shadow:0 0 0 #0000;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin-left:0;margin-right:0;padding:0 32px 0 8px;width:100%}@media not (prefers-reduced-motion){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{transition:box-shadow .1s linear}}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px;line-height:normal}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{color:#1e1e1e9e}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{font-size:13px}}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{background:#fff;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{color:#757575}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{-webkit-appearance:none}.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{align-items:center;display:flex;justify-content:center;position:absolute;right:12px;top:50%;transform:translateY(-50%);width:24px}.dataviews-filters__container-visibility-toggle{flex-shrink:0;position:relative}.dataviews-filters-toggle__count{background:var(--wp-admin-theme-color,#3858e9);border-radius:8px;box-sizing:border-box;color:#fff;font-size:11px;height:16px;line-height:16px;min-width:16px;outline:var(--wp-admin-border-width-focus) solid #fff;padding:0 4px;position:absolute;right:0;text-align:center;top:0;transform:translate(50%,-50%)}.dataviews-search{width:fit-content}.dataviews-footer{background-color:#fff;border-top:1px solid #f0f0f0;bottom:0;flex-shrink:0;left:0;padding:12px 48px;position:sticky;z-index:2}@media not (prefers-reduced-motion){.dataviews-footer{transition:padding .1s ease-out}}@container (max-width: 430px){.dataviews-footer{padding:12px 24px}}@container (max-width: 560px){.dataviews-footer{flex-direction:column!important}.dataviews-footer .dataviews-bulk-actions-footer__container{width:100%}.dataviews-footer .dataviews-bulk-actions-footer__item-count{flex-grow:1}.dataviews-footer .dataviews-pagination{justify-content:space-between;width:100%}}.dataviews-pagination__page-select{font-size:11px;font-weight:500;text-transform:uppercase}@media (min-width:600px){.dataviews-pagination__page-select .components-select-control__input{font-size:11px!important;font-weight:500}}.dataviews-action-modal{z-index:1000001}.dataviews-selection-checkbox{--checkbox-input-size:24px;flex-shrink:0;line-height:0}@media (min-width:600px){.dataviews-selection-checkbox{--checkbox-input-size:16px}}.dataviews-selection-checkbox .components-checkbox-control__input-container{margin:0}.dataviews-view-config{container-type:inline-size;font-size:13px;line-height:1.4;width:320px}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{height:100%;overflow-y:scroll}.dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{width:auto}.dataviews-view-config__sort-direction .components-toggle-group-control-option-base{text-transform:uppercase}.dataviews-settings-section__title.dataviews-settings-section__title{font-size:15px;line-height:24px}.dataviews-settings-section__sidebar{grid-column:span 4}.dataviews-settings-section__content,.dataviews-settings-section__content>*{grid-column:span 8}.dataviews-settings-section__content .is-divided-in-two{display:contents}.dataviews-settings-section__content .is-divided-in-two>*{grid-column:span 4}.dataviews-settings-section:has(.dataviews-settings-section__content:empty){display:none}@container (max-width: 500px){.dataviews-settings-section.dataviews-settings-section{grid-template-columns:repeat(2,1fr)}.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{grid-column:span 2}}.dataviews-field-control__field{height:32px}.dataviews-field-control__actions{position:absolute;top:-9999em}.dataviews-field-control__actions.dataviews-field-control__actions{gap:4px}.dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{position:unset;top:unset}.dataviews-field-control__icon{display:flex;width:24px}.dataviews-field-control__label-sub-label-container{flex-grow:1}.dataviews-field-control__label{display:block}.dataviews-field-control__sub-label{color:#757575;font-size:11px;font-style:normal;margin-bottom:0;margin-top:8px}.dataviews-view-grid{container-type:inline-size;grid-template-rows:max-content;margin-bottom:auto;padding:0 48px 24px}@media not (prefers-reduced-motion){.dataviews-view-grid{transition:padding .1s ease-out}}.dataviews-view-grid .dataviews-view-grid__card{height:100%;justify-content:flex-start;position:relative}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{padding:8px 0 4px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{align-items:center;display:flex;min-height:24px}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{width:fit-content}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{color:#1e1e1e}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.dataviews-view-grid .dataviews-view-grid__media{aspect-ratio:1/1;background-color:#f0f0f0;border-radius:4px;min-height:200px;position:relative;width:100%}.dataviews-view-grid .dataviews-view-grid__media img{height:100%;object-fit:cover;width:100%}.dataviews-view-grid .dataviews-view-grid__media:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%}.dataviews-view-grid .dataviews-view-grid__fields{font-size:12px;line-height:16px;position:relative}.dataviews-view-grid .dataviews-view-grid__fields:not(:empty){padding:0 0 12px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){line-height:20px;min-height:24px;padding-top:2px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{align-items:center;min-height:24px}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{color:#757575;width:35%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:65%}.dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){display:none}.dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){padding-bottom:12px}@container (max-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(1,minmax(0,1fr));padding-left:24px;padding-right:24px}}@container (min-width: 480px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (min-width: 780px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (min-width: 1140px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}@container (min-width: 1520px){.dataviews-view-grid.dataviews-view-grid{grid-template-columns:repeat(5,minmax(0,1fr))}}.dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{display:none}.dataviews-view-grid__card .dataviews-selection-checkbox{left:8px;position:absolute;top:-9999em;z-index:1}.dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{top:8px}.dataviews-view-grid__media--clickable{cursor:pointer}div.dataviews-view-list{list-style-type:none}.dataviews-view-list{margin:0 0 auto}.dataviews-view-list div[role=row]{border-top:1px solid #f0f0f0;margin:0}.dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{box-sizing:border-box;padding:16px 24px;position:relative}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions{flex:0;overflow:hidden}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{height:24px}.dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{opacity:0;position:relative;z-index:1}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{flex-basis:min-content;overflow:unset;padding-inline-end:4px}.dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{opacity:1}.dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{color:#1e1e1e}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{background-color:#f8f8f8;color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#1e1e1e}.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{color:var(--wp-admin-theme-color)}.dataviews-view-list .dataviews-view-list__item{appearance:none;background:none;border:none;cursor:pointer;inset:0;padding:0;position:absolute;scroll-margin:8px 0;z-index:1}.dataviews-view-list .dataviews-view-list__item:focus-visible{outline:none}.dataviews-view-list .dataviews-view-list__item:focus-visible:before{border-radius:2px;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";inset:var(--wp-admin-border-width-focus);outline:2px solid #0000;position:absolute}.dataviews-view-list .dataviews-view-list__title-field{flex:1;line-height:24px;min-height:24px;overflow:hidden}.dataviews-view-list .dataviews-view-list__title-field:has(a,button){z-index:1}.dataviews-view-list .dataviews-view-list__media-wrapper{background-color:#f0f0f0;border-radius:4px;flex-shrink:0;height:52px;overflow:hidden;position:relative;width:52px}.dataviews-view-list .dataviews-view-list__media-wrapper img{height:100%;object-fit:cover;width:100%}.dataviews-view-list .dataviews-view-list__media-wrapper:after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;position:absolute;top:0;width:100%}.dataviews-view-list .dataviews-view-list__field-wrapper{flex-grow:1;min-height:52px}.dataviews-view-list .dataviews-view-list__fields{color:#757575;display:flex;flex-wrap:wrap;font-size:12px;gap:12px;row-gap:4px}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{display:none}.dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{align-items:center;display:flex;line-height:20px;min-height:24px}.dataviews-view-list+.dataviews-pagination{justify-content:space-between}.dataviews-view-table{border-collapse:collapse;border-color:inherit;color:#757575;margin-bottom:auto;position:relative;text-indent:0;width:100%}.dataviews-view-table th{color:#1e1e1e;font-size:13px;font-weight:400;text-align:left}.dataviews-view-table td,.dataviews-view-table th{padding:12px;white-space:nowrap}.dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{text-align:right}.dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{padding-right:0;width:1%}.dataviews-view-table tr{border-top:1px solid #f0f0f0}.dataviews-view-table tr .dataviews-view-table-header-button{gap:4px}.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-left:48px}.dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{margin-left:-8px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-right:48px}.dataviews-view-table tr:last-child{border-bottom:0}.dataviews-view-table tr.is-hovered{background-color:#f8f8f8}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{opacity:0}.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{opacity:1}.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:0}.dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}@media (hover:none){.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){opacity:1}}.dataviews-view-table tr.is-selected{background-color:rgba(var(--wp-admin-theme-color--rgb),.04);color:#757575}.dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{border-top:1px solid rgba(var(--wp-admin-theme-color--rgb),.12)}.dataviews-view-table tr.is-selected:hover{background-color:rgba(var(--wp-admin-theme-color--rgb),.08)}.dataviews-view-table thead{inset-block-start:0;position:sticky;z-index:1}.dataviews-view-table thead tr{border:0}.dataviews-view-table thead th{background-color:#fff;font-size:11px;font-weight:500;padding-bottom:8px;padding-left:12px;padding-top:8px;text-transform:uppercase}.dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-left:4px}.dataviews-view-table tbody td{vertical-align:top}.dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{align-items:center;display:flex;min-height:32px}.dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){min-height:0}.dataviews-view-table .dataviews-view-table-header-button{font-size:11px;font-weight:500;padding:4px 8px;text-transform:uppercase}.dataviews-view-table .dataviews-view-table-header-button:not(:hover){color:#1e1e1e}.dataviews-view-table .dataviews-view-table-header-button span{speak:none}.dataviews-view-table .dataviews-view-table-header-button span:empty{display:none}.dataviews-view-table .dataviews-view-table-header{padding-left:4px}.dataviews-view-table .dataviews-view-table__actions-column{width:1%}.dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{opacity:1}.dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){padding-left:0}.dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{padding:4px 8px}.dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{padding:16px 12px}.dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{padding-right:0}@container (max-width: 430px){.dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{padding-left:24px}.dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{padding-right:24px}}.dataviews-view-table-selection-checkbox{--checkbox-input-size:24px}@media (min-width:600px){.dataviews-view-table-selection-checkbox{--checkbox-input-size:16px}}.dataviews-column-primary__media{max-width:60px}.dataviews-controls__datetime{border:none;padding:0}.dataforms-layouts-panel__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-panel__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-panel__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.dataforms-layouts-panel__field-control .components-button{max-width:100%;min-height:32px;text-align:left;text-wrap:balance;text-wrap:pretty;white-space:normal}.dataforms-layouts-panel__field-control .components-dropdown{max-width:100%}.dataforms-layouts-panel__field-dropdown .components-popover__content{min-width:320px;padding:16px}.dataforms-layouts-panel__dropdown-header{margin-bottom:16px}.components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{z-index:159990}.dataforms-layouts-regular__field{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.dataforms-layouts-regular__field .components-base-control__label{font-size:inherit;font-weight:400;text-transform:none}.dataforms-layouts-regular__field-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.dataforms-layouts-regular__field-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.edit-site-layout{color:#ccc;display:flex;flex-direction:column;height:100%}.edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{background:#1e1e1e}.edit-site-layout__content{display:flex;flex-grow:1;height:100%}.edit-site-layout__sidebar-region{flex-shrink:0;width:100vw;z-index:1}@media (min-width:782px){.edit-site-layout__sidebar-region{width:300px}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{height:100vh;left:0;position:fixed!important;top:0}.edit-site-layout__sidebar-region .edit-site-layout__sidebar{display:flex;flex-direction:column;height:100%}.edit-site-layout__sidebar-region .resizable-editor__drag-handle{right:0}.edit-site-layout__main{display:flex;flex-direction:column;flex-grow:1;overflow:hidden}.edit-site-layout__mobile{display:flex;flex-direction:column;position:relative;width:100%;z-index:2}.edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{padding:0}.edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{padding:0 12px}.edit-site-layout__canvas-container{flex-grow:1;overflow:visible;position:relative;z-index:2}.edit-site-layout__canvas-container.is-resizing:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:100}.edit-site-layout__canvas{align-items:center;bottom:0;display:flex;justify-content:center;left:0;position:absolute;top:0;width:100%}.edit-site-layout__canvas.is-right-aligned{justify-content:flex-end}.edit-site-layout__canvas .edit-site-resizable-frame__inner{color:#1e1e1e}@media (min-width:782px){.edit-site-layout__canvas{bottom:16px;top:16px;width:calc(100% - 16px)}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;overflow:hidden}}@media (min-width:782px) and (not (prefers-reduced-motion)){.edit-site-layout__canvas .edit-site-resizable-frame__inner-content{transition:border-radius,box-shadow .4s}}@media (min-width:782px){.edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{border-radius:8px}.edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005}}.edit-site-layout.is-full-canvas .edit-site-layout__canvas{bottom:0;top:0;width:100%}.edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{min-height:100%!important;position:relative!important}.edit-site-template-pages-preview{height:100%}html.canvas-mode-edit-transition::view-transition-group(toggle){animation-delay:255ms}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){animation:none!important}}.edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{display:none}.edit-site-layout__view-mode-toggle.components-button{view-transition-name:toggle;align-items:center;background:#1e1e1e;border-radius:0;color:#fff;display:flex;height:60px;justify-content:center;overflow:hidden;padding:0;position:relative;width:60px}.edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{color:#fff}.edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{box-shadow:0 0 0 3px #1e1e1e,0 0 0 6px var(--wp-admin-theme-color);outline:4px solid #0000;outline-offset:4px}.edit-site-layout__view-mode-toggle.components-button:before{border-radius:4px;bottom:9px;box-shadow:none;content:"";display:block;left:9px;position:absolute;right:9px;top:9px}@media not (prefers-reduced-motion){.edit-site-layout__view-mode-toggle.components-button:before{transition:box-shadow .1s ease}}.edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{align-items:center;display:flex;height:60px;justify-content:center;width:60px}.edit-site-layout__actions{background:#fff;bottom:auto;color:#1e1e1e;left:auto;position:fixed!important;right:0;top:-9999em;width:280px;z-index:100000}.edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{bottom:0;top:auto}.edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{top:0}@media (min-width:782px){.edit-site-layout__actions{border-left:1px solid #ddd}}.edit-site-layout__area{box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;flex-grow:1;margin:0;overflow:hidden}@media (min-width:782px){.edit-site-layout__area{border-radius:8px;margin:16px 16px 16px 0}}.edit-site .components-editor-notices__snackbar{bottom:16px;padding-left:16px;padding-right:16px;position:fixed;right:0}.edit-site-page{background:#fff;color:#2f2f2f;container:edit-site-page/inline-size;height:100%}@media not (prefers-reduced-motion){.edit-site-page{transition:width .2s ease-out}}.edit-site-page-header{background:#fff;border-bottom:1px solid #f0f0f0;padding:16px 48px;position:sticky;top:0;z-index:2}@media not (prefers-reduced-motion){.edit-site-page-header{transition:padding .1s ease-out}}.edit-site-page-header .components-heading{color:#1e1e1e}.edit-site-page-header .edit-site-page-header__page-title{min-height:40px}.edit-site-page-header .edit-site-page-header__page-title .components-heading{flex-basis:0;flex-grow:1;white-space:nowrap}.edit-site-page-header .edit-site-page-header__sub-title{margin-bottom:8px}@container (max-width: 430px){.edit-site-page-header{padding:16px 24px}}.edit-site-page-content{display:flex;flex-flow:column;height:100%;position:relative;z-index:1}.edit-site-save-hub{border-top:1px solid #2f2f2f;color:#949494;flex-shrink:0;margin:0;padding:16px}.edit-site-save-hub__button{color:inherit;justify-content:center;width:100%}.edit-site-save-hub__button[aria-disabled=true]{opacity:1}.edit-site-save-hub__button[aria-disabled=true]:hover{color:inherit}.edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{color:#1e1e1e}@media (min-width:600px){.edit-site-save-panel__modal{width:600px}}.edit-site-sidebar__content{contain:content;flex-grow:1;overflow-x:hidden;overflow-y:auto}@keyframes _fwjws_slide-from-right{0%{opacity:0;transform:translateX(50px)}to{opacity:1;transform:none}}@keyframes _fwjws_slide-from-left{0%{opacity:0;transform:translateX(-50px)}to{opacity:1;transform:none}}.edit-site-sidebar__screen-wrapper{animation-duration:.14s;animation-timing-function:ease-in-out;display:flex;flex-direction:column;height:100%;max-height:100%;overflow-x:auto;padding:0 12px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:stable;scrollbar-width:thin;will-change:transform;will-change:transform,opacity}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar{height:12px;width:12px}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{background-color:initial}.edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{background-color:#757575}.edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{scrollbar-color:#757575 #0000}@media (hover:none){.edit-site-sidebar__screen-wrapper{scrollbar-color:#757575 #0000}}@media (prefers-reduced-motion:reduce){.edit-site-sidebar__screen-wrapper{animation-duration:0s}}.edit-site-sidebar__screen-wrapper.slide-from-left{animation-name:_fwjws_slide-from-left}.edit-site-sidebar__screen-wrapper.slide-from-right{animation-name:_fwjws_slide-from-right}.edit-site-site-hub{align-items:center;display:flex;gap:8px;height:60px;justify-content:space-between;margin-right:12px}.edit-site-site-hub__actions{flex-shrink:0}.edit-site-site-hub__view-mode-toggle-container{flex-shrink:0;height:60px;width:60px}.edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{background:#0000}.edit-site-site-hub__title .components-button{color:#e0e0e0;display:block;flex-grow:1;font-size:15px;font-weight:500;margin-left:-4px;overflow:hidden;padding-right:16px;position:relative;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{color:#e0e0e0}.edit-site-site-hub__title .components-button:focus{box-shadow:none;outline:none}.edit-site-site-hub__title .components-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.edit-site-site-hub__title .components-button:after{content:"↗";font-weight:400;opacity:0;position:absolute;right:0}@media not (prefers-reduced-motion){.edit-site-site-hub__title .components-button:after{transition:opacity .1s linear}}.edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{opacity:1}.edit-site-site-hub_toggle-command-center{color:#e0e0e0}.edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{fill:#f0f0f0}.edit-site-site-icon__icon{fill:currentColor;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__icon{padding:12px}.edit-site-site-icon__image{aspect-ratio:1/1;background:#333;height:100%;object-fit:cover;width:100%}.edit-site-layout.is-full-canvas .edit-site-site-icon__image{border-radius:0}.edit-site-editor__view-mode-toggle button:focus{position:relative}.edit-site-editor__view-mode-toggle button:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff;content:"";display:block;left:0;position:absolute;right:0;top:0;z-index:1}.edit-site-editor-canvas-container{background-color:#ddd;height:100%}.edit-site-editor-canvas-container iframe{display:block;height:100%;width:100%}.edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{padding:24px 24px 0}.edit-site-editor-canvas-container__section{background:#fff;border-radius:8px;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.edit-site-editor-canvas-container__section{transition:all .3s}}.edit-site-editor-canvas-container__close-button{background:#fff;position:absolute;right:8px;top:8px;z-index:2}.edit-site-post-list__featured-image{height:100%;object-fit:cover;width:100%}.edit-site-post-list__featured-image-wrapper{border-radius:4px;height:100%;width:100%}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){background-color:#f0f0f0;border-radius:4px;display:block;flex-grow:0!important;height:32px;overflow:hidden;position:relative;width:32px}.edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{border-radius:4px;box-shadow:inset 0 0 0 1px #0000001a;content:"";height:100%;left:0;position:absolute;top:0;width:100%}.edit-site-post-list__featured-image-button{background-color:unset;border:none;border-radius:4px;box-shadow:none;box-sizing:border-box;cursor:pointer;height:100%;overflow:hidden;padding:0;width:100%}.edit-site-post-list__featured-image-button:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{background:rgba(var(--wp-admin-theme-color--rgb),.04);box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.edit-site-post-list__status-icon{height:24px;width:24px}.edit-site-post-list__status-icon svg{fill:currentColor;margin-left:-4px}.edit-site-resizable-frame__inner{position:relative}body:has(.edit-site-resizable-frame__inner.is-resizing){cursor:col-resize;user-select:none;-webkit-user-select:none}.edit-site-resizable-frame__inner.is-resizing:before{content:"";inset:0;position:absolute;z-index:1}.edit-site-resizable-frame__inner-content{inset:0;position:absolute;z-index:0}.edit-site-resizable-frame__handle{align-items:center;background-color:#75757566;border:0;border-radius:4px;cursor:col-resize;display:flex;height:64px;justify-content:flex-end;padding:0;position:absolute;top:calc(50% - 32px);width:4px;z-index:100}.edit-site-resizable-frame__handle:before{content:"";height:100%;left:100%;position:absolute;width:32px}.edit-site-resizable-frame__handle:after{content:"";height:100%;position:absolute;right:100%;width:32px}.edit-site-resizable-frame__handle:focus-visible{outline:2px solid #0000}.edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{background-color:var(--wp-admin-theme-color)}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}#adminmenumain,#wpadminbar{display:none}#wpcontent{margin-left:0}body.js #wpbody{padding-top:0}body{background:#fff}body #wpcontent{padding-left:0}body #wpbody-content{padding-bottom:0}body #wpbody-content>div:not(#gutenberg-posts-dashboard):not(#screen-meta),body #wpfooter{display:none}body .a11y-speak-region{left:-1px;top:-1px}body ul#adminmenu a.wp-has-current-submenu:after,body ul#adminmenu>li.current>a.current:after{border-right-color:#fff}body .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}#gutenberg-posts-dashboard{box-sizing:border-box;height:100vh}#gutenberg-posts-dashboard *,#gutenberg-posts-dashboard :after,#gutenberg-posts-dashboard :before{box-sizing:inherit}@media (min-width:600px){#gutenberg-posts-dashboard{bottom:0;left:0;min-height:100vh;position:fixed;right:0;top:0}}.no-js #gutenberg-posts-dashboard{min-height:0;position:static}#gutenberg-posts-dashboard .components-editor-notices__snackbar{bottom:16px;padding-left:16px;padding-right:16px;position:fixed;right:0}@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .dataviews-wrapper{ box-sizing:border-box; container:dataviews-wrapper/inline-size; display:flex; flex-direction:column; font-size:13px; height:100%; line-height:1.4; overflow:auto; scroll-padding-bottom:64px; } .dataviews-filters__container,.dataviews__view-actions{ box-sizing:border-box; flex-shrink:0; padding:16px 48px; position:sticky; right:0; } @media not (prefers-reduced-motion){ .dataviews-filters__container,.dataviews__view-actions{ transition:padding .1s ease-out; } } .dataviews-loading,.dataviews-no-results{ align-items:center; display:flex; flex-grow:1; justify-content:center; padding:0 48px; } @media not (prefers-reduced-motion){ .dataviews-loading,.dataviews-no-results{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-filters__container,.dataviews__view-actions{ padding:12px 24px; } .dataviews-loading,.dataviews-no-results{ padding-left:24px; padding-right:24px; } } .dataviews-title-field{ font-size:13px; font-weight:500; width:100%; } .dataviews-title-field,.dataviews-title-field a{ color:#2f2f2f; text-overflow:ellipsis; white-space:nowrap; } .dataviews-title-field a{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; } .dataviews-title-field a:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field a:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-title-field button.components-button.is-link{ color:#1e1e1e; display:block; font-weight:inherit; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; width:100%; } .dataviews-title-field button.components-button.is-link:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable{ color:#2f2f2f; cursor:pointer; } .dataviews-title-field--clickable:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-bulk-actions-footer__item-count{ color:#1e1e1e; font-size:11px; font-weight:500; text-transform:uppercase; } .dataviews-bulk-actions-footer__container{ margin-left:auto; min-height:32px; } .dataviews-filters__button{ position:relative; } .dataviews-filters__container{ padding-top:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{ opacity:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{ opacity:1; } .dataviews-filters__summary-popover{ font-size:13px; line-height:1.4; } .dataviews-filters__summary-popover .components-popover__content{ border-radius:4px; width:230px; } .dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{ padding:0; } .dataviews-filters__summary-operators-container{ padding:8px 8px 0; } .dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){ border-bottom:1px solid #e0e0e0; padding-bottom:8px; } .dataviews-filters__summary-operators-container:empty{ display:none; } .dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{ color:#757575; } .dataviews-filters__summary-chip-container{ position:relative; white-space:pre-wrap; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{ align-items:center; background:#f0f0f0; border:1px solid #0000; border-radius:16px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:flex; min-height:32px; padding:4px 12px; position:relative; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{ padding-inline-end:28px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{ background:#e0e0e0; color:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{ background:rgba(var(--wp-admin-theme-color--rgb), .04); color:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{ background:rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{ font-weight:500; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{ align-items:center; background:#0000; border:0; border-radius:50%; cursor:pointer; display:flex; height:24px; justify-content:center; left:4px; padding:0; position:absolute; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{ fill:#757575; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{ background:#e0e0e0; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{ fill:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{ fill:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__search-widget-filter-combobox-list{ border-top:1px solid #e0e0e0; max-height:184px; overflow:auto; padding:4px; } .dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{ font-weight:600; } .dataviews-filters__search-widget-listbox{ overflow:auto; padding:4px; } .dataviews-filters__search-widget-listitem{ align-items:center; border-radius:2px; box-sizing:border-box; cursor:default; display:flex; gap:8px; margin-block-end:2px; padding:8px 12px; } .dataviews-filters__search-widget-listitem:last-child{ margin-block-end:0; } .dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{ background-color:var(--wp-admin-theme-color); color:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{ fill:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{ color:#fff; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{ flex-shrink:0; height:24px; width:24px; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{ color:#757575; display:block; font-size:12px; line-height:16px; overflow:hidden; text-overflow:ellipsis; } .dataviews-filters__search-widget-filter-combobox__wrapper{ padding:8px; position:relative; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ background:#f0f0f0; border:none; border-radius:2px; box-shadow:0 0 0 #0000; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin-left:0; margin-right:0; padding:0 8px 0 32px; width:100%; } @media not (prefers-reduced-motion){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; line-height:normal; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ background:#fff; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{ color:#757575; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{ -webkit-appearance:none; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{ align-items:center; display:flex; justify-content:center; left:12px; position:absolute; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__container-visibility-toggle{ flex-shrink:0; position:relative; } .dataviews-filters-toggle__count{ background:var(--wp-admin-theme-color, #3858e9); border-radius:8px; box-sizing:border-box; color:#fff; font-size:11px; height:16px; left:0; line-height:16px; min-width:16px; outline:var(--wp-admin-border-width-focus) solid #fff; padding:0 4px; position:absolute; text-align:center; top:0; transform:translate(-50%, -50%); } .dataviews-search{ width:fit-content; } .dataviews-footer{ background-color:#fff; border-top:1px solid #f0f0f0; bottom:0; flex-shrink:0; padding:12px 48px; position:sticky; right:0; z-index:2; } @media not (prefers-reduced-motion){ .dataviews-footer{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-footer{ padding:12px 24px; } } @container (max-width: 560px){ .dataviews-footer{ flex-direction:column !important; } .dataviews-footer .dataviews-bulk-actions-footer__container{ width:100%; } .dataviews-footer .dataviews-bulk-actions-footer__item-count{ flex-grow:1; } .dataviews-footer .dataviews-pagination{ justify-content:space-between; width:100%; } } .dataviews-pagination__page-select{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .dataviews-pagination__page-select .components-select-control__input{ font-size:11px !important; font-weight:500; } } .dataviews-action-modal{ z-index:1000001; } .dataviews-selection-checkbox{ --checkbox-input-size:24px; flex-shrink:0; line-height:0; } @media (min-width:600px){ .dataviews-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-selection-checkbox .components-checkbox-control__input-container{ margin:0; } .dataviews-view-config{ container-type:inline-size; font-size:13px; line-height:1.4; width:320px; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{ height:100%; overflow-y:scroll; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{ width:auto; } .dataviews-view-config__sort-direction .components-toggle-group-control-option-base{ text-transform:uppercase; } .dataviews-settings-section__title.dataviews-settings-section__title{ font-size:15px; line-height:24px; } .dataviews-settings-section__sidebar{ grid-column:span 4; } .dataviews-settings-section__content,.dataviews-settings-section__content>*{ grid-column:span 8; } .dataviews-settings-section__content .is-divided-in-two{ display:contents; } .dataviews-settings-section__content .is-divided-in-two>*{ grid-column:span 4; } .dataviews-settings-section:has(.dataviews-settings-section__content:empty){ display:none; } @container (max-width: 500px){ .dataviews-settings-section.dataviews-settings-section{ grid-template-columns:repeat(2, 1fr); } .dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{ grid-column:span 2; } } .dataviews-field-control__field{ height:32px; } .dataviews-field-control__actions{ position:absolute; top:-9999em; } .dataviews-field-control__actions.dataviews-field-control__actions{ gap:4px; } .dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{ position:unset; top:unset; } .dataviews-field-control__icon{ display:flex; width:24px; } .dataviews-field-control__label-sub-label-container{ flex-grow:1; } .dataviews-field-control__label{ display:block; } .dataviews-field-control__sub-label{ color:#757575; font-size:11px; font-style:normal; margin-bottom:0; margin-top:8px; } .dataviews-view-grid{ container-type:inline-size; grid-template-rows:max-content; margin-bottom:auto; padding:0 48px 24px; } @media not (prefers-reduced-motion){ .dataviews-view-grid{ transition:padding .1s ease-out; } } .dataviews-view-grid .dataviews-view-grid__card{ height:100%; justify-content:flex-start; position:relative; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{ padding:8px 0 4px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{ align-items:center; display:flex; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{ width:fit-content; } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ color:#1e1e1e; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__media{ aspect-ratio:1/1; background-color:#f0f0f0; border-radius:4px; min-height:200px; position:relative; width:100%; } .dataviews-view-grid .dataviews-view-grid__media img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-grid .dataviews-view-grid__media:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; pointer-events:none; position:absolute; right:0; top:0; width:100%; } .dataviews-view-grid .dataviews-view-grid__fields{ font-size:12px; line-height:16px; position:relative; } .dataviews-view-grid .dataviews-view-grid__fields:not(:empty){ padding:0 0 12px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){ line-height:20px; min-height:24px; padding-top:2px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{ align-items:center; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{ color:#757575; width:35%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:65%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){ display:none; } .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){ padding-bottom:12px; } @container (max-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(1, minmax(0, 1fr)); padding-left:24px; padding-right:24px; } } @container (min-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); } } @container (min-width: 780px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(3, minmax(0, 1fr)); } } @container (min-width: 1140px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(4, minmax(0, 1fr)); } } @container (min-width: 1520px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(5, minmax(0, 1fr)); } } .dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{ display:none; } .dataviews-view-grid__card .dataviews-selection-checkbox{ position:absolute; right:8px; top:-9999em; z-index:1; } .dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{ top:8px; } .dataviews-view-grid__media--clickable{ cursor:pointer; } div.dataviews-view-list{ list-style-type:none; } .dataviews-view-list{ margin:0 0 auto; } .dataviews-view-list div[role=row]{ border-top:1px solid #f0f0f0; margin:0; } .dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{ box-sizing:border-box; padding:16px 24px; position:relative; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions{ flex:0; overflow:hidden; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{ height:24px; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{ opacity:0; position:relative; z-index:1; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{ flex-basis:min-content; overflow:unset; padding-inline-end:4px; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{ opacity:1; } .dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{ color:#1e1e1e; } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{ background-color:#f8f8f8; color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#1e1e1e; } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list .dataviews-view-list__item{ appearance:none; background:none; border:none; cursor:pointer; inset:0; padding:0; position:absolute; scroll-margin:8px 0; z-index:1; } .dataviews-view-list .dataviews-view-list__item:focus-visible{ outline:none; } .dataviews-view-list .dataviews-view-list__item:focus-visible:before{ border-radius:2px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .dataviews-view-list .dataviews-view-list__title-field{ flex:1; line-height:24px; min-height:24px; overflow:hidden; } .dataviews-view-list .dataviews-view-list__title-field:has(a,button){ z-index:1; } .dataviews-view-list .dataviews-view-list__media-wrapper{ background-color:#f0f0f0; border-radius:4px; flex-shrink:0; height:52px; overflow:hidden; position:relative; width:52px; } .dataviews-view-list .dataviews-view-list__media-wrapper img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-list .dataviews-view-list__media-wrapper:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; position:absolute; right:0; top:0; width:100%; } .dataviews-view-list .dataviews-view-list__field-wrapper{ flex-grow:1; min-height:52px; } .dataviews-view-list .dataviews-view-list__fields{ color:#757575; display:flex; flex-wrap:wrap; font-size:12px; gap:12px; row-gap:4px; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{ display:none; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{ align-items:center; display:flex; line-height:20px; min-height:24px; } .dataviews-view-list+.dataviews-pagination{ justify-content:space-between; } .dataviews-view-table{ border-collapse:collapse; border-color:inherit; color:#757575; margin-bottom:auto; position:relative; text-indent:0; width:100%; } .dataviews-view-table th{ color:#1e1e1e; font-size:13px; font-weight:400; text-align:right; } .dataviews-view-table td,.dataviews-view-table th{ padding:12px; white-space:nowrap; } .dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{ text-align:left; } .dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{ padding-left:0; width:1%; } .dataviews-view-table tr{ border-top:1px solid #f0f0f0; } .dataviews-view-table tr .dataviews-view-table-header-button{ gap:4px; } .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-right:48px; } .dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{ margin-right:-8px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-left:48px; } .dataviews-view-table tr:last-child{ border-bottom:0; } .dataviews-view-table tr.is-hovered{ background-color:#f8f8f8; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{ opacity:0; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{ opacity:1; } .dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:0; } .dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } @media (hover:none){ .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } } .dataviews-view-table tr.is-selected{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#757575; } .dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-table tr.is-selected:hover{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-table thead{ inset-block-start:0; position:sticky; z-index:1; } .dataviews-view-table thead tr{ border:0; } .dataviews-view-table thead th{ background-color:#fff; font-size:11px; font-weight:500; padding-bottom:8px; padding-right:12px; padding-top:8px; text-transform:uppercase; } .dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-right:4px; } .dataviews-view-table tbody td{ vertical-align:top; } .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{ align-items:center; display:flex; min-height:32px; } .dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){ min-height:0; } .dataviews-view-table .dataviews-view-table-header-button{ font-size:11px; font-weight:500; padding:4px 8px; text-transform:uppercase; } .dataviews-view-table .dataviews-view-table-header-button:not(:hover){ color:#1e1e1e; } .dataviews-view-table .dataviews-view-table-header-button span{ speak:none; } .dataviews-view-table .dataviews-view-table-header-button span:empty{ display:none; } .dataviews-view-table .dataviews-view-table-header{ padding-right:4px; } .dataviews-view-table .dataviews-view-table__actions-column{ width:1%; } .dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{ opacity:1; } .dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-right:0; } .dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{ padding:4px 8px; } .dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{ padding:16px 12px; } .dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{ padding-left:0; } @container (max-width: 430px){ .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-right:24px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-left:24px; } } .dataviews-view-table-selection-checkbox{ --checkbox-input-size:24px; } @media (min-width:600px){ .dataviews-view-table-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-column-primary__media{ max-width:60px; } .dataviews-controls__datetime{ border:none; padding:0; } .dataforms-layouts-panel__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-panel__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-panel__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .dataforms-layouts-panel__field-control .components-button{ max-width:100%; min-height:32px; text-align:right; text-wrap:balance; text-wrap:pretty; white-space:normal; } .dataforms-layouts-panel__field-control .components-dropdown{ max-width:100%; } .dataforms-layouts-panel__field-dropdown .components-popover__content{ min-width:320px; padding:16px; } .dataforms-layouts-panel__dropdown-header{ margin-bottom:16px; } .components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{ z-index:159990; } .dataforms-layouts-regular__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-regular__field .components-base-control__label{ font-size:inherit; font-weight:400; text-transform:none; } .dataforms-layouts-regular__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-regular__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .fields-create-template-part-modal{ z-index:1000001; } .fields-create-template-part-modal__area-radio-group{ border:1px solid #949494; border-radius:2px; } .fields-create-template-part-modal__area-radio-wrapper{ align-items:center; display:grid; grid-template-columns:min-content 1fr min-content; padding:12px; position:relative; grid-gap:4px 8px; color:#1e1e1e; } .fields-create-template-part-modal__area-radio-wrapper+.fields-create-template-part-modal__area-radio-wrapper{ border-top:1px solid #949494; } .fields-create-template-part-modal__area-radio-wrapper input[type=radio]{ opacity:0; position:absolute; } .fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:checked){ z-index:1; } .fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:not(:checked)):hover{ color:var(--wp-admin-theme-color); } .fields-create-template-part-modal__area-radio-wrapper>:not(.fields-create-template-part-modal__area-radio-label){ pointer-events:none; } .fields-create-template-part-modal__area-radio-label:before{ content:""; inset:0; position:absolute; } input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-label:before{ cursor:pointer; } input[type=radio]:focus-visible~.fields-create-template-part-modal__area-radio-label:before{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:4px solid #0000; } .fields-create-template-part-modal__area-radio-checkmark,.fields-create-template-part-modal__area-radio-icon{ fill:currentColor; } input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-checkmark{ opacity:0; } .fields-create-template-part-modal__area-radio-description{ color:#757575; font-size:12px; grid-column:2 / 3; line-height:normal; margin:0; text-wrap:pretty; } input[type=radio]:not(:checked):hover~.fields-create-template-part-modal__area-radio-description{ color:inherit; } .fields-controls__slug .fields-controls__slug-external-icon{ margin-right:5ch; } .fields-controls__slug .fields-controls__slug-input input.components-input-control__input{ padding-inline-start:0 !important; } .fields-controls__slug .fields-controls__slug-help-link{ word-break:break-word; } .fields-controls__slug .fields-controls__slug-help{ display:flex; flex-direction:column; } .fields-controls__slug .fields-controls__slug-help .fields-controls__slug-help-slug{ font-weight:600; } .fields-controls__featured-image-placeholder{ background:#fff linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); border-radius:2px; box-shadow:inset 0 0 0 1px #0003; display:inline-block; padding:0; } .fields-controls__featured-image-title{ color:#1e1e1e; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:100%; } .fields-controls__featured-image-image{ align-self:center; border-radius:2px; height:100%; width:100%; } .fields-controls__featured-image-container .fields-controls__featured-image-placeholder{ margin:0; } .fields-controls__featured-image-container span{ margin-left:auto; } fieldset.fields-controls__featured-image .fields-controls__featured-image-container{ border:1px solid #ddd; border-radius:2px; cursor:pointer; padding:8px 12px; } fieldset.fields-controls__featured-image .fields-controls__featured-image-container:hover{ background-color:#f0f0f0; } fieldset.fields-controls__featured-image .fields-controls__featured-image-placeholder{ height:24px; width:24px; } fieldset.fields-controls__featured-image span{ align-self:center; text-align:start; white-space:nowrap; } fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button{ height:fit-content; padding:0; } fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:focus,fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:hover{ border:0; color:unset; } fieldset.fields-controls__featured-image .fields-controls__featured-image-remove-button{ place-self:end; } .dataforms-layouts-panel__field-control .fields-controls__featured-image-image,.dataforms-layouts-panel__field-control .fields-controls__featured-image-placeholder{ height:16px; width:16px; } .dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-image,.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-placeholder{ display:block; height:32px; width:32px; } .fields-controls__template-modal{ z-index:1000001; } .fields-controls__template-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; padding-top:2px; } @media (min-width:782px){ .fields-controls__template-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .fields-controls__template-content .block-editor-block-patterns-list{ column-count:4; } } .fields-controls__template-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .fields-field__title span:first-child{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .fields-field__pattern-title span:first-child{ flex:1; } .edit-site-custom-template-modal__contents-wrapper{ height:100%; justify-content:flex-start !important; } .edit-site-custom-template-modal__contents-wrapper>*{ width:100%; } .edit-site-custom-template-modal__contents-wrapper__suggestions_list{ margin-left:-12px; margin-right:-12px; width:calc(100% + 24px); } .edit-site-custom-template-modal__contents>.components-button{ height:auto; justify-content:center; } @media (min-width:782px){ .edit-site-custom-template-modal{ width:456px; } } @media (min-width:600px){ .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list{ max-height:224px; overflow-y:auto; } } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item{ display:block; height:auto; overflow-wrap:break-word; padding:8px 12px; text-align:right; white-space:pre-wrap; width:100%; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item mark{ background:none; font-weight:700; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover *,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover mark{ color:var(--wp-admin-theme-color); } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus{ background-color:#f0f0f0; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color) inset; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__title{ display:block; overflow:hidden; text-overflow:ellipsis; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info{ color:#757575; word-break:break-all; } .edit-site-custom-template-modal__no-results{ border:1px solid #ccc; border-radius:2px; padding:16px; } .edit-site-custom-generic-template__modal .components-modal__header{ border-bottom:none; } .edit-site-custom-generic-template__modal .components-modal__content:before{ margin-bottom:4px; } @media (min-width:960px){ .edit-site-add-new-template__modal{ margin-top:64px; max-height:calc(100% - 128px); max-width:832px; width:calc(100% - 128px); } } .edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button svg,.edit-site-add-new-template__modal .edit-site-add-new-template__template-button svg{ fill:var(--wp-admin-theme-color); } .edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button .edit-site-add-new-template__template-name{ align-items:flex-start; flex-grow:1; } .edit-site-add-new-template__modal .edit-site-add-new-template__template-icon{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-radius:100%; max-height:40px; max-width:40px; padding:8px; } .edit-site-add-new-template__template-list__contents>.components-button,.edit-site-custom-template-modal__contents>.components-button{ border:1px solid #ddd; display:flex; flex-direction:column; justify-content:center; outline:1px solid #0000; padding:32px; } .edit-site-add-new-template__template-list__contents>.components-button span:first-child,.edit-site-custom-template-modal__contents>.components-button span:first-child{ color:#1e1e1e; } .edit-site-add-new-template__template-list__contents>.components-button span,.edit-site-custom-template-modal__contents>.components-button span{ color:#757575; } .edit-site-add-new-template__template-list__contents>.components-button:hover,.edit-site-custom-template-modal__contents>.components-button:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-color:#0000; color:var(--wp-admin-theme-color-darker-10); } .edit-site-add-new-template__template-list__contents>.components-button:hover span,.edit-site-custom-template-modal__contents>.components-button:hover span{ color:var(--wp-admin-theme-color); } .edit-site-add-new-template__template-list__contents>.components-button:focus,.edit-site-custom-template-modal__contents>.components-button:focus{ border-color:#0000; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:3px solid #0000; } .edit-site-add-new-template__template-list__contents>.components-button:focus span:first-child,.edit-site-custom-template-modal__contents>.components-button:focus span:first-child{ color:var(--wp-admin-theme-color); } .edit-site-add-new-template__template-list__contents .edit-site-add-new-template__custom-template-button,.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__template-list__prompt,.edit-site-custom-template-modal__contents .edit-site-add-new-template__custom-template-button,.edit-site-custom-template-modal__contents .edit-site-add-new-template__template-list__prompt{ grid-column:1 / -1; } .edit-site-add-new-template__template-list__contents>.components-button{ align-items:flex-start; height:100%; text-align:start; } .edit-site-visual-editor__editor-canvas.is-focused{ outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-2); } .edit-site-canvas-loader{ align-items:center; display:flex; height:100%; justify-content:center; opacity:0; position:absolute; right:0; top:0; width:100%; } @media not (prefers-reduced-motion){ .edit-site-canvas-loader{ animation:edit-site-canvas-loader__fade-in-animation .5s ease .2s; animation-fill-mode:forwards; } } .edit-site-canvas-loader>div{ width:160px; } @keyframes edit-site-canvas-loader__fade-in-animation{ 0%{ opacity:0; } to{ opacity:1; } } .edit-site-global-styles-preview{ align-items:center; cursor:pointer; display:flex; justify-content:center; line-height:1; } .edit-site-global-styles-preview__wrapper{ display:block; max-width:100%; width:100%; } .edit-site-typography-preview{ align-items:center; background:#f0f0f0; border-radius:2px; display:flex; justify-content:center; margin-bottom:16px; min-height:100px; overflow:hidden; } .edit-site-font-size__item{ line-break:anywhere; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .edit-site-font-size__item-value{ color:#757575; } .edit-site-global-styles-screen{ margin:12px 16px 16px; } .edit-site-global-styles-screen-typography__indicator{ align-items:center; border-radius:1px; display:flex !important; font-size:14px; height:24px; justify-content:center; width:24px; } .edit-site-global-styles-screen-typography__font-variants-count{ color:#757575; } .edit-site-global-styles-font-families__manage-fonts{ justify-content:center; } .edit-site-global-styles-screen .color-block-support-panel{ border-top:none; padding-left:0; padding-right:0; padding-top:0; row-gap:12px; } .edit-site-global-styles-header__description{ padding:0 16px; } .edit-site-block-types-search{ margin-bottom:8px; padding:0 16px; } .edit-site-global-styles-header{ margin-bottom:0 !important; } .edit-site-global-styles-subtitle{ font-size:11px !important; font-weight:500 !important; margin-bottom:0 !important; text-transform:uppercase; } .edit-site-global-styles-section-title{ color:#2f2f2f; font-weight:600; line-height:1.2; margin:0; padding:16px 16px 0; } .edit-site-global-styles-icon-with-current-color{ fill:currentColor; } .edit-site-global-styles__color-indicator-wrapper{ flex-shrink:0; height:24px; } .edit-site-global-styles__shadows-panel__options-container,.edit-site-global-styles__shadows-panel__title{ height:24px; } .edit-site-global-styles__block-preview-panel{ border:1px solid #e0e0e0; border-radius:4px; overflow:hidden; position:relative; width:100%; } .edit-site-global-styles__shadow-preview-panel{ background-image:repeating-linear-gradient(-45deg, #f5f5f5 25%, #0000 0, #0000 75%, #f5f5f5 0, #f5f5f5), repeating-linear-gradient(-45deg, #f5f5f5 25%, #0000 0, #0000 75%, #f5f5f5 0, #f5f5f5); background-position:100% 0, right 8px top 8px; background-size:16px 16px; border:1px solid #e0e0e0; border-radius:4px; height:144px; overflow:auto; } .edit-site-global-styles__shadow-preview-panel .edit-site-global-styles__shadow-preview-block{ background-color:#fff; border:1px solid #e0e0e0; border-radius:2px; height:60px; width:60%; } .edit-site-global-styles__shadow-editor__dropdown-content{ width:280px; } .edit-site-global-styles__shadow-editor-panel{ margin-bottom:4px; } .edit-site-global-styles__shadow-editor__dropdown{ position:relative; width:100%; } .edit-site-global-styles__shadow-editor__dropdown-toggle{ border-radius:inherit; height:auto; padding-bottom:8px; padding-top:8px; text-align:right; width:100%; } .edit-site-global-styles__shadow-editor__dropdown-toggle.is-open{ background:#f0f0f0; color:var(--wp-admin-theme-color); } .edit-site-global-styles__shadow-editor__remove-button{ left:8px; opacity:0; position:absolute; top:8px; } .edit-site-global-styles__shadow-editor__remove-button.edit-site-global-styles__shadow-editor__remove-button{ border:none; } .edit-site-global-styles__shadow-editor__dropdown-toggle:hover+.edit-site-global-styles__shadow-editor__remove-button,.edit-site-global-styles__shadow-editor__remove-button:focus,.edit-site-global-styles__shadow-editor__remove-button:hover{ opacity:1; } @media (hover:none){ .edit-site-global-styles__shadow-editor__remove-button{ opacity:1; } } .edit-site-global-styles-screen-css{ display:flex; flex:1 1 auto; flex-direction:column; margin:16px; } .edit-site-global-styles-screen-css .components-v-stack{ flex:1 1 auto; } .edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input,.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{ display:flex; flex:1 1 auto; flex-direction:column; } .edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field .components-textarea-control__input{ direction:ltr; flex:1 1 auto; } .edit-site-global-styles-screen-css-help-link{ display:inline-block; margin-top:8px; } .edit-site-global-styles-screen-variations{ border-top:1px solid #ddd; margin-top:16px; } .edit-site-global-styles-screen-variations>*{ margin:24px 16px; } .edit-site-global-styles-sidebar__navigator-provider{ height:100%; } .edit-site-global-styles-sidebar__navigator-screen{ display:flex; flex-direction:column; height:100%; } .edit-site-global-styles-sidebar__navigator-screen .single-column{ grid-column:span 1; } .edit-site-global-styles-screen-root.edit-site-global-styles-screen-root,.edit-site-global-styles-screen-style-variations.edit-site-global-styles-screen-style-variations{ background:unset; color:inherit; } .edit-site-global-styles-sidebar__panel .block-editor-block-icon svg{ fill:currentColor; } .edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile,.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile .edit-site-global-styles-screen-root__active-style-tile-preview{ border-radius:2px; } .edit-site-global-styles-screen-revisions__revisions-list{ flex-grow:1; list-style:none; margin:0 16px 16px; } .edit-site-global-styles-screen-revisions__revisions-list li{ margin-bottom:0; } .edit-site-global-styles-screen-revisions__revision-item{ cursor:pointer; display:flex; flex-direction:column; position:relative; } .edit-site-global-styles-screen-revisions__revision-item[role=option]:active,.edit-site-global-styles-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 #0000; } .edit-site-global-styles-screen-revisions__revision-item:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .edit-site-global-styles-screen-revisions__revision-item:hover .edit-site-global-styles-screen-revisions__date{ color:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item:after,.edit-site-global-styles-screen-revisions__revision-item:before{ content:"\a"; display:block; position:absolute; } .edit-site-global-styles-screen-revisions__revision-item:before{ background:#ddd; border:4px solid #0000; border-radius:50%; height:8px; right:17px; top:18px; transform:translate(50%, -50%); width:8px; z-index:1; } .edit-site-global-styles-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 #0000; outline-offset:-2px; } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__date{ color:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true]:before{ background:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__changes>li,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__meta{ color:#1e1e1e; } .edit-site-global-styles-screen-revisions__revision-item:after{ border:.5px solid #ddd; height:100%; right:16px; top:0; width:0; } .edit-site-global-styles-screen-revisions__revision-item:first-child:after{ top:18px; } .edit-site-global-styles-screen-revisions__revision-item:last-child:after{ height:18px; } .edit-site-global-styles-screen-revisions__revision-item-wrapper{ display:block; padding:12px 40px 4px 12px; } .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__apply-button.is-primary{ align-self:flex-start; margin:4px 40px 12px 12px; } .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__changes,.edit-site-global-styles-screen-revisions__meta{ color:#757575; font-size:12px; } .edit-site-global-styles-screen-revisions__description{ align-items:flex-start; display:flex; flex-direction:column; gap:8px; } .edit-site-global-styles-screen-revisions__description .edit-site-global-styles-screen-revisions__date{ font-size:12px; font-weight:600; text-transform:uppercase; } .edit-site-global-styles-screen-revisions__meta{ align-items:flex-start; display:flex; justify-content:start; margin-bottom:4px; text-align:right; width:100%; } .edit-site-global-styles-screen-revisions__meta img{ border-radius:100%; height:16px; margin-left:8px; width:16px; } .edit-site-global-styles-screen-revisions__loading{ margin:24px auto !important; } .edit-site-global-styles-screen-revisions__changes{ line-height:1.4; list-style:disc; margin-right:12px; text-align:right; } .edit-site-global-styles-screen-revisions__changes li{ margin-bottom:4px; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination{ gap:2px; justify-content:space-between; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .edit-site-pagination__total{ height:1px; margin:-1px; overflow:hidden; position:absolute; right:-1000px; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-text{ font-size:12px; will-change:opacity; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary{ color:#1e1e1e; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary:disabled,.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{ color:#949494; } .edit-site-global-styles-screen-revisions__footer{ background:#fff; border-top:1px solid #ddd; bottom:0; height:56px; min-width:100%; padding:12px; position:sticky; z-index:1; } .editor-sidebar{ width:280px; } .editor-sidebar>.components-panel{ border-left:0; border-right:0; margin-bottom:-1px; margin-top:-1px; } .editor-sidebar>.components-panel>.components-panel__header{ background:#f0f0f0; } .editor-sidebar .block-editor-block-inspector__card{ margin:0; } .edit-site-global-styles-sidebar{ display:flex; flex-direction:column; min-height:100%; } .edit-site-global-styles-sidebar__panel{ flex:1; } .edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-title{ margin:0; } .edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-actions{ flex:1; } .edit-site-global-styles-sidebar .components-navigation__menu-title-heading{ font-size:15.6px; font-weight:500; } .edit-site-global-styles-sidebar .components-navigation__item>button span{ font-weight:500; } .edit-site-global-styles-sidebar .block-editor-panel-color-gradient-settings{ border:0; } .edit-site-global-styles-sidebar .single-column{ grid-column:span 1; } .edit-site-global-styles-sidebar .components-tools-panel .span-columns{ grid-column:1 / -1; } .edit-site-global-styles-sidebar__blocks-group{ border-top:1px solid #e0e0e0; padding-top:24px; } .edit-site-global-styles-sidebar__blocks-group-help{ padding:0 16px; } .edit-site-global-styles-color-palette-panel,.edit-site-global-styles-gradient-palette-panel{ padding:16px; } .edit-site-global-styles-sidebar hr{ margin:0; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon{ width:auto; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon svg{ display:none; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } .edit-site-page{ background:#fff; color:#2f2f2f; container:edit-site-page/inline-size; height:100%; } @media not (prefers-reduced-motion){ .edit-site-page{ transition:width .2s ease-out; } } .edit-site-page-header{ background:#fff; border-bottom:1px solid #f0f0f0; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-page-header{ transition:padding .1s ease-out; } } .edit-site-page-header .components-heading{ color:#1e1e1e; } .edit-site-page-header .edit-site-page-header__page-title{ min-height:40px; } .edit-site-page-header .edit-site-page-header__page-title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-page-header .edit-site-page-header__sub-title{ margin-bottom:8px; } @container (max-width: 430px){ .edit-site-page-header{ padding:16px 24px; } } .edit-site-page-content{ display:flex; flex-flow:column; height:100%; position:relative; z-index:1; } .edit-site-patterns__delete-modal{ width:384px; } .page-patterns-preview-field{ align-items:center; border-radius:4px; display:flex; flex-direction:column; height:100%; justify-content:center; } .dataviews-view-grid .page-patterns-preview-field .block-editor-block-preview__container{ height:100%; } .dataviews-view-table .page-patterns-preview-field{ flex-grow:0; text-wrap:balance; text-wrap:pretty; width:96px; } .edit-site-patterns__pattern-icon{ fill:var(--wp-block-synced-color); flex-shrink:0; } .edit-site-patterns__section-header{ border-bottom:1px solid #f0f0f0; flex-shrink:0; min-height:40px; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-patterns__section-header{ transition:padding .1s ease-out; } } .edit-site-patterns__section-header .edit-site-patterns__title{ min-height:40px; } .edit-site-patterns__section-header .edit-site-patterns__title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-patterns__section-header .edit-site-patterns__sub-title{ margin-bottom:8px; } .edit-site-patterns__section-header .screen-reader-shortcut:focus{ top:0; } .edit-site-page-patterns-dataviews .dataviews-view-grid__badge-fields .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully){ background:rgba(var(--wp-block-synced-color--rgb), .04); color:var(--wp-block-synced-color); } .dataviews-action-modal__duplicate-pattern [role=dialog]>[role=document]{ width:350px; } .dataviews-action-modal__duplicate-pattern .patterns-menu-items__convert-modal-categories{ position:relative; } .dataviews-action-modal__duplicate-pattern .components-form-token-field__suggestions-list:not(:empty){ background-color:#fff; border:1px solid var(--wp-admin-theme-color); border-bottom-left-radius:2px; border-bottom-right-radius:2px; box-shadow:0 0 .5px .5px var(--wp-admin-theme-color); box-sizing:border-box; max-height:96px; min-width:auto; position:absolute; right:-1px; width:calc(100% + 2px); z-index:1; } @media (min-width:600px){ .dataviews-action-modal__duplicate-template-part .components-modal__frame{ max-width:500px; } } @container (max-width: 430px){ .edit-site-page-patterns-dataviews .edit-site-patterns__section-header{ padding-left:24px; padding-right:24px; } } .page-templates-preview-field{ align-items:center; border-radius:4px; display:flex; flex-direction:column; height:100%; justify-content:center; width:100%; } .dataviews-view-list .page-templates-preview-field .block-editor-block-preview__container{ height:120px; } .dataviews-view-grid .page-templates-preview-field .block-editor-block-preview__container{ height:100%; } .dataviews-view-table .page-templates-preview-field{ max-height:160px; position:relative; text-wrap:balance; text-wrap:pretty; width:120px; } .dataviews-view-table .page-templates-preview-field:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; position:absolute; right:0; top:0; width:100%; } .page-templates-description{ max-width:50em; text-wrap:balance; text-wrap:pretty; } .dataviews-view-table .page-templates-description{ display:block; margin-bottom:8px; } .edit-site-page-templates .dataviews-pagination{ z-index:2; } .page-templates-author-field__avatar{ align-items:center; display:flex; flex-shrink:0; height:24px; justify-content:right; overflow:hidden; width:24px; } .page-templates-author-field__avatar img{ border-radius:100%; height:16px; object-fit:cover; opacity:0; width:16px; } @media not (prefers-reduced-motion){ .page-templates-author-field__avatar img{ transition:opacity .1s linear; } } .page-templates-author-field__avatar.is-loaded img{ opacity:1; } .page-templates-author-field__icon{ display:flex; flex-shrink:0; height:24px; width:24px; } .page-templates-author-field__icon svg{ margin-right:-4px; fill:currentColor; } .page-templates-author-field__name{ overflow:hidden; text-overflow:ellipsis; } .edit-site-list__rename-modal{ z-index:1000001; } @media (min-width:782px){ .edit-site-list__rename-modal .components-base-control{ width:320px; } } .edit-site-editor__editor-interface{ opacity:1; } @media not (prefers-reduced-motion){ .edit-site-editor__editor-interface{ transition:opacity .1s ease-out; } } .edit-site-editor__editor-interface.is-loading{ opacity:0; } .edit-site-editor__toggle-save-panel{ background-color:#fff; border:1px dotted #ddd; box-sizing:border-box; display:flex; justify-content:center; padding:24px; width:280px; } .edit-site-editor__view-mode-toggle{ view-transition-name:toggle; height:60px; right:0; top:0; width:60px; z-index:100; } .edit-site-editor__view-mode-toggle .components-button{ align-items:center; border-radius:0; color:#fff; display:flex; height:100%; justify-content:center; overflow:hidden; padding:0; width:100%; } .edit-site-editor__view-mode-toggle .components-button:active,.edit-site-editor__view-mode-toggle .components-button:hover{ color:#fff; } .edit-site-editor__view-mode-toggle .components-button:focus{ box-shadow:none; } .edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon img,.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon svg{ background:#1e1e1e; display:block; } .edit-site-editor__back-icon{ align-items:center; background-color:#ccc; display:flex; height:60px; justify-content:center; pointer-events:none; position:absolute; right:0; top:0; width:60px; } .edit-site-editor__back-icon svg{ fill:currentColor; } .edit-site-editor__back-icon.has-site-icon{ -webkit-backdrop-filter:saturate(180%) blur(15px); backdrop-filter:saturate(180%) blur(15px); background-color:#fff9; } .edit-site-welcome-guide{ width:312px; } .edit-site-welcome-guide.guide-editor .edit-site-welcome-guide__image,.edit-site-welcome-guide.guide-styles .edit-site-welcome-guide__image{ background:#00a0d2; } .edit-site-welcome-guide.guide-page .edit-site-welcome-guide__video{ border-left:16px solid #3858e9; border-top:16px solid #3858e9; } .edit-site-welcome-guide.guide-template .edit-site-welcome-guide__video{ border-right:16px solid #3858e9; border-top:16px solid #3858e9; } .edit-site-welcome-guide__image{ margin:0 0 16px; } .edit-site-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-site-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-site-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 16px; padding:0 32px; } .edit-site-welcome-guide__text img{ vertical-align:bottom; } .edit-site-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-site-layout{ color:#ccc; display:flex; flex-direction:column; height:100%; } .edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{ background:#1e1e1e; } .edit-site-layout__content{ display:flex; flex-grow:1; height:100%; } .edit-site-layout__sidebar-region{ flex-shrink:0; width:100vw; z-index:1; } @media (min-width:782px){ .edit-site-layout__sidebar-region{ width:300px; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{ height:100vh; position:fixed !important; right:0; top:0; } .edit-site-layout__sidebar-region .edit-site-layout__sidebar{ display:flex; flex-direction:column; height:100%; } .edit-site-layout__sidebar-region .resizable-editor__drag-handle{ left:0; } .edit-site-layout__main{ display:flex; flex-direction:column; flex-grow:1; overflow:hidden; } .edit-site-layout__mobile{ display:flex; flex-direction:column; position:relative; width:100%; z-index:2; } .edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{ padding:0; } .edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{ padding:0 12px; } .edit-site-layout__canvas-container{ flex-grow:1; overflow:visible; position:relative; z-index:2; } .edit-site-layout__canvas-container.is-resizing:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:100; } .edit-site-layout__canvas{ align-items:center; bottom:0; display:flex; justify-content:center; position:absolute; right:0; top:0; width:100%; } .edit-site-layout__canvas.is-right-aligned{ justify-content:flex-end; } .edit-site-layout__canvas .edit-site-resizable-frame__inner{ color:#1e1e1e; } @media (min-width:782px){ .edit-site-layout__canvas{ bottom:16px; top:16px; width:calc(100% - 16px); } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; overflow:hidden; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ transition:border-radius,box-shadow .4s; } } @media (min-width:782px){ .edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ border-radius:8px; } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; } } .edit-site-layout.is-full-canvas .edit-site-layout__canvas{ bottom:0; top:0; width:100%; } .edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{ min-height:100% !important; position:relative !important; } .edit-site-template-pages-preview{ height:100%; } html.canvas-mode-edit-transition::view-transition-group(toggle){ animation-delay:255ms; } @media (prefers-reduced-motion){ ::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){ animation:none !important; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{ display:none; } .edit-site-layout__view-mode-toggle.components-button{ view-transition-name:toggle; align-items:center; background:#1e1e1e; border-radius:0; color:#fff; display:flex; height:60px; justify-content:center; overflow:hidden; padding:0; position:relative; width:60px; } .edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{ color:#fff; } .edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{ box-shadow:0 0 0 3px #1e1e1e, 0 0 0 6px var(--wp-admin-theme-color); outline:4px solid #0000; outline-offset:4px; } .edit-site-layout__view-mode-toggle.components-button:before{ border-radius:4px; bottom:9px; box-shadow:none; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } @media not (prefers-reduced-motion){ .edit-site-layout__view-mode-toggle.components-button:before{ transition:box-shadow .1s ease; } } .edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{ align-items:center; display:flex; height:60px; justify-content:center; width:60px; } .edit-site-layout__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:0; position:fixed !important; right:auto; top:-9999em; width:280px; z-index:100000; } .edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{ bottom:0; top:auto; } .edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{ top:0; } @media (min-width:782px){ .edit-site-layout__actions{ border-right:1px solid #ddd; } } .edit-site-layout__area{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; flex-grow:1; margin:0; overflow:hidden; } @media (min-width:782px){ .edit-site-layout__area{ border-radius:8px; margin:16px 0 16px 16px; } } .edit-site .components-editor-notices__snackbar{ bottom:16px; left:0; padding-left:16px; padding-right:16px; position:fixed; } .edit-site-save-hub{ border-top:1px solid #2f2f2f; color:#949494; flex-shrink:0; margin:0; padding:16px; } .edit-site-save-hub__button{ color:inherit; justify-content:center; width:100%; } .edit-site-save-hub__button[aria-disabled=true]{ opacity:1; } .edit-site-save-hub__button[aria-disabled=true]:hover{ color:inherit; } .edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{ color:#1e1e1e; } @media (min-width:600px){ .edit-site-save-panel__modal{ width:600px; } } .edit-site-sidebar__content{ contain:content; flex-grow:1; overflow-x:hidden; overflow-y:auto; } @keyframes _x51ri_slide-from-right{ 0%{ opacity:0; transform:translateX(-50px); } to{ opacity:1; transform:none; } } @keyframes _x51ri_slide-from-left{ 0%{ opacity:0; transform:translateX(50px); } to{ opacity:1; transform:none; } } .edit-site-sidebar__screen-wrapper{ animation-duration:.14s; animation-timing-function:ease-in-out; display:flex; flex-direction:column; height:100%; max-height:100%; overflow-x:auto; padding:0 12px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:stable; scrollbar-width:thin; will-change:transform; will-change:transform, opacity; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar{ height:12px; width:12px; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{ background-color:initial; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{ background-color:#757575; } .edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{ scrollbar-color:#757575 #0000; } @media (hover:none){ .edit-site-sidebar__screen-wrapper{ scrollbar-color:#757575 #0000; } } @media (prefers-reduced-motion:reduce){ .edit-site-sidebar__screen-wrapper{ animation-duration:0s; } } .edit-site-sidebar__screen-wrapper.slide-from-left{ animation-name:_x51ri_slide-from-left; } .edit-site-sidebar__screen-wrapper.slide-from-right{ animation-name:_x51ri_slide-from-right; } .edit-site-sidebar-button{ color:#e0e0e0; flex-shrink:0; } .edit-site-sidebar-button:focus:not(:disabled){ box-shadow:none; outline:none; } .edit-site-sidebar-button:focus-visible:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:3px solid #0000; } .edit-site-sidebar-button:focus,.edit-site-sidebar-button:focus-visible,.edit-site-sidebar-button:hover:not(:disabled,[aria-disabled=true]),.edit-site-sidebar-button:not(:disabled,[aria-disabled=true]):active,.edit-site-sidebar-button[aria-expanded=true]{ color:#f0f0f0; } .edit-site-sidebar-navigation-item.components-item{ border:none; color:#949494; min-height:40px; padding:8px 16px 8px 6px; } .edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-item.components-item[aria-current=true]{ color:#e0e0e0; } .edit-site-sidebar-navigation-item.components-item:focus .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item:hover .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item[aria-current=true] .edit-site-sidebar-navigation-item__drilldown-indicator{ fill:#e0e0e0; } .edit-site-sidebar-navigation-item.components-item[aria-current=true]{ background:#2f2f2f; color:#fff; font-weight:500; } .edit-site-sidebar-navigation-item.components-item:focus-visible{ transform:translateZ(0); } .edit-site-sidebar-navigation-item.components-item .edit-site-sidebar-navigation-item__drilldown-indicator{ fill:#949494; } .edit-site-sidebar-navigation-item.components-item.with-suffix{ padding-left:16px; } .edit-site-sidebar-navigation-screen__content .block-editor-list-view-block-select-button{ cursor:grab; padding:8px 0 8px 8px; } .edit-site-sidebar-navigation-screen{ display:flex; flex-direction:column; overflow-x:unset !important; position:relative; } .edit-site-sidebar-navigation-screen__main{ flex-grow:1; margin-bottom:16px; } .edit-site-sidebar-navigation-screen__main.has-footer{ margin-bottom:0; } .edit-site-sidebar-navigation-screen__content{ padding:0 16px; } .edit-site-sidebar-navigation-screen__content .components-text{ color:#ccc; } .edit-site-sidebar-navigation-screen__content .components-heading{ margin-bottom:8px; } .edit-site-sidebar-navigation-screen__title-icon{ background:#1e1e1e; margin-bottom:8px; padding-bottom:8px; padding-top:48px; position:sticky; top:0; z-index:1; } .edit-site-sidebar-navigation-screen__title{ flex-grow:1; overflow-wrap:break-word; } .edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title,.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title .edit-site-sidebar-navigation-screen__title{ line-height:32px; } .edit-site-sidebar-navigation-screen__actions{ display:flex; flex-shrink:0; } @media (min-width:782px){ .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variation-container{ max-width:292px; } } .edit-site-global-styles-variation-title{ color:#ddd; font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ outline-color:#ffffff0d; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{ outline-color:#ffffff26; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview{ outline-color:#fff; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:var(--wp-admin-theme-color); } .edit-site-sidebar-navigation-screen__footer{ background-color:#1e1e1e; border-top:1px solid #2f2f2f; bottom:0; gap:0; margin:16px 0 0; padding:8px 16px; position:sticky; } .edit-site-sidebar-navigation-screen__footer .edit-site-sidebar-navigation-screen-details-footer{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen__input-control{ width:100%; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__container{ background:#2f2f2f; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__container .components-button{ color:#e0e0e0 !important; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__input{ background:#2f2f2f !important; color:#e0e0e0 !important; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__backdrop{ border:4px !important; } .edit-site-sidebar-navigation-screen__input-control .components-base-control__help{ color:#949494; } .edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item[aria-current]{ background:none; } .sidebar-navigation__more-menu .components-button{ color:#e0e0e0; } .sidebar-navigation__more-menu .components-button:focus,.sidebar-navigation__more-menu .components-button:hover,.sidebar-navigation__more-menu .components-button[aria-current]{ color:#f0f0f0; } .edit-site-sidebar-navigation-screen-patterns__group{ margin-bottom:24px; margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-patterns__group:last-of-type{ border-bottom:0; margin-bottom:0; padding-bottom:0; } .edit-site-sidebar-navigation-screen-patterns__group-header{ margin-top:16px; } .edit-site-sidebar-navigation-screen-patterns__group-header p{ color:#949494; } .edit-site-sidebar-navigation-screen-patterns__group-header h2{ font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-navigation-screen-patterns__divider{ border-top:1px solid #2f2f2f; margin:16px 0; } .edit-site-sidebar-navigation-screen__description{ margin:0 0 32px; } .edit-site-sidebar-navigation-screen-navigation-menus{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell{ width:100%; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{ white-space:normal; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__title{ margin-top:3px; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu-cell{ padding-left:0; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button{ color:#949494; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:hover,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button[aria-current]{ color:#fff; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu{ color:#949494; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:hover{ color:#fff; } .edit-site-sidebar-navigation-screen-navigation-menus__loading.components-spinner{ display:block; margin-left:auto; margin-right:auto; } .edit-site-sidebar-navigation-screen-navigation-menus__helper-block-editor{ display:none; } .edit-site-sidebar-navigation-screen-main,.edit-site-sidebar-navigation-screen-templates-browse{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-dataviews__group-header{ margin-top:32px; } .edit-site-sidebar-navigation-screen-dataviews__group-header h2{ font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-dataviews{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-dataviews__custom-items .edit-site-sidebar-dataviews-dataview-item{ padding-left:8px; } .edit-site-sidebar-dataviews-dataview-item{ border-radius:2px; } .edit-site-sidebar-dataviews-dataview-item .edit-site-sidebar-dataviews-dataview-item__dropdown-menu{ min-width:auto; } .edit-site-sidebar-dataviews-dataview-item:focus,.edit-site-sidebar-dataviews-dataview-item:hover,.edit-site-sidebar-dataviews-dataview-item[aria-current]{ color:#e0e0e0; } .edit-site-sidebar-dataviews-dataview-item.is-selected{ background:#2f2f2f; color:#fff; font-weight:500; } .edit-site-site-hub{ align-items:center; display:flex; gap:8px; height:60px; justify-content:space-between; margin-left:12px; } .edit-site-site-hub__actions{ flex-shrink:0; } .edit-site-site-hub__view-mode-toggle-container{ flex-shrink:0; height:60px; width:60px; } .edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{ background:#0000; } .edit-site-site-hub__title .components-button{ color:#e0e0e0; display:block; flex-grow:1; font-size:15px; font-weight:500; margin-right:-4px; overflow:hidden; padding-left:16px; position:relative; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{ color:#e0e0e0; } .edit-site-site-hub__title .components-button:focus{ box-shadow:none; outline:none; } .edit-site-site-hub__title .components-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .edit-site-site-hub__title .components-button:after{ content:"↗"; font-weight:400; left:0; opacity:0; position:absolute; } @media not (prefers-reduced-motion){ .edit-site-site-hub__title .components-button:after{ transition:opacity .1s linear; } } .edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{ opacity:1; } .edit-site-site-hub_toggle-command-center{ color:#e0e0e0; } .edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{ fill:#f0f0f0; } .edit-site-site-icon__icon{ fill:currentColor; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__icon{ padding:12px; } .edit-site-site-icon__image{ aspect-ratio:1/1; background:#333; height:100%; object-fit:cover; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__image{ border-radius:0; } .edit-site-editor__view-mode-toggle button:focus{ position:relative; } .edit-site-editor__view-mode-toggle button:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff; content:""; display:block; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-site-style-book{ align-items:stretch; display:flex; flex-direction:column; height:100%; } .edit-site-style-book.is-button{ border-radius:8px; } .edit-site-style-book__iframe{ display:block; height:100%; width:100%; } .edit-site-style-book__iframe.is-button{ border-radius:8px; } .edit-site-style-book__iframe.is-focused{ outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-2); } .edit-site-style-book__tablist-container{ background:#fff; display:flex; flex:none; padding-left:56px; width:100%; } .edit-site-style-book__tabpanel{ flex:1 0 auto; overflow:auto; } .edit-site-editor-canvas-container{ background-color:#ddd; height:100%; } .edit-site-editor-canvas-container iframe{ display:block; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{ padding:24px 24px 0; } .edit-site-editor-canvas-container__section{ background:#fff; border-radius:8px; bottom:0; left:0; overflow:hidden; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .edit-site-editor-canvas-container__section{ transition:all .3s; } } .edit-site-editor-canvas-container__close-button{ background:#fff; left:8px; position:absolute; top:8px; z-index:2; } .edit-site-post-edit{ padding:24px; } .edit-site-post-edit.is-empty .edit-site-page-content{ align-items:center; display:flex; justify-content:center; } .dataforms-layouts-panel__field-dropdown .fields-controls__password{ border-top:1px solid #e0e0e0; padding-top:16px; } .edit-site-post-list__featured-image{ height:100%; object-fit:cover; width:100%; } .edit-site-post-list__featured-image-wrapper{ border-radius:4px; height:100%; width:100%; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){ background-color:#f0f0f0; border-radius:4px; display:block; flex-grow:0 !important; height:32px; overflow:hidden; position:relative; width:32px; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; position:absolute; right:0; top:0; width:100%; } .edit-site-post-list__featured-image-button{ background-color:unset; border:none; border-radius:4px; box-shadow:none; box-sizing:border-box; cursor:pointer; height:100%; overflow:hidden; padding:0; width:100%; } .edit-site-post-list__featured-image-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{ background:rgba(var(--wp-admin-theme-color--rgb), .04); box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .edit-site-post-list__status-icon{ height:24px; width:24px; } .edit-site-post-list__status-icon svg{ fill:currentColor; margin-right:-4px; } .edit-site-resizable-frame__inner{ position:relative; } body:has(.edit-site-resizable-frame__inner.is-resizing){ cursor:col-resize; user-select:none; -webkit-user-select:none; } .edit-site-resizable-frame__inner.is-resizing:before{ content:""; inset:0; position:absolute; z-index:1; } .edit-site-resizable-frame__inner-content{ inset:0; position:absolute; z-index:0; } .edit-site-resizable-frame__handle{ align-items:center; background-color:#75757566; border:0; border-radius:4px; cursor:col-resize; display:flex; height:64px; justify-content:flex-end; padding:0; position:absolute; top:calc(50% - 32px); width:4px; z-index:100; } .edit-site-resizable-frame__handle:before{ content:""; height:100%; position:absolute; right:100%; width:32px; } .edit-site-resizable-frame__handle:after{ content:""; height:100%; left:100%; position:absolute; width:32px; } .edit-site-resizable-frame__handle:focus-visible{ outline:2px solid #0000; } .edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{ background-color:var(--wp-admin-theme-color); } .edit-site-push-changes-to-global-styles-control .components-button{ justify-content:center; width:100%; } @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:70px; padding-top:0; } .font-library-modal .font-library-modal__subtitle{ font-size:11px; font-weight:500; text-transform:uppercase; } .font-library-modal .components-navigator-screen{ padding:3px; } .font-library-modal__tabpanel-layout{ margin-top:32px; } .font-library-modal__tabpanel-layout .font-library-modal__loading{ align-items:center; display:flex; height:100%; justify-content:center; padding-top:120px; position:absolute; right:0; top:0; width:100%; } .font-library-modal__footer{ background-color:#fff; border-top:1px solid #ddd; bottom:32px; height:70px; margin:0 -32px -32px; padding:16px 32px; position:absolute; width:100%; } .font-library-modal__page-selection{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .font-library-modal__page-selection .components-select-control__input{ font-size:11px !important; font-weight:500; } } .font-library-modal__tabpanel-layout .components-base-control__field{ margin-bottom:0; } .font-library-modal__fonts-title{ font-size:11px; font-weight:600; text-transform:uppercase; } .font-library-modal__fonts-list,.font-library-modal__fonts-title{ margin-bottom:0; margin-top:0; } .font-library-modal__fonts-list-item{ margin-bottom:0; } .font-library-modal__font-card{ border:1px solid #e0e0e0; height:auto !important; margin-top:-1px; padding:16px; width:100%; } .font-library-modal__font-card:hover{ background-color:#f0f0f0; } .font-library-modal__font-card .font-library-modal__font-card__name{ font-weight:700; } .font-library-modal__font-card .font-library-modal__font-card__count{ color:#757575; } .font-library-modal__font-card .font-library-modal__font-variant_demo-image{ display:block; height:24px; width:auto; } .font-library-modal__font-card .font-library-modal__font-variant_demo-text{ flex-shrink:0; white-space:nowrap; } @media not (prefers-reduced-motion){ .font-library-modal__font-card .font-library-modal__font-variant_demo-text{ transition:opacity .3s ease-in-out; } } .font-library-modal__font-variant{ border-bottom:1px solid #e0e0e0; padding-bottom:16px; } .font-library-modal__tablist-container{ background:#fff; border-bottom:1px solid #ddd; margin:0 -32px; padding:0 16px; position:sticky; top:0; z-index:1; } .font-library-modal__tablist-container [role=tablist]{ margin-bottom:-1px; } .font-library-modal__upload-area{ align-items:center; display:flex; height:256px !important; justify-content:center; width:100%; } button.font-library-modal__upload-area{ background-color:#f0f0f0; } .font-library-modal__local-fonts{ margin:0 auto; width:80%; } .font-library-modal__local-fonts .font-library-modal__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-modal__select-all{ padding:16px 17px 16px 16px; } .font-library-modal__select-all .components-checkbox-control__label{ padding-right:16px; } .edit-site-pagination .components-button.is-tertiary{ height:32px; justify-content:center; width:32px; } .edit-site-global-styles-variations_item{ box-sizing:border-box; cursor:pointer; } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ border-radius:2px; outline:1px solid #0000001a; outline-offset:-1px; overflow:hidden; position:relative; } @media not (prefers-reduced-motion){ .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ transition:outline .1s linear; } } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill{ height:32px; } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill .block-editor-iframe__scale-container{ overflow:hidden; } .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{ outline-color:#0000004d; } .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview,.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:#1e1e1e; outline-offset:1px; outline-width:var(--wp-admin-border-width-focus); } .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:var(--wp-admin-theme-color); } .edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root{ box-shadow:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root>div>hr{ display:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider{ overflow-y:auto; padding-left:0; padding-right:0; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .components-tools-panel{ border-top:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .edit-site-global-styles-sidebar__navigator-screen{ outline:none; padding:12px; } .edit-site-styles .edit-site-page-content .edit-site-page-header{ padding-left:48px; padding-right:48px; } @container (max-width: 430px){ .edit-site-styles .edit-site-page-content .edit-site-page-header{ padding-left:24px; padding-right:24px; } } .edit-site-styles .edit-site-page-content .edit-site-sidebar-button{ color:#1e1e1e; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon{ padding:0 8px; width:auto; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon svg{ display:none; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } ::view-transition-image-pair(root){ isolation:auto; } ::view-transition-new(root),::view-transition-old(root){ animation:none; display:block; mix-blend-mode:normal; } body.js #wpadminbar{ display:none; } body.js #wpbody{ padding-top:0; } body.js.appearance_page_gutenberg-template-parts,body.js.site-editor-php{ background:#fff; } body.js.appearance_page_gutenberg-template-parts #wpcontent,body.js.site-editor-php #wpcontent{ padding-right:0; } body.js.appearance_page_gutenberg-template-parts #wpbody-content,body.js.site-editor-php #wpbody-content{ padding-bottom:0; } body.js.appearance_page_gutenberg-template-parts #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.appearance_page_gutenberg-template-parts #wpfooter,body.js.site-editor-php #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.site-editor-php #wpfooter{ display:none; } body.js.appearance_page_gutenberg-template-parts .a11y-speak-region,body.js.site-editor-php .a11y-speak-region{ right:-1px; top:-1px; } body.js.appearance_page_gutenberg-template-parts ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-template-parts ul#adminmenu>li.current>a.current:after,body.js.site-editor-php ul#adminmenu a.wp-has-current-submenu:after,body.js.site-editor-php ul#adminmenu>li.current>a.current:after{ border-left-color:#fff; } body.js.appearance_page_gutenberg-template-parts .media-frame select.attachment-filters:last-of-type,body.js.site-editor-php .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } body.js.site-editor-php{ background:#1e1e1e; } .edit-site{ box-sizing:border-box; height:100vh; } .edit-site *,.edit-site :after,.edit-site :before{ box-sizing:inherit; } @media (min-width:600px){ .edit-site{ bottom:0; left:0; min-height:100vh; position:fixed; right:0; top:0; } } .no-js .edit-site{ min-height:0; position:static; } .edit-site .interface-interface-skeleton{ top:0; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .dataviews-wrapper{ box-sizing:border-box; container:dataviews-wrapper/inline-size; display:flex; flex-direction:column; font-size:13px; height:100%; line-height:1.4; overflow:auto; scroll-padding-bottom:64px; } .dataviews-filters__container,.dataviews__view-actions{ box-sizing:border-box; flex-shrink:0; left:0; padding:16px 48px; position:sticky; } @media not (prefers-reduced-motion){ .dataviews-filters__container,.dataviews__view-actions{ transition:padding .1s ease-out; } } .dataviews-loading,.dataviews-no-results{ align-items:center; display:flex; flex-grow:1; justify-content:center; padding:0 48px; } @media not (prefers-reduced-motion){ .dataviews-loading,.dataviews-no-results{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-filters__container,.dataviews__view-actions{ padding:12px 24px; } .dataviews-loading,.dataviews-no-results{ padding-left:24px; padding-right:24px; } } .dataviews-title-field{ font-size:13px; font-weight:500; width:100%; } .dataviews-title-field,.dataviews-title-field a{ color:#2f2f2f; text-overflow:ellipsis; white-space:nowrap; } .dataviews-title-field a{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; } .dataviews-title-field a:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field a:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-title-field button.components-button.is-link{ color:#1e1e1e; display:block; font-weight:inherit; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; width:100%; } .dataviews-title-field button.components-button.is-link:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable{ color:#2f2f2f; cursor:pointer; } .dataviews-title-field--clickable:hover{ color:var(--wp-admin-theme-color); } .dataviews-title-field--clickable:focus{ border-radius:2px; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color, #007cba); color:var(--wp-admin-theme-color--rgb); } .dataviews-bulk-actions-footer__item-count{ color:#1e1e1e; font-size:11px; font-weight:500; text-transform:uppercase; } .dataviews-bulk-actions-footer__container{ margin-right:auto; min-height:32px; } .dataviews-filters__button{ position:relative; } .dataviews-filters__container{ padding-top:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true],.dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:hover{ opacity:0; } .dataviews-filters__reset-button.dataviews-filters__reset-button[aria-disabled=true]:focus{ opacity:1; } .dataviews-filters__summary-popover{ font-size:13px; line-height:1.4; } .dataviews-filters__summary-popover .components-popover__content{ border-radius:4px; width:230px; } .dataviews-filters__summary-popover.components-dropdown__content .components-popover__content{ padding:0; } .dataviews-filters__summary-operators-container{ padding:8px 8px 0; } .dataviews-filters__summary-operators-container:has(+.dataviews-filters__search-widget-listbox){ border-bottom:1px solid #e0e0e0; padding-bottom:8px; } .dataviews-filters__summary-operators-container:empty{ display:none; } .dataviews-filters__summary-operators-container .dataviews-filters__summary-operators-filter-name{ color:#757575; } .dataviews-filters__summary-chip-container{ position:relative; white-space:pre-wrap; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip{ align-items:center; background:#f0f0f0; border:1px solid #0000; border-radius:16px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:flex; min-height:32px; padding:4px 12px; position:relative; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-reset{ padding-inline-end:28px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip[aria-expanded=true]{ background:#e0e0e0; color:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values{ background:rgba(var(--wp-admin-theme-color--rgb), .04); color:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values:hover,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip.has-values[aria-expanded=true]{ background:rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip .dataviews-filters-__summary-filter-text-name{ font-weight:500; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove{ align-items:center; background:#0000; border:0; border-radius:50%; cursor:pointer; display:flex; height:24px; justify-content:center; padding:0; position:absolute; right:4px; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove svg{ fill:#757575; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover{ background:#e0e0e0; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus svg,.dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:hover svg{ fill:#1e1e1e; } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values svg{ fill:var(--wp-admin-theme-color); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove.has-values:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-filters__summary-chip-container .dataviews-filters__summary-chip-remove:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:none; } .dataviews-filters__search-widget-filter-combobox-list{ border-top:1px solid #e0e0e0; max-height:184px; overflow:auto; padding:4px; } .dataviews-filters__search-widget-filter-combobox-list .dataviews-filters__search-widget-filter-combobox-item-value [data-user-value]{ font-weight:600; } .dataviews-filters__search-widget-listbox{ overflow:auto; padding:4px; } .dataviews-filters__search-widget-listitem{ align-items:center; border-radius:2px; box-sizing:border-box; cursor:default; display:flex; gap:8px; margin-block-end:2px; padding:8px 12px; } .dataviews-filters__search-widget-listitem:last-child{ margin-block-end:0; } .dataviews-filters__search-widget-listitem:focus,.dataviews-filters__search-widget-listitem:hover,.dataviews-filters__search-widget-listitem[data-active-item]{ background-color:var(--wp-admin-theme-color); color:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-check,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-check{ fill:#fff; } .dataviews-filters__search-widget-listitem:focus .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem:hover .dataviews-filters__search-widget-listitem-description,.dataviews-filters__search-widget-listitem[data-active-item] .dataviews-filters__search-widget-listitem-description{ color:#fff; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-check{ flex-shrink:0; height:24px; width:24px; } .dataviews-filters__search-widget-listitem .dataviews-filters__search-widget-listitem-description{ color:#757575; display:block; font-size:12px; line-height:16px; overflow:hidden; text-overflow:ellipsis; } .dataviews-filters__search-widget-filter-combobox__wrapper{ padding:8px; position:relative; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ background:#f0f0f0; border:none; border-radius:2px; box-shadow:0 0 0 #0000; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin-left:0; margin-right:0; padding:0 32px 0 8px; width:100%; } @media not (prefers-reduced-motion){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; line-height:normal; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-input-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-moz-placeholder{ color:#1e1e1e9e; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input{ font-size:13px; } } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input:focus{ background:#fff; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::placeholder{ color:#757575; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-cancel-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-decoration,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-button,.dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__input::-webkit-search-results-decoration{ -webkit-appearance:none; } .dataviews-filters__search-widget-filter-combobox__wrapper .dataviews-filters__search-widget-filter-combobox__icon{ align-items:center; display:flex; justify-content:center; position:absolute; right:12px; top:50%; transform:translateY(-50%); width:24px; } .dataviews-filters__container-visibility-toggle{ flex-shrink:0; position:relative; } .dataviews-filters-toggle__count{ background:var(--wp-admin-theme-color, #3858e9); border-radius:8px; box-sizing:border-box; color:#fff; font-size:11px; height:16px; line-height:16px; min-width:16px; outline:var(--wp-admin-border-width-focus) solid #fff; padding:0 4px; position:absolute; right:0; text-align:center; top:0; transform:translate(50%, -50%); } .dataviews-search{ width:fit-content; } .dataviews-footer{ background-color:#fff; border-top:1px solid #f0f0f0; bottom:0; flex-shrink:0; left:0; padding:12px 48px; position:sticky; z-index:2; } @media not (prefers-reduced-motion){ .dataviews-footer{ transition:padding .1s ease-out; } } @container (max-width: 430px){ .dataviews-footer{ padding:12px 24px; } } @container (max-width: 560px){ .dataviews-footer{ flex-direction:column !important; } .dataviews-footer .dataviews-bulk-actions-footer__container{ width:100%; } .dataviews-footer .dataviews-bulk-actions-footer__item-count{ flex-grow:1; } .dataviews-footer .dataviews-pagination{ justify-content:space-between; width:100%; } } .dataviews-pagination__page-select{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .dataviews-pagination__page-select .components-select-control__input{ font-size:11px !important; font-weight:500; } } .dataviews-action-modal{ z-index:1000001; } .dataviews-selection-checkbox{ --checkbox-input-size:24px; flex-shrink:0; line-height:0; } @media (min-width:600px){ .dataviews-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-selection-checkbox .components-checkbox-control__input-container{ margin:0; } .dataviews-view-config{ container-type:inline-size; font-size:13px; line-height:1.4; width:320px; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper{ height:100%; overflow-y:scroll; } .dataviews-config__popover.is-expanded .dataviews-config__popover-content-wrapper .dataviews-view-config{ width:auto; } .dataviews-view-config__sort-direction .components-toggle-group-control-option-base{ text-transform:uppercase; } .dataviews-settings-section__title.dataviews-settings-section__title{ font-size:15px; line-height:24px; } .dataviews-settings-section__sidebar{ grid-column:span 4; } .dataviews-settings-section__content,.dataviews-settings-section__content>*{ grid-column:span 8; } .dataviews-settings-section__content .is-divided-in-two{ display:contents; } .dataviews-settings-section__content .is-divided-in-two>*{ grid-column:span 4; } .dataviews-settings-section:has(.dataviews-settings-section__content:empty){ display:none; } @container (max-width: 500px){ .dataviews-settings-section.dataviews-settings-section{ grid-template-columns:repeat(2, 1fr); } .dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__content,.dataviews-settings-section.dataviews-settings-section .dataviews-settings-section__sidebar{ grid-column:span 2; } } .dataviews-field-control__field{ height:32px; } .dataviews-field-control__actions{ position:absolute; top:-9999em; } .dataviews-field-control__actions.dataviews-field-control__actions{ gap:4px; } .dataviews-field-control__field.is-interacting .dataviews-field-control__actions,.dataviews-field-control__field:focus-within .dataviews-field-control__actions,.dataviews-field-control__field:hover .dataviews-field-control__actions{ position:unset; top:unset; } .dataviews-field-control__icon{ display:flex; width:24px; } .dataviews-field-control__label-sub-label-container{ flex-grow:1; } .dataviews-field-control__label{ display:block; } .dataviews-field-control__sub-label{ color:#757575; font-size:11px; font-style:normal; margin-bottom:0; margin-top:8px; } .dataviews-view-grid{ container-type:inline-size; grid-template-rows:max-content; margin-bottom:auto; padding:0 48px 24px; } @media not (prefers-reduced-motion){ .dataviews-view-grid{ transition:padding .1s ease-out; } } .dataviews-view-grid .dataviews-view-grid__card{ height:100%; justify-content:flex-start; position:relative; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-actions{ padding:8px 0 4px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field{ align-items:center; display:flex; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__title-field--clickable{ width:fit-content; } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ color:#1e1e1e; } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after,.dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-grid .dataviews-view-grid__card.is-selected .dataviews-view-grid__media:after{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__card .dataviews-view-grid__media:focus:after{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .dataviews-view-grid .dataviews-view-grid__media{ aspect-ratio:1/1; background-color:#f0f0f0; border-radius:4px; min-height:200px; position:relative; width:100%; } .dataviews-view-grid .dataviews-view-grid__media img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-grid .dataviews-view-grid__media:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; pointer-events:none; position:absolute; top:0; width:100%; } .dataviews-view-grid .dataviews-view-grid__fields{ font-size:12px; line-height:16px; position:relative; } .dataviews-view-grid .dataviews-view-grid__fields:not(:empty){ padding:0 0 12px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field-value:not(:empty){ line-height:20px; min-height:24px; padding-top:2px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field{ align-items:center; min-height:24px; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-name{ color:#757575; width:35%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field .dataviews-view-grid__field-value{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:65%; } .dataviews-view-grid .dataviews-view-grid__fields .dataviews-view-grid__field:not(:has(.dataviews-view-grid__field-value:not(:empty))){ display:none; } .dataviews-view-grid .dataviews-view-grid__badge-fields:not(:empty){ padding-bottom:12px; } @container (max-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(1, minmax(0, 1fr)); padding-left:24px; padding-right:24px; } } @container (min-width: 480px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(2, minmax(0, 1fr)); } } @container (min-width: 780px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(3, minmax(0, 1fr)); } } @container (min-width: 1140px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(4, minmax(0, 1fr)); } } @container (min-width: 1520px){ .dataviews-view-grid.dataviews-view-grid{ grid-template-columns:repeat(5, minmax(0, 1fr)); } } .dataviews-view-grid__field-value:empty,.dataviews-view-grid__field:empty{ display:none; } .dataviews-view-grid__card .dataviews-selection-checkbox{ left:8px; position:absolute; top:-9999em; z-index:1; } .dataviews-view-grid__card.is-selected .dataviews-selection-checkbox,.dataviews-view-grid__card:focus-within .dataviews-selection-checkbox,.dataviews-view-grid__card:hover .dataviews-selection-checkbox{ top:8px; } .dataviews-view-grid__media--clickable{ cursor:pointer; } div.dataviews-view-list{ list-style-type:none; } .dataviews-view-list{ margin:0 0 auto; } .dataviews-view-list div[role=row]{ border-top:1px solid #f0f0f0; margin:0; } .dataviews-view-list div[role=row] .dataviews-view-list__item-wrapper{ box-sizing:border-box; padding:16px 24px; position:relative; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions{ flex:0; overflow:hidden; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions>div{ height:24px; } .dataviews-view-list div[role=row] .dataviews-view-list__item-actions .components-button{ opacity:0; position:relative; z-index:1; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions{ flex-basis:min-content; overflow:unset; padding-inline-end:4px; } .dataviews-view-list div[role=row]:where(.is-selected,.is-hovered,:focus-within) .dataviews-view-list__item-actions .components-button{ opacity:1; } .dataviews-view-list div[role=row].is-selected.is-selected,.dataviews-view-list div[role=row].is-selected.is-selected+div[role=row]{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-list div[role=row]:not(.is-selected) .dataviews-view-list__title-field{ color:#1e1e1e; } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered,.dataviews-view-list div[role=row]:not(.is-selected):focus-within,.dataviews-view-list div[role=row]:not(.is-selected):hover{ background-color:#f8f8f8; color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected).is-hovered .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):focus-within .dataviews-view-list__title-field,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__fields,.dataviews-view-list div[role=row]:not(.is-selected):hover .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#1e1e1e; } .dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected .dataviews-view-list__item-wrapper .dataviews-view-list__title-field,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__fields,.dataviews-view-list div[role=row].is-selected:focus-within .dataviews-view-list__item-wrapper .dataviews-view-list__title-field{ color:var(--wp-admin-theme-color); } .dataviews-view-list .dataviews-view-list__item{ appearance:none; background:none; border:none; cursor:pointer; inset:0; padding:0; position:absolute; scroll-margin:8px 0; z-index:1; } .dataviews-view-list .dataviews-view-list__item:focus-visible{ outline:none; } .dataviews-view-list .dataviews-view-list__item:focus-visible:before{ border-radius:2px; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; inset:var(--wp-admin-border-width-focus); outline:2px solid #0000; position:absolute; } .dataviews-view-list .dataviews-view-list__title-field{ flex:1; line-height:24px; min-height:24px; overflow:hidden; } .dataviews-view-list .dataviews-view-list__title-field:has(a,button){ z-index:1; } .dataviews-view-list .dataviews-view-list__media-wrapper{ background-color:#f0f0f0; border-radius:4px; flex-shrink:0; height:52px; overflow:hidden; position:relative; width:52px; } .dataviews-view-list .dataviews-view-list__media-wrapper img{ height:100%; object-fit:cover; width:100%; } .dataviews-view-list .dataviews-view-list__media-wrapper:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; position:absolute; top:0; width:100%; } .dataviews-view-list .dataviews-view-list__field-wrapper{ flex-grow:1; min-height:52px; } .dataviews-view-list .dataviews-view-list__fields{ color:#757575; display:flex; flex-wrap:wrap; font-size:12px; gap:12px; row-gap:4px; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field:has(.dataviews-view-list__field-value:empty),.dataviews-view-list .dataviews-view-list__fields:empty{ display:none; } .dataviews-view-list .dataviews-view-list__fields .dataviews-view-list__field-value{ align-items:center; display:flex; line-height:20px; min-height:24px; } .dataviews-view-list+.dataviews-pagination{ justify-content:space-between; } .dataviews-view-table{ border-collapse:collapse; border-color:inherit; color:#757575; margin-bottom:auto; position:relative; text-indent:0; width:100%; } .dataviews-view-table th{ color:#1e1e1e; font-size:13px; font-weight:400; text-align:left; } .dataviews-view-table td,.dataviews-view-table th{ padding:12px; white-space:nowrap; } .dataviews-view-table td.dataviews-view-table__actions-column,.dataviews-view-table th.dataviews-view-table__actions-column{ text-align:right; } .dataviews-view-table td.dataviews-view-table__checkbox-column,.dataviews-view-table th.dataviews-view-table__checkbox-column{ padding-right:0; width:1%; } .dataviews-view-table tr{ border-top:1px solid #f0f0f0; } .dataviews-view-table tr .dataviews-view-table-header-button{ gap:4px; } .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-left:48px; } .dataviews-view-table tr td:first-child .dataviews-view-table-header-button,.dataviews-view-table tr th:first-child .dataviews-view-table-header-button{ margin-left:-8px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-right:48px; } .dataviews-view-table tr:last-child{ border-bottom:0; } .dataviews-view-table tr.is-hovered{ background-color:#f8f8f8; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input{ opacity:0; } .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:checked,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:focus,.dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input:indeterminate{ opacity:1; } .dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:0; } .dataviews-view-table tr.is-hovered .components-checkbox-control__input,.dataviews-view-table tr.is-hovered .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:focus-within .components-checkbox-control__input,.dataviews-view-table tr:focus-within .dataviews-item-actions .components-button:not(.dataviews-all-actions-button),.dataviews-view-table tr:hover .components-checkbox-control__input,.dataviews-view-table tr:hover .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } @media (hover:none){ .dataviews-view-table tr .components-checkbox-control__input.components-checkbox-control__input,.dataviews-view-table tr .dataviews-item-actions .components-button:not(.dataviews-all-actions-button){ opacity:1; } } .dataviews-view-table tr.is-selected{ background-color:rgba(var(--wp-admin-theme-color--rgb), .04); color:#757575; } .dataviews-view-table tr.is-selected,.dataviews-view-table tr.is-selected+tr{ border-top:1px solid rgba(var(--wp-admin-theme-color--rgb), .12); } .dataviews-view-table tr.is-selected:hover{ background-color:rgba(var(--wp-admin-theme-color--rgb), .08); } .dataviews-view-table thead{ inset-block-start:0; position:sticky; z-index:1; } .dataviews-view-table thead tr{ border:0; } .dataviews-view-table thead th{ background-color:#fff; font-size:11px; font-weight:500; padding-bottom:8px; padding-left:12px; padding-top:8px; text-transform:uppercase; } .dataviews-view-table thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-left:4px; } .dataviews-view-table tbody td{ vertical-align:top; } .dataviews-view-table tbody .dataviews-view-table__cell-content-wrapper{ align-items:center; display:flex; min-height:32px; } .dataviews-view-table tbody .components-v-stack>.dataviews-view-table__cell-content-wrapper:not(:first-child){ min-height:0; } .dataviews-view-table .dataviews-view-table-header-button{ font-size:11px; font-weight:500; padding:4px 8px; text-transform:uppercase; } .dataviews-view-table .dataviews-view-table-header-button:not(:hover){ color:#1e1e1e; } .dataviews-view-table .dataviews-view-table-header-button span{ speak:none; } .dataviews-view-table .dataviews-view-table-header-button span:empty{ display:none; } .dataviews-view-table .dataviews-view-table-header{ padding-left:4px; } .dataviews-view-table .dataviews-view-table__actions-column{ width:1%; } .dataviews-view-table:has(tr.is-selected) .components-checkbox-control__input{ opacity:1; } .dataviews-view-table.has-compact-density thead th:has(.dataviews-view-table-header-button):not(:first-child){ padding-left:0; } .dataviews-view-table.has-compact-density td,.dataviews-view-table.has-compact-density th{ padding:4px 8px; } .dataviews-view-table.has-comfortable-density td,.dataviews-view-table.has-comfortable-density th{ padding:16px 12px; } .dataviews-view-table.has-comfortable-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-comfortable-density th.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density td.dataviews-view-table__checkbox-column,.dataviews-view-table.has-compact-density th.dataviews-view-table__checkbox-column{ padding-right:0; } @container (max-width: 430px){ .dataviews-view-table tr td:first-child,.dataviews-view-table tr th:first-child{ padding-left:24px; } .dataviews-view-table tr td:last-child,.dataviews-view-table tr th:last-child{ padding-right:24px; } } .dataviews-view-table-selection-checkbox{ --checkbox-input-size:24px; } @media (min-width:600px){ .dataviews-view-table-selection-checkbox{ --checkbox-input-size:16px; } } .dataviews-column-primary__media{ max-width:60px; } .dataviews-controls__datetime{ border:none; padding:0; } .dataforms-layouts-panel__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-panel__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-panel__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .dataforms-layouts-panel__field-control .components-button{ max-width:100%; min-height:32px; text-align:left; text-wrap:balance; text-wrap:pretty; white-space:normal; } .dataforms-layouts-panel__field-control .components-dropdown{ max-width:100%; } .dataforms-layouts-panel__field-dropdown .components-popover__content{ min-width:320px; padding:16px; } .dataforms-layouts-panel__dropdown-header{ margin-bottom:16px; } .components-popover.components-dropdown__content.dataforms-layouts-panel__field-dropdown{ z-index:159990; } .dataforms-layouts-regular__field{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .dataforms-layouts-regular__field .components-base-control__label{ font-size:inherit; font-weight:400; text-transform:none; } .dataforms-layouts-regular__field-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .dataforms-layouts-regular__field-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .fields-create-template-part-modal{ z-index:1000001; } .fields-create-template-part-modal__area-radio-group{ border:1px solid #949494; border-radius:2px; } .fields-create-template-part-modal__area-radio-wrapper{ align-items:center; display:grid; grid-template-columns:min-content 1fr min-content; padding:12px; position:relative; grid-gap:4px 8px; color:#1e1e1e; } .fields-create-template-part-modal__area-radio-wrapper+.fields-create-template-part-modal__area-radio-wrapper{ border-top:1px solid #949494; } .fields-create-template-part-modal__area-radio-wrapper input[type=radio]{ opacity:0; position:absolute; } .fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:checked){ z-index:1; } .fields-create-template-part-modal__area-radio-wrapper:has(input[type=radio]:not(:checked)):hover{ color:var(--wp-admin-theme-color); } .fields-create-template-part-modal__area-radio-wrapper>:not(.fields-create-template-part-modal__area-radio-label){ pointer-events:none; } .fields-create-template-part-modal__area-radio-label:before{ content:""; inset:0; position:absolute; } input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-label:before{ cursor:pointer; } input[type=radio]:focus-visible~.fields-create-template-part-modal__area-radio-label:before{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:4px solid #0000; } .fields-create-template-part-modal__area-radio-checkmark,.fields-create-template-part-modal__area-radio-icon{ fill:currentColor; } input[type=radio]:not(:checked)~.fields-create-template-part-modal__area-radio-checkmark{ opacity:0; } .fields-create-template-part-modal__area-radio-description{ color:#757575; font-size:12px; grid-column:2 / 3; line-height:normal; margin:0; text-wrap:pretty; } input[type=radio]:not(:checked):hover~.fields-create-template-part-modal__area-radio-description{ color:inherit; } .fields-controls__slug .fields-controls__slug-external-icon{ margin-left:5ch; } .fields-controls__slug .fields-controls__slug-input input.components-input-control__input{ padding-inline-start:0 !important; } .fields-controls__slug .fields-controls__slug-help-link{ word-break:break-word; } .fields-controls__slug .fields-controls__slug-help{ display:flex; flex-direction:column; } .fields-controls__slug .fields-controls__slug-help .fields-controls__slug-help-slug{ font-weight:600; } .fields-controls__featured-image-placeholder{ background:#fff linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); border-radius:2px; box-shadow:inset 0 0 0 1px #0003; display:inline-block; padding:0; } .fields-controls__featured-image-title{ color:#1e1e1e; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:100%; } .fields-controls__featured-image-image{ align-self:center; border-radius:2px; height:100%; width:100%; } .fields-controls__featured-image-container .fields-controls__featured-image-placeholder{ margin:0; } .fields-controls__featured-image-container span{ margin-right:auto; } fieldset.fields-controls__featured-image .fields-controls__featured-image-container{ border:1px solid #ddd; border-radius:2px; cursor:pointer; padding:8px 12px; } fieldset.fields-controls__featured-image .fields-controls__featured-image-container:hover{ background-color:#f0f0f0; } fieldset.fields-controls__featured-image .fields-controls__featured-image-placeholder{ height:24px; width:24px; } fieldset.fields-controls__featured-image span{ align-self:center; text-align:start; white-space:nowrap; } fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button{ height:fit-content; padding:0; } fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:focus,fieldset.fields-controls__featured-image .fields-controls__featured-image-upload-button:hover{ border:0; color:unset; } fieldset.fields-controls__featured-image .fields-controls__featured-image-remove-button{ place-self:end; } .dataforms-layouts-panel__field-control .fields-controls__featured-image-image,.dataforms-layouts-panel__field-control .fields-controls__featured-image-placeholder{ height:16px; width:16px; } .dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-image,.dataviews-view-table__cell-content-wrapper .fields-controls__featured-image-placeholder{ display:block; height:32px; width:32px; } .fields-controls__template-modal{ z-index:1000001; } .fields-controls__template-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; padding-top:2px; } @media (min-width:782px){ .fields-controls__template-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .fields-controls__template-content .block-editor-block-patterns-list{ column-count:4; } } .fields-controls__template-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .fields-field__title span:first-child{ display:block; flex-grow:0; overflow:hidden; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .fields-field__pattern-title span:first-child{ flex:1; } .edit-site-custom-template-modal__contents-wrapper{ height:100%; justify-content:flex-start !important; } .edit-site-custom-template-modal__contents-wrapper>*{ width:100%; } .edit-site-custom-template-modal__contents-wrapper__suggestions_list{ margin-left:-12px; margin-right:-12px; width:calc(100% + 24px); } .edit-site-custom-template-modal__contents>.components-button{ height:auto; justify-content:center; } @media (min-width:782px){ .edit-site-custom-template-modal{ width:456px; } } @media (min-width:600px){ .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list{ max-height:224px; overflow-y:auto; } } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item{ display:block; height:auto; overflow-wrap:break-word; padding:8px 12px; text-align:left; white-space:pre-wrap; width:100%; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item mark{ background:none; font-weight:700; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover *,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:hover mark{ color:var(--wp-admin-theme-color); } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus{ background-color:#f0f0f0; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color) inset; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info,.edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__title{ display:block; overflow:hidden; text-overflow:ellipsis; } .edit-site-custom-template-modal .edit-site-custom-template-modal__suggestions_list__list-item__info{ color:#757575; word-break:break-all; } .edit-site-custom-template-modal__no-results{ border:1px solid #ccc; border-radius:2px; padding:16px; } .edit-site-custom-generic-template__modal .components-modal__header{ border-bottom:none; } .edit-site-custom-generic-template__modal .components-modal__content:before{ margin-bottom:4px; } @media (min-width:960px){ .edit-site-add-new-template__modal{ margin-top:64px; max-height:calc(100% - 128px); max-width:832px; width:calc(100% - 128px); } } .edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button svg,.edit-site-add-new-template__modal .edit-site-add-new-template__template-button svg{ fill:var(--wp-admin-theme-color); } .edit-site-add-new-template__modal .edit-site-add-new-template__custom-template-button .edit-site-add-new-template__template-name{ align-items:flex-start; flex-grow:1; } .edit-site-add-new-template__modal .edit-site-add-new-template__template-icon{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-radius:100%; max-height:40px; max-width:40px; padding:8px; } .edit-site-add-new-template__template-list__contents>.components-button,.edit-site-custom-template-modal__contents>.components-button{ border:1px solid #ddd; display:flex; flex-direction:column; justify-content:center; outline:1px solid #0000; padding:32px; } .edit-site-add-new-template__template-list__contents>.components-button span:first-child,.edit-site-custom-template-modal__contents>.components-button span:first-child{ color:#1e1e1e; } .edit-site-add-new-template__template-list__contents>.components-button span,.edit-site-custom-template-modal__contents>.components-button span{ color:#757575; } .edit-site-add-new-template__template-list__contents>.components-button:hover,.edit-site-custom-template-modal__contents>.components-button:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-color:#0000; color:var(--wp-admin-theme-color-darker-10); } .edit-site-add-new-template__template-list__contents>.components-button:hover span,.edit-site-custom-template-modal__contents>.components-button:hover span{ color:var(--wp-admin-theme-color); } .edit-site-add-new-template__template-list__contents>.components-button:focus,.edit-site-custom-template-modal__contents>.components-button:focus{ border-color:#0000; box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:3px solid #0000; } .edit-site-add-new-template__template-list__contents>.components-button:focus span:first-child,.edit-site-custom-template-modal__contents>.components-button:focus span:first-child{ color:var(--wp-admin-theme-color); } .edit-site-add-new-template__template-list__contents .edit-site-add-new-template__custom-template-button,.edit-site-add-new-template__template-list__contents .edit-site-add-new-template__template-list__prompt,.edit-site-custom-template-modal__contents .edit-site-add-new-template__custom-template-button,.edit-site-custom-template-modal__contents .edit-site-add-new-template__template-list__prompt{ grid-column:1 / -1; } .edit-site-add-new-template__template-list__contents>.components-button{ align-items:flex-start; height:100%; text-align:start; } .edit-site-visual-editor__editor-canvas.is-focused{ outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-2); } .edit-site-canvas-loader{ align-items:center; display:flex; height:100%; justify-content:center; left:0; opacity:0; position:absolute; top:0; width:100%; } @media not (prefers-reduced-motion){ .edit-site-canvas-loader{ animation:edit-site-canvas-loader__fade-in-animation .5s ease .2s; animation-fill-mode:forwards; } } .edit-site-canvas-loader>div{ width:160px; } @keyframes edit-site-canvas-loader__fade-in-animation{ 0%{ opacity:0; } to{ opacity:1; } } .edit-site-global-styles-preview{ align-items:center; cursor:pointer; display:flex; justify-content:center; line-height:1; } .edit-site-global-styles-preview__wrapper{ display:block; max-width:100%; width:100%; } .edit-site-typography-preview{ align-items:center; background:#f0f0f0; border-radius:2px; display:flex; justify-content:center; margin-bottom:16px; min-height:100px; overflow:hidden; } .edit-site-font-size__item{ line-break:anywhere; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .edit-site-font-size__item-value{ color:#757575; } .edit-site-global-styles-screen{ margin:12px 16px 16px; } .edit-site-global-styles-screen-typography__indicator{ align-items:center; border-radius:1px; display:flex !important; font-size:14px; height:24px; justify-content:center; width:24px; } .edit-site-global-styles-screen-typography__font-variants-count{ color:#757575; } .edit-site-global-styles-font-families__manage-fonts{ justify-content:center; } .edit-site-global-styles-screen .color-block-support-panel{ border-top:none; padding-left:0; padding-right:0; padding-top:0; row-gap:12px; } .edit-site-global-styles-header__description{ padding:0 16px; } .edit-site-block-types-search{ margin-bottom:8px; padding:0 16px; } .edit-site-global-styles-header{ margin-bottom:0 !important; } .edit-site-global-styles-subtitle{ font-size:11px !important; font-weight:500 !important; margin-bottom:0 !important; text-transform:uppercase; } .edit-site-global-styles-section-title{ color:#2f2f2f; font-weight:600; line-height:1.2; margin:0; padding:16px 16px 0; } .edit-site-global-styles-icon-with-current-color{ fill:currentColor; } .edit-site-global-styles__color-indicator-wrapper{ flex-shrink:0; height:24px; } .edit-site-global-styles__shadows-panel__options-container,.edit-site-global-styles__shadows-panel__title{ height:24px; } .edit-site-global-styles__block-preview-panel{ border:1px solid #e0e0e0; border-radius:4px; overflow:hidden; position:relative; width:100%; } .edit-site-global-styles__shadow-preview-panel{ background-image:repeating-linear-gradient(45deg, #f5f5f5 25%, #0000 0, #0000 75%, #f5f5f5 0, #f5f5f5), repeating-linear-gradient(45deg, #f5f5f5 25%, #0000 0, #0000 75%, #f5f5f5 0, #f5f5f5); background-position:0 0, 8px 8px; background-size:16px 16px; border:1px solid #e0e0e0; border-radius:4px; height:144px; overflow:auto; } .edit-site-global-styles__shadow-preview-panel .edit-site-global-styles__shadow-preview-block{ background-color:#fff; border:1px solid #e0e0e0; border-radius:2px; height:60px; width:60%; } .edit-site-global-styles__shadow-editor__dropdown-content{ width:280px; } .edit-site-global-styles__shadow-editor-panel{ margin-bottom:4px; } .edit-site-global-styles__shadow-editor__dropdown{ position:relative; width:100%; } .edit-site-global-styles__shadow-editor__dropdown-toggle{ border-radius:inherit; height:auto; padding-bottom:8px; padding-top:8px; text-align:left; width:100%; } .edit-site-global-styles__shadow-editor__dropdown-toggle.is-open{ background:#f0f0f0; color:var(--wp-admin-theme-color); } .edit-site-global-styles__shadow-editor__remove-button{ opacity:0; position:absolute; right:8px; top:8px; } .edit-site-global-styles__shadow-editor__remove-button.edit-site-global-styles__shadow-editor__remove-button{ border:none; } .edit-site-global-styles__shadow-editor__dropdown-toggle:hover+.edit-site-global-styles__shadow-editor__remove-button,.edit-site-global-styles__shadow-editor__remove-button:focus,.edit-site-global-styles__shadow-editor__remove-button:hover{ opacity:1; } @media (hover:none){ .edit-site-global-styles__shadow-editor__remove-button{ opacity:1; } } .edit-site-global-styles-screen-css{ display:flex; flex:1 1 auto; flex-direction:column; margin:16px; } .edit-site-global-styles-screen-css .components-v-stack{ flex:1 1 auto; } .edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input,.edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field{ display:flex; flex:1 1 auto; flex-direction:column; } .edit-site-global-styles-screen-css .components-v-stack .block-editor-global-styles-advanced-panel__custom-css-input .components-base-control__field .components-textarea-control__input{ direction:ltr; flex:1 1 auto; } .edit-site-global-styles-screen-css-help-link{ display:inline-block; margin-top:8px; } .edit-site-global-styles-screen-variations{ border-top:1px solid #ddd; margin-top:16px; } .edit-site-global-styles-screen-variations>*{ margin:24px 16px; } .edit-site-global-styles-sidebar__navigator-provider{ height:100%; } .edit-site-global-styles-sidebar__navigator-screen{ display:flex; flex-direction:column; height:100%; } .edit-site-global-styles-sidebar__navigator-screen .single-column{ grid-column:span 1; } .edit-site-global-styles-screen-root.edit-site-global-styles-screen-root,.edit-site-global-styles-screen-style-variations.edit-site-global-styles-screen-style-variations{ background:unset; color:inherit; } .edit-site-global-styles-sidebar__panel .block-editor-block-icon svg{ fill:currentColor; } .edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile,.edit-site-global-styles-screen-root__active-style-tile.edit-site-global-styles-screen-root__active-style-tile .edit-site-global-styles-screen-root__active-style-tile-preview{ border-radius:2px; } .edit-site-global-styles-screen-revisions__revisions-list{ flex-grow:1; list-style:none; margin:0 16px 16px; } .edit-site-global-styles-screen-revisions__revisions-list li{ margin-bottom:0; } .edit-site-global-styles-screen-revisions__revision-item{ cursor:pointer; display:flex; flex-direction:column; position:relative; } .edit-site-global-styles-screen-revisions__revision-item[role=option]:active,.edit-site-global-styles-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 #0000; } .edit-site-global-styles-screen-revisions__revision-item:hover{ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .edit-site-global-styles-screen-revisions__revision-item:hover .edit-site-global-styles-screen-revisions__date{ color:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item:after,.edit-site-global-styles-screen-revisions__revision-item:before{ content:"\a"; display:block; position:absolute; } .edit-site-global-styles-screen-revisions__revision-item:before{ background:#ddd; border:4px solid #0000; border-radius:50%; height:8px; left:17px; top:18px; transform:translate(-50%, -50%); width:8px; z-index:1; } .edit-site-global-styles-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 #0000; outline-offset:-2px; } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__date{ color:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true]:before{ background:var(--wp-admin-theme-color); } .edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__changes>li,.edit-site-global-styles-screen-revisions__revision-item[aria-selected=true] .edit-site-global-styles-screen-revisions__meta{ color:#1e1e1e; } .edit-site-global-styles-screen-revisions__revision-item:after{ border:.5px solid #ddd; height:100%; left:16px; top:0; width:0; } .edit-site-global-styles-screen-revisions__revision-item:first-child:after{ top:18px; } .edit-site-global-styles-screen-revisions__revision-item:last-child:after{ height:18px; } .edit-site-global-styles-screen-revisions__revision-item-wrapper{ display:block; padding:12px 12px 4px 40px; } .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__apply-button.is-primary{ align-self:flex-start; margin:4px 12px 12px 40px; } .edit-site-global-styles-screen-revisions__applied-text,.edit-site-global-styles-screen-revisions__changes,.edit-site-global-styles-screen-revisions__meta{ color:#757575; font-size:12px; } .edit-site-global-styles-screen-revisions__description{ align-items:flex-start; display:flex; flex-direction:column; gap:8px; } .edit-site-global-styles-screen-revisions__description .edit-site-global-styles-screen-revisions__date{ font-size:12px; font-weight:600; text-transform:uppercase; } .edit-site-global-styles-screen-revisions__meta{ align-items:flex-start; display:flex; justify-content:start; margin-bottom:4px; text-align:left; width:100%; } .edit-site-global-styles-screen-revisions__meta img{ border-radius:100%; height:16px; margin-right:8px; width:16px; } .edit-site-global-styles-screen-revisions__loading{ margin:24px auto !important; } .edit-site-global-styles-screen-revisions__changes{ line-height:1.4; list-style:disc; margin-left:12px; text-align:left; } .edit-site-global-styles-screen-revisions__changes li{ margin-bottom:4px; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination{ gap:2px; justify-content:space-between; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .edit-site-pagination__total{ height:1px; left:-1000px; margin:-1px; overflow:hidden; position:absolute; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-text{ font-size:12px; will-change:opacity; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary{ color:#1e1e1e; } .edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary:disabled,.edit-site-global-styles-screen-revisions__pagination.edit-site-global-styles-screen-revisions__pagination .components-button.is-tertiary[aria-disabled=true]{ color:#949494; } .edit-site-global-styles-screen-revisions__footer{ background:#fff; border-top:1px solid #ddd; bottom:0; height:56px; min-width:100%; padding:12px; position:sticky; z-index:1; } .editor-sidebar{ width:280px; } .editor-sidebar>.components-panel{ border-left:0; border-right:0; margin-bottom:-1px; margin-top:-1px; } .editor-sidebar>.components-panel>.components-panel__header{ background:#f0f0f0; } .editor-sidebar .block-editor-block-inspector__card{ margin:0; } .edit-site-global-styles-sidebar{ display:flex; flex-direction:column; min-height:100%; } .edit-site-global-styles-sidebar__panel{ flex:1; } .edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-title{ margin:0; } .edit-site-global-styles-sidebar .edit-site-global-styles-sidebar__header-actions{ flex:1; } .edit-site-global-styles-sidebar .components-navigation__menu-title-heading{ font-size:15.6px; font-weight:500; } .edit-site-global-styles-sidebar .components-navigation__item>button span{ font-weight:500; } .edit-site-global-styles-sidebar .block-editor-panel-color-gradient-settings{ border:0; } .edit-site-global-styles-sidebar .single-column{ grid-column:span 1; } .edit-site-global-styles-sidebar .components-tools-panel .span-columns{ grid-column:1 / -1; } .edit-site-global-styles-sidebar__blocks-group{ border-top:1px solid #e0e0e0; padding-top:24px; } .edit-site-global-styles-sidebar__blocks-group-help{ padding:0 16px; } .edit-site-global-styles-color-palette-panel,.edit-site-global-styles-gradient-palette-panel{ padding:16px; } .edit-site-global-styles-sidebar hr{ margin:0; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon{ width:auto; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon svg{ display:none; } .show-icon-labels .edit-site-global-styles-sidebar__header .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } .edit-site-page{ background:#fff; color:#2f2f2f; container:edit-site-page/inline-size; height:100%; } @media not (prefers-reduced-motion){ .edit-site-page{ transition:width .2s ease-out; } } .edit-site-page-header{ background:#fff; border-bottom:1px solid #f0f0f0; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-page-header{ transition:padding .1s ease-out; } } .edit-site-page-header .components-heading{ color:#1e1e1e; } .edit-site-page-header .edit-site-page-header__page-title{ min-height:40px; } .edit-site-page-header .edit-site-page-header__page-title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-page-header .edit-site-page-header__sub-title{ margin-bottom:8px; } @container (max-width: 430px){ .edit-site-page-header{ padding:16px 24px; } } .edit-site-page-content{ display:flex; flex-flow:column; height:100%; position:relative; z-index:1; } .edit-site-patterns__delete-modal{ width:384px; } .page-patterns-preview-field{ align-items:center; border-radius:4px; display:flex; flex-direction:column; height:100%; justify-content:center; } .dataviews-view-grid .page-patterns-preview-field .block-editor-block-preview__container{ height:100%; } .dataviews-view-table .page-patterns-preview-field{ flex-grow:0; text-wrap:balance; text-wrap:pretty; width:96px; } .edit-site-patterns__pattern-icon{ fill:var(--wp-block-synced-color); flex-shrink:0; } .edit-site-patterns__section-header{ border-bottom:1px solid #f0f0f0; flex-shrink:0; min-height:40px; padding:16px 48px; position:sticky; top:0; z-index:2; } @media not (prefers-reduced-motion){ .edit-site-patterns__section-header{ transition:padding .1s ease-out; } } .edit-site-patterns__section-header .edit-site-patterns__title{ min-height:40px; } .edit-site-patterns__section-header .edit-site-patterns__title .components-heading{ flex-basis:0; flex-grow:1; white-space:nowrap; } .edit-site-patterns__section-header .edit-site-patterns__sub-title{ margin-bottom:8px; } .edit-site-patterns__section-header .screen-reader-shortcut:focus{ top:0; } .edit-site-page-patterns-dataviews .dataviews-view-grid__badge-fields .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully){ background:rgba(var(--wp-block-synced-color--rgb), .04); color:var(--wp-block-synced-color); } .dataviews-action-modal__duplicate-pattern [role=dialog]>[role=document]{ width:350px; } .dataviews-action-modal__duplicate-pattern .patterns-menu-items__convert-modal-categories{ position:relative; } .dataviews-action-modal__duplicate-pattern .components-form-token-field__suggestions-list:not(:empty){ background-color:#fff; border:1px solid var(--wp-admin-theme-color); border-bottom-left-radius:2px; border-bottom-right-radius:2px; box-shadow:0 0 .5px .5px var(--wp-admin-theme-color); box-sizing:border-box; left:-1px; max-height:96px; min-width:auto; position:absolute; width:calc(100% + 2px); z-index:1; } @media (min-width:600px){ .dataviews-action-modal__duplicate-template-part .components-modal__frame{ max-width:500px; } } @container (max-width: 430px){ .edit-site-page-patterns-dataviews .edit-site-patterns__section-header{ padding-left:24px; padding-right:24px; } } .page-templates-preview-field{ align-items:center; border-radius:4px; display:flex; flex-direction:column; height:100%; justify-content:center; width:100%; } .dataviews-view-list .page-templates-preview-field .block-editor-block-preview__container{ height:120px; } .dataviews-view-grid .page-templates-preview-field .block-editor-block-preview__container{ height:100%; } .dataviews-view-table .page-templates-preview-field{ max-height:160px; position:relative; text-wrap:balance; text-wrap:pretty; width:120px; } .dataviews-view-table .page-templates-preview-field:after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; position:absolute; top:0; width:100%; } .page-templates-description{ max-width:50em; text-wrap:balance; text-wrap:pretty; } .dataviews-view-table .page-templates-description{ display:block; margin-bottom:8px; } .edit-site-page-templates .dataviews-pagination{ z-index:2; } .page-templates-author-field__avatar{ align-items:center; display:flex; flex-shrink:0; height:24px; justify-content:left; overflow:hidden; width:24px; } .page-templates-author-field__avatar img{ border-radius:100%; height:16px; object-fit:cover; opacity:0; width:16px; } @media not (prefers-reduced-motion){ .page-templates-author-field__avatar img{ transition:opacity .1s linear; } } .page-templates-author-field__avatar.is-loaded img{ opacity:1; } .page-templates-author-field__icon{ display:flex; flex-shrink:0; height:24px; width:24px; } .page-templates-author-field__icon svg{ margin-left:-4px; fill:currentColor; } .page-templates-author-field__name{ overflow:hidden; text-overflow:ellipsis; } .edit-site-list__rename-modal{ z-index:1000001; } @media (min-width:782px){ .edit-site-list__rename-modal .components-base-control{ width:320px; } } .edit-site-editor__editor-interface{ opacity:1; } @media not (prefers-reduced-motion){ .edit-site-editor__editor-interface{ transition:opacity .1s ease-out; } } .edit-site-editor__editor-interface.is-loading{ opacity:0; } .edit-site-editor__toggle-save-panel{ background-color:#fff; border:1px dotted #ddd; box-sizing:border-box; display:flex; justify-content:center; padding:24px; width:280px; } .edit-site-editor__view-mode-toggle{ view-transition-name:toggle; height:60px; left:0; top:0; width:60px; z-index:100; } .edit-site-editor__view-mode-toggle .components-button{ align-items:center; border-radius:0; color:#fff; display:flex; height:100%; justify-content:center; overflow:hidden; padding:0; width:100%; } .edit-site-editor__view-mode-toggle .components-button:active,.edit-site-editor__view-mode-toggle .components-button:hover{ color:#fff; } .edit-site-editor__view-mode-toggle .components-button:focus{ box-shadow:none; } .edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon img,.edit-site-editor__view-mode-toggle .edit-site-editor__view-mode-toggle-icon svg{ background:#1e1e1e; display:block; } .edit-site-editor__back-icon{ align-items:center; background-color:#ccc; display:flex; height:60px; justify-content:center; left:0; pointer-events:none; position:absolute; top:0; width:60px; } .edit-site-editor__back-icon svg{ fill:currentColor; } .edit-site-editor__back-icon.has-site-icon{ -webkit-backdrop-filter:saturate(180%) blur(15px); backdrop-filter:saturate(180%) blur(15px); background-color:#fff9; } .edit-site-welcome-guide{ width:312px; } .edit-site-welcome-guide.guide-editor .edit-site-welcome-guide__image,.edit-site-welcome-guide.guide-styles .edit-site-welcome-guide__image{ background:#00a0d2; } .edit-site-welcome-guide.guide-page .edit-site-welcome-guide__video{ border-right:16px solid #3858e9; border-top:16px solid #3858e9; } .edit-site-welcome-guide.guide-template .edit-site-welcome-guide__video{ border-left:16px solid #3858e9; border-top:16px solid #3858e9; } .edit-site-welcome-guide__image{ margin:0 0 16px; } .edit-site-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-site-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-site-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 16px; padding:0 32px; } .edit-site-welcome-guide__text img{ vertical-align:bottom; } .edit-site-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-site-layout{ color:#ccc; display:flex; flex-direction:column; height:100%; } .edit-site-layout,.edit-site-layout:not(.is-full-canvas) .editor-visual-editor{ background:#1e1e1e; } .edit-site-layout__content{ display:flex; flex-grow:1; height:100%; } .edit-site-layout__sidebar-region{ flex-shrink:0; width:100vw; z-index:1; } @media (min-width:782px){ .edit-site-layout__sidebar-region{ width:300px; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region{ height:100vh; left:0; position:fixed !important; top:0; } .edit-site-layout__sidebar-region .edit-site-layout__sidebar{ display:flex; flex-direction:column; height:100%; } .edit-site-layout__sidebar-region .resizable-editor__drag-handle{ right:0; } .edit-site-layout__main{ display:flex; flex-direction:column; flex-grow:1; overflow:hidden; } .edit-site-layout__mobile{ display:flex; flex-direction:column; position:relative; width:100%; z-index:2; } .edit-site-layout__mobile .edit-site-sidebar__screen-wrapper{ padding:0; } .edit-site-layout__mobile .edit-site-sidebar-navigation-screen__main{ padding:0 12px; } .edit-site-layout__canvas-container{ flex-grow:1; overflow:visible; position:relative; z-index:2; } .edit-site-layout__canvas-container.is-resizing:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:100; } .edit-site-layout__canvas{ align-items:center; bottom:0; display:flex; justify-content:center; left:0; position:absolute; top:0; width:100%; } .edit-site-layout__canvas.is-right-aligned{ justify-content:flex-end; } .edit-site-layout__canvas .edit-site-resizable-frame__inner{ color:#1e1e1e; } @media (min-width:782px){ .edit-site-layout__canvas{ bottom:16px; top:16px; width:calc(100% - 16px); } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; overflow:hidden; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ transition:border-radius,box-shadow .4s; } } @media (min-width:782px){ .edit-site-layout:not(.is-full-canvas) .edit-site-layout__canvas .edit-site-resizable-frame__inner-content{ border-radius:8px; } .edit-site-layout__canvas .edit-site-resizable-frame__inner-content:hover{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; } } .edit-site-layout.is-full-canvas .edit-site-layout__canvas{ bottom:0; top:0; width:100%; } .edit-site-layout__canvas .interface-interface-skeleton,.edit-site-layout__mobile .interface-interface-skeleton,.edit-site-template-pages-preview .interface-interface-skeleton{ min-height:100% !important; position:relative !important; } .edit-site-template-pages-preview{ height:100%; } html.canvas-mode-edit-transition::view-transition-group(toggle){ animation-delay:255ms; } @media (prefers-reduced-motion){ ::view-transition-group(*),::view-transition-new(*),::view-transition-old(*){ animation:none !important; } } .edit-site-layout.is-full-canvas .edit-site-layout__sidebar-region .edit-site-layout__view-mode-toggle{ display:none; } .edit-site-layout__view-mode-toggle.components-button{ view-transition-name:toggle; align-items:center; background:#1e1e1e; border-radius:0; color:#fff; display:flex; height:60px; justify-content:center; overflow:hidden; padding:0; position:relative; width:60px; } .edit-site-layout__view-mode-toggle.components-button:active,.edit-site-layout__view-mode-toggle.components-button:hover{ color:#fff; } .edit-site-layout__view-mode-toggle.components-button:focus,.edit-site-layout__view-mode-toggle.components-button:focus-visible{ box-shadow:0 0 0 3px #1e1e1e, 0 0 0 6px var(--wp-admin-theme-color); outline:4px solid #0000; outline-offset:4px; } .edit-site-layout__view-mode-toggle.components-button:before{ border-radius:4px; bottom:9px; box-shadow:none; content:""; display:block; left:9px; position:absolute; right:9px; top:9px; } @media not (prefers-reduced-motion){ .edit-site-layout__view-mode-toggle.components-button:before{ transition:box-shadow .1s ease; } } .edit-site-layout__view-mode-toggle.components-button .edit-site-layout__view-mode-toggle-icon{ align-items:center; display:flex; height:60px; justify-content:center; width:60px; } .edit-site-layout__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:auto; position:fixed !important; right:0; top:-9999em; width:280px; z-index:100000; } .edit-site-layout__actions:focus,.edit-site-layout__actions:focus-within{ bottom:0; top:auto; } .edit-site-layout__actions.is-entity-save-view-open:focus,.edit-site-layout__actions.is-entity-save-view-open:focus-within{ top:0; } @media (min-width:782px){ .edit-site-layout__actions{ border-left:1px solid #ddd; } } .edit-site-layout__area{ box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; flex-grow:1; margin:0; overflow:hidden; } @media (min-width:782px){ .edit-site-layout__area{ border-radius:8px; margin:16px 16px 16px 0; } } .edit-site .components-editor-notices__snackbar{ bottom:16px; padding-left:16px; padding-right:16px; position:fixed; right:0; } .edit-site-save-hub{ border-top:1px solid #2f2f2f; color:#949494; flex-shrink:0; margin:0; padding:16px; } .edit-site-save-hub__button{ color:inherit; justify-content:center; width:100%; } .edit-site-save-hub__button[aria-disabled=true]{ opacity:1; } .edit-site-save-hub__button[aria-disabled=true]:hover{ color:inherit; } .edit-site-save-hub__button:not(.is-primary).is-busy,.edit-site-save-hub__button:not(.is-primary).is-busy[aria-disabled=true]:hover{ color:#1e1e1e; } @media (min-width:600px){ .edit-site-save-panel__modal{ width:600px; } } .edit-site-sidebar__content{ contain:content; flex-grow:1; overflow-x:hidden; overflow-y:auto; } @keyframes _x51ri_slide-from-right{ 0%{ opacity:0; transform:translateX(50px); } to{ opacity:1; transform:none; } } @keyframes _x51ri_slide-from-left{ 0%{ opacity:0; transform:translateX(-50px); } to{ opacity:1; transform:none; } } .edit-site-sidebar__screen-wrapper{ animation-duration:.14s; animation-timing-function:ease-in-out; display:flex; flex-direction:column; height:100%; max-height:100%; overflow-x:auto; padding:0 12px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:stable; scrollbar-width:thin; will-change:transform; will-change:transform, opacity; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar{ height:12px; width:12px; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-track{ background-color:initial; } .edit-site-sidebar__screen-wrapper::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .edit-site-sidebar__screen-wrapper:focus-within::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:focus::-webkit-scrollbar-thumb,.edit-site-sidebar__screen-wrapper:hover::-webkit-scrollbar-thumb{ background-color:#757575; } .edit-site-sidebar__screen-wrapper:focus,.edit-site-sidebar__screen-wrapper:focus-within,.edit-site-sidebar__screen-wrapper:hover{ scrollbar-color:#757575 #0000; } @media (hover:none){ .edit-site-sidebar__screen-wrapper{ scrollbar-color:#757575 #0000; } } @media (prefers-reduced-motion:reduce){ .edit-site-sidebar__screen-wrapper{ animation-duration:0s; } } .edit-site-sidebar__screen-wrapper.slide-from-left{ animation-name:_x51ri_slide-from-left; } .edit-site-sidebar__screen-wrapper.slide-from-right{ animation-name:_x51ri_slide-from-right; } .edit-site-sidebar-button{ color:#e0e0e0; flex-shrink:0; } .edit-site-sidebar-button:focus:not(:disabled){ box-shadow:none; outline:none; } .edit-site-sidebar-button:focus-visible:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:3px solid #0000; } .edit-site-sidebar-button:focus,.edit-site-sidebar-button:focus-visible,.edit-site-sidebar-button:hover:not(:disabled,[aria-disabled=true]),.edit-site-sidebar-button:not(:disabled,[aria-disabled=true]):active,.edit-site-sidebar-button[aria-expanded=true]{ color:#f0f0f0; } .edit-site-sidebar-navigation-item.components-item{ border:none; color:#949494; min-height:40px; padding:8px 6px 8px 16px; } .edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-item.components-item[aria-current=true]{ color:#e0e0e0; } .edit-site-sidebar-navigation-item.components-item:focus .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item:hover .edit-site-sidebar-navigation-item__drilldown-indicator,.edit-site-sidebar-navigation-item.components-item[aria-current=true] .edit-site-sidebar-navigation-item__drilldown-indicator{ fill:#e0e0e0; } .edit-site-sidebar-navigation-item.components-item[aria-current=true]{ background:#2f2f2f; color:#fff; font-weight:500; } .edit-site-sidebar-navigation-item.components-item:focus-visible{ transform:translateZ(0); } .edit-site-sidebar-navigation-item.components-item .edit-site-sidebar-navigation-item__drilldown-indicator{ fill:#949494; } .edit-site-sidebar-navigation-item.components-item.with-suffix{ padding-right:16px; } .edit-site-sidebar-navigation-screen__content .block-editor-list-view-block-select-button{ cursor:grab; padding:8px 8px 8px 0; } .edit-site-sidebar-navigation-screen{ display:flex; flex-direction:column; overflow-x:unset !important; position:relative; } .edit-site-sidebar-navigation-screen__main{ flex-grow:1; margin-bottom:16px; } .edit-site-sidebar-navigation-screen__main.has-footer{ margin-bottom:0; } .edit-site-sidebar-navigation-screen__content{ padding:0 16px; } .edit-site-sidebar-navigation-screen__content .components-text{ color:#ccc; } .edit-site-sidebar-navigation-screen__content .components-heading{ margin-bottom:8px; } .edit-site-sidebar-navigation-screen__title-icon{ background:#1e1e1e; margin-bottom:8px; padding-bottom:8px; padding-top:48px; position:sticky; top:0; z-index:1; } .edit-site-sidebar-navigation-screen__title{ flex-grow:1; overflow-wrap:break-word; } .edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title,.edit-site-sidebar-navigation-screen__title.edit-site-sidebar-navigation-screen__title .edit-site-sidebar-navigation-screen__title{ line-height:32px; } .edit-site-sidebar-navigation-screen__actions{ display:flex; flex-shrink:0; } @media (min-width:782px){ .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variation-container{ max-width:292px; } } .edit-site-global-styles-variation-title{ color:#ddd; font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ outline-color:#ffffff0d; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{ outline-color:#ffffff26; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview{ outline-color:#fff; } .edit-site-sidebar-navigation-screen__content .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:var(--wp-admin-theme-color); } .edit-site-sidebar-navigation-screen__footer{ background-color:#1e1e1e; border-top:1px solid #2f2f2f; bottom:0; gap:0; margin:16px 0 0; padding:8px 16px; position:sticky; } .edit-site-sidebar-navigation-screen__footer .edit-site-sidebar-navigation-screen-details-footer{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen__input-control{ width:100%; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__container{ background:#2f2f2f; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__container .components-button{ color:#e0e0e0 !important; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__input{ background:#2f2f2f !important; color:#e0e0e0 !important; } .edit-site-sidebar-navigation-screen__input-control .components-input-control__backdrop{ border:4px !important; } .edit-site-sidebar-navigation-screen__input-control .components-base-control__help{ color:#949494; } .edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:focus,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item:hover,.edit-site-sidebar-navigation-screen-details-footer div.edit-site-sidebar-navigation-item.components-item[aria-current]{ background:none; } .sidebar-navigation__more-menu .components-button{ color:#e0e0e0; } .sidebar-navigation__more-menu .components-button:focus,.sidebar-navigation__more-menu .components-button:hover,.sidebar-navigation__more-menu .components-button[aria-current]{ color:#f0f0f0; } .edit-site-sidebar-navigation-screen-patterns__group{ margin-bottom:24px; margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-patterns__group:last-of-type{ border-bottom:0; margin-bottom:0; padding-bottom:0; } .edit-site-sidebar-navigation-screen-patterns__group-header{ margin-top:16px; } .edit-site-sidebar-navigation-screen-patterns__group-header p{ color:#949494; } .edit-site-sidebar-navigation-screen-patterns__group-header h2{ font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-navigation-screen-patterns__divider{ border-top:1px solid #2f2f2f; margin:16px 0; } .edit-site-sidebar-navigation-screen__description{ margin:0 0 32px; } .edit-site-sidebar-navigation-screen-navigation-menus{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell{ width:100%; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{ white-space:normal; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__title{ margin-top:3px; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu-cell{ padding-right:0; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button{ color:#949494; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button:hover,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block-select-button[aria-current]{ color:#fff; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu{ color:#949494; } .edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:focus,.edit-site-sidebar-navigation-screen-navigation-menus__content .block-editor-list-view-block__menu:hover{ color:#fff; } .edit-site-sidebar-navigation-screen-navigation-menus__loading.components-spinner{ display:block; margin-left:auto; margin-right:auto; } .edit-site-sidebar-navigation-screen-navigation-menus__helper-block-editor{ display:none; } .edit-site-sidebar-navigation-screen-main,.edit-site-sidebar-navigation-screen-templates-browse{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-dataviews__group-header{ margin-top:32px; } .edit-site-sidebar-navigation-screen-dataviews__group-header h2{ font-size:11px; font-weight:500; text-transform:uppercase; } .edit-site-sidebar-dataviews{ margin-left:-16px; margin-right:-16px; } .edit-site-sidebar-navigation-screen-dataviews__custom-items .edit-site-sidebar-dataviews-dataview-item{ padding-right:8px; } .edit-site-sidebar-dataviews-dataview-item{ border-radius:2px; } .edit-site-sidebar-dataviews-dataview-item .edit-site-sidebar-dataviews-dataview-item__dropdown-menu{ min-width:auto; } .edit-site-sidebar-dataviews-dataview-item:focus,.edit-site-sidebar-dataviews-dataview-item:hover,.edit-site-sidebar-dataviews-dataview-item[aria-current]{ color:#e0e0e0; } .edit-site-sidebar-dataviews-dataview-item.is-selected{ background:#2f2f2f; color:#fff; font-weight:500; } .edit-site-site-hub{ align-items:center; display:flex; gap:8px; height:60px; justify-content:space-between; margin-right:12px; } .edit-site-site-hub__actions{ flex-shrink:0; } .edit-site-site-hub__view-mode-toggle-container{ flex-shrink:0; height:60px; width:60px; } .edit-site-site-hub__view-mode-toggle-container.has-transparent-background .edit-site-layout__view-mode-toggle-icon{ background:#0000; } .edit-site-site-hub__title .components-button{ color:#e0e0e0; display:block; flex-grow:1; font-size:15px; font-weight:500; margin-left:-4px; overflow:hidden; padding-right:16px; position:relative; text-decoration:none; text-overflow:ellipsis; white-space:nowrap; } .edit-site-site-hub__title .components-button:active,.edit-site-site-hub__title .components-button:focus,.edit-site-site-hub__title .components-button:hover{ color:#e0e0e0; } .edit-site-site-hub__title .components-button:focus{ box-shadow:none; outline:none; } .edit-site-site-hub__title .components-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #1e1e1e, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .edit-site-site-hub__title .components-button:after{ content:"↗"; font-weight:400; opacity:0; position:absolute; right:0; } @media not (prefers-reduced-motion){ .edit-site-site-hub__title .components-button:after{ transition:opacity .1s linear; } } .edit-site-site-hub__title .components-button:active:after,.edit-site-site-hub__title .components-button:focus:after,.edit-site-site-hub__title .components-button:hover:after{ opacity:1; } .edit-site-site-hub_toggle-command-center{ color:#e0e0e0; } .edit-site-site-hub_toggle-command-center:active svg,.edit-site-site-hub_toggle-command-center:hover svg{ fill:#f0f0f0; } .edit-site-site-icon__icon{ fill:currentColor; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__icon{ padding:12px; } .edit-site-site-icon__image{ aspect-ratio:1/1; background:#333; height:100%; object-fit:cover; width:100%; } .edit-site-layout.is-full-canvas .edit-site-site-icon__image{ border-radius:0; } .edit-site-editor__view-mode-toggle button:focus{ position:relative; } .edit-site-editor__view-mode-toggle button:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 calc(1px + var(--wp-admin-border-width-focus)) #fff; content:""; display:block; left:0; position:absolute; right:0; top:0; z-index:1; } .edit-site-style-book{ align-items:stretch; display:flex; flex-direction:column; height:100%; } .edit-site-style-book.is-button{ border-radius:8px; } .edit-site-style-book__iframe{ display:block; height:100%; width:100%; } .edit-site-style-book__iframe.is-button{ border-radius:8px; } .edit-site-style-book__iframe.is-focused{ outline:calc(var(--wp-admin-border-width-focus)*2) solid var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-2); } .edit-site-style-book__tablist-container{ background:#fff; display:flex; flex:none; padding-right:56px; width:100%; } .edit-site-style-book__tabpanel{ flex:1 0 auto; overflow:auto; } .edit-site-editor-canvas-container{ background-color:#ddd; height:100%; } .edit-site-editor-canvas-container iframe{ display:block; height:100%; width:100%; } .edit-site-layout.is-full-canvas .edit-site-editor-canvas-container{ padding:24px 24px 0; } .edit-site-editor-canvas-container__section{ background:#fff; border-radius:8px; bottom:0; left:0; overflow:hidden; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .edit-site-editor-canvas-container__section{ transition:all .3s; } } .edit-site-editor-canvas-container__close-button{ background:#fff; position:absolute; right:8px; top:8px; z-index:2; } .edit-site-post-edit{ padding:24px; } .edit-site-post-edit.is-empty .edit-site-page-content{ align-items:center; display:flex; justify-content:center; } .dataforms-layouts-panel__field-dropdown .fields-controls__password{ border-top:1px solid #e0e0e0; padding-top:16px; } .edit-site-post-list__featured-image{ height:100%; object-fit:cover; width:100%; } .edit-site-post-list__featured-image-wrapper{ border-radius:4px; height:100%; width:100%; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)){ background-color:#f0f0f0; border-radius:4px; display:block; flex-grow:0 !important; height:32px; overflow:hidden; position:relative; width:32px; } .edit-site-post-list__featured-image-wrapper.is-layout-table .edit-site-post-list__featured-image-button:after,.edit-site-post-list__featured-image-wrapper.is-layout-table:not(:has(.edit-site-post-list__featured-image-button)):after{ border-radius:4px; box-shadow:inset 0 0 0 1px #0000001a; content:""; height:100%; left:0; position:absolute; top:0; width:100%; } .edit-site-post-list__featured-image-button{ background-color:unset; border:none; border-radius:4px; box-shadow:none; box-sizing:border-box; cursor:pointer; height:100%; overflow:hidden; padding:0; width:100%; } .edit-site-post-list__featured-image-button:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .dataviews-view-grid__card.is-selected .edit-site-post-list__featured-image-button:after{ background:rgba(var(--wp-admin-theme-color--rgb), .04); box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .edit-site-post-list__status-icon{ height:24px; width:24px; } .edit-site-post-list__status-icon svg{ fill:currentColor; margin-left:-4px; } .edit-site-resizable-frame__inner{ position:relative; } body:has(.edit-site-resizable-frame__inner.is-resizing){ cursor:col-resize; user-select:none; -webkit-user-select:none; } .edit-site-resizable-frame__inner.is-resizing:before{ content:""; inset:0; position:absolute; z-index:1; } .edit-site-resizable-frame__inner-content{ inset:0; position:absolute; z-index:0; } .edit-site-resizable-frame__handle{ align-items:center; background-color:#75757566; border:0; border-radius:4px; cursor:col-resize; display:flex; height:64px; justify-content:flex-end; padding:0; position:absolute; top:calc(50% - 32px); width:4px; z-index:100; } .edit-site-resizable-frame__handle:before{ content:""; height:100%; left:100%; position:absolute; width:32px; } .edit-site-resizable-frame__handle:after{ content:""; height:100%; position:absolute; right:100%; width:32px; } .edit-site-resizable-frame__handle:focus-visible{ outline:2px solid #0000; } .edit-site-resizable-frame__handle.is-resizing,.edit-site-resizable-frame__handle:focus,.edit-site-resizable-frame__handle:hover{ background-color:var(--wp-admin-theme-color); } .edit-site-push-changes-to-global-styles-control .components-button{ justify-content:center; width:100%; } @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:70px; padding-top:0; } .font-library-modal .font-library-modal__subtitle{ font-size:11px; font-weight:500; text-transform:uppercase; } .font-library-modal .components-navigator-screen{ padding:3px; } .font-library-modal__tabpanel-layout{ margin-top:32px; } .font-library-modal__tabpanel-layout .font-library-modal__loading{ align-items:center; display:flex; height:100%; justify-content:center; left:0; padding-top:120px; position:absolute; top:0; width:100%; } .font-library-modal__footer{ background-color:#fff; border-top:1px solid #ddd; bottom:32px; height:70px; margin:0 -32px -32px; padding:16px 32px; position:absolute; width:100%; } .font-library-modal__page-selection{ font-size:11px; font-weight:500; text-transform:uppercase; } @media (min-width:600px){ .font-library-modal__page-selection .components-select-control__input{ font-size:11px !important; font-weight:500; } } .font-library-modal__tabpanel-layout .components-base-control__field{ margin-bottom:0; } .font-library-modal__fonts-title{ font-size:11px; font-weight:600; text-transform:uppercase; } .font-library-modal__fonts-list,.font-library-modal__fonts-title{ margin-bottom:0; margin-top:0; } .font-library-modal__fonts-list-item{ margin-bottom:0; } .font-library-modal__font-card{ border:1px solid #e0e0e0; height:auto !important; margin-top:-1px; padding:16px; width:100%; } .font-library-modal__font-card:hover{ background-color:#f0f0f0; } .font-library-modal__font-card .font-library-modal__font-card__name{ font-weight:700; } .font-library-modal__font-card .font-library-modal__font-card__count{ color:#757575; } .font-library-modal__font-card .font-library-modal__font-variant_demo-image{ display:block; height:24px; width:auto; } .font-library-modal__font-card .font-library-modal__font-variant_demo-text{ flex-shrink:0; white-space:nowrap; } @media not (prefers-reduced-motion){ .font-library-modal__font-card .font-library-modal__font-variant_demo-text{ transition:opacity .3s ease-in-out; } } .font-library-modal__font-variant{ border-bottom:1px solid #e0e0e0; padding-bottom:16px; } .font-library-modal__tablist-container{ background:#fff; border-bottom:1px solid #ddd; margin:0 -32px; padding:0 16px; position:sticky; top:0; z-index:1; } .font-library-modal__tablist-container [role=tablist]{ margin-bottom:-1px; } .font-library-modal__upload-area{ align-items:center; display:flex; height:256px !important; justify-content:center; width:100%; } button.font-library-modal__upload-area{ background-color:#f0f0f0; } .font-library-modal__local-fonts{ margin:0 auto; width:80%; } .font-library-modal__local-fonts .font-library-modal__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-modal__select-all{ padding:16px 16px 16px 17px; } .font-library-modal__select-all .components-checkbox-control__label{ padding-left:16px; } .edit-site-pagination .components-button.is-tertiary{ height:32px; justify-content:center; width:32px; } .edit-site-global-styles-variations_item{ box-sizing:border-box; cursor:pointer; } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ border-radius:2px; outline:1px solid #0000001a; outline-offset:-1px; overflow:hidden; position:relative; } @media not (prefers-reduced-motion){ .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview{ transition:outline .1s linear; } } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill{ height:32px; } .edit-site-global-styles-variations_item .edit-site-global-styles-variations_item-preview.is-pill .block-editor-iframe__scale-container{ overflow:hidden; } .edit-site-global-styles-variations_item:not(.is-active):hover .edit-site-global-styles-variations_item-preview{ outline-color:#0000004d; } .edit-site-global-styles-variations_item.is-active .edit-site-global-styles-variations_item-preview,.edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:#1e1e1e; outline-offset:1px; outline-width:var(--wp-admin-border-width-focus); } .edit-site-global-styles-variations_item:focus-visible .edit-site-global-styles-variations_item-preview{ outline-color:var(--wp-admin-theme-color); } .edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root{ box-shadow:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-screen-root>div>hr{ display:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider{ overflow-y:auto; padding-left:0; padding-right:0; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .components-tools-panel{ border-top:none; } .edit-site-styles .edit-site-page-content .edit-site-global-styles-sidebar__navigator-provider .edit-site-global-styles-sidebar__navigator-screen{ outline:none; padding:12px; } .edit-site-styles .edit-site-page-content .edit-site-page-header{ padding-left:48px; padding-right:48px; } @container (max-width: 430px){ .edit-site-styles .edit-site-page-content .edit-site-page-header{ padding-left:24px; padding-right:24px; } } .edit-site-styles .edit-site-page-content .edit-site-sidebar-button{ color:#1e1e1e; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon{ padding:0 8px; width:auto; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon svg{ display:none; } .show-icon-labels .edit-site-styles .edit-site-page-content .edit-site-page-header__actions .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } ::view-transition-image-pair(root){ isolation:auto; } ::view-transition-new(root),::view-transition-old(root){ animation:none; display:block; mix-blend-mode:normal; } body.js #wpadminbar{ display:none; } body.js #wpbody{ padding-top:0; } body.js.appearance_page_gutenberg-template-parts,body.js.site-editor-php{ background:#fff; } body.js.appearance_page_gutenberg-template-parts #wpcontent,body.js.site-editor-php #wpcontent{ padding-left:0; } body.js.appearance_page_gutenberg-template-parts #wpbody-content,body.js.site-editor-php #wpbody-content{ padding-bottom:0; } body.js.appearance_page_gutenberg-template-parts #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.appearance_page_gutenberg-template-parts #wpfooter,body.js.site-editor-php #wpbody-content>div:not(.edit-site):not(#screen-meta),body.js.site-editor-php #wpfooter{ display:none; } body.js.appearance_page_gutenberg-template-parts .a11y-speak-region,body.js.site-editor-php .a11y-speak-region{ left:-1px; top:-1px; } body.js.appearance_page_gutenberg-template-parts ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-template-parts ul#adminmenu>li.current>a.current:after,body.js.site-editor-php ul#adminmenu a.wp-has-current-submenu:after,body.js.site-editor-php ul#adminmenu>li.current>a.current:after{ border-right-color:#fff; } body.js.appearance_page_gutenberg-template-parts .media-frame select.attachment-filters:last-of-type,body.js.site-editor-php .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } body.js.site-editor-php{ background:#1e1e1e; } .edit-site{ box-sizing:border-box; height:100vh; } .edit-site *,.edit-site :after,.edit-site :before{ box-sizing:inherit; } @media (min-width:600px){ .edit-site{ bottom:0; left:0; min-height:100vh; position:fixed; right:0; top:0; } } .no-js .edit-site{ min-height:0; position:static; } .edit-site .interface-interface-skeleton{ top:0; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.interface-complementary-area-header{background:#fff;gap:4px;padding-left:8px}.interface-complementary-area-header .interface-complementary-area-header__title{margin:0 0 0 auto}.interface-complementary-area{background:#fff;color:#1e1e1e;height:100%;overflow:auto}@media (min-width:600px){.interface-complementary-area{-webkit-overflow-scrolling:touch}}@media (min-width:782px){.interface-complementary-area{width:280px}}.interface-complementary-area .components-panel{border:none;position:relative;z-index:0}.interface-complementary-area .components-panel__header{position:sticky;top:0;z-index:1}.interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{top:0}.interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){margin-top:0}.interface-complementary-area h2{color:#1e1e1e;font-size:13px;font-weight:500;margin-bottom:1.5em}.interface-complementary-area h3{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.interface-complementary-area hr{border-bottom:1px solid #f0f0f0;border-top:none;margin:1.5em 0}.interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{box-shadow:none;margin-bottom:1.5em}.interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{margin-bottom:0}.interface-complementary-area .block-editor-skip-to-selected-block:focus{bottom:10px;left:10px;right:auto;top:auto}.interface-complementary-area__fill{height:100%}@media (min-width:782px){body.js.is-fullscreen-mode{height:calc(100% + 32px);margin-top:-32px}body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{display:none}body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{margin-right:0}}html.interface-interface-skeleton__html-container{position:fixed;width:100%}@media (min-width:782px){html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){position:static;width:auto}}.interface-interface-skeleton{bottom:0;display:flex;flex-direction:row;height:auto;left:0;max-height:100%;position:fixed;top:46px}@media (min-width:783px){.interface-interface-skeleton{top:32px}.is-fullscreen-mode .interface-interface-skeleton{top:0}}.interface-interface-skeleton__editor{display:flex;flex:0 1 100%;flex-direction:column;overflow:hidden}.interface-interface-skeleton{right:0}@media (min-width:783px){.interface-interface-skeleton{right:160px}}@media (min-width:783px){.auto-fold .interface-interface-skeleton{right:36px}}@media (min-width:961px){.auto-fold .interface-interface-skeleton{right:160px}}.folded .interface-interface-skeleton{right:0}@media (min-width:783px){.folded .interface-interface-skeleton{right:36px}}body.is-fullscreen-mode .interface-interface-skeleton{right:0!important}.interface-interface-skeleton__body{display:flex;flex-grow:1;overflow:auto;overscroll-behavior-y:none;position:relative}@media (min-width:782px){.has-footer .interface-interface-skeleton__body{padding-bottom:25px}}.interface-interface-skeleton__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;z-index:20}@media (min-width:782px){.interface-interface-skeleton__content{z-index:auto}}.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{background:#fff;bottom:0;color:#1e1e1e;flex-shrink:0;position:absolute;right:0;top:0;width:auto;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{position:relative!important}}.interface-interface-skeleton__sidebar{border-top:1px solid #e0e0e0;overflow:hidden}@media (min-width:782px){.interface-interface-skeleton__sidebar{box-shadow:1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__secondary-sidebar{border-top:1px solid #e0e0e0;left:0}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar{box-shadow:-1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);color:#1e1e1e;flex-shrink:0;height:auto;outline:1px solid #0000;z-index:30}.interface-interface-skeleton__footer{background-color:#fff;border-top:1px solid #e0e0e0;bottom:0;color:#1e1e1e;display:none;flex-shrink:0;height:auto;position:absolute;right:0;width:100%;z-index:90}@media (min-width:782px){.interface-interface-skeleton__footer{display:flex}}.interface-interface-skeleton__footer .block-editor-block-breadcrumb{align-items:center;background:#fff;display:flex;font-size:13px;height:24px;padding:0 18px;z-index:30}.interface-interface-skeleton__actions{background:#fff;bottom:auto;color:#1e1e1e;left:0;position:fixed!important;right:auto;top:-9999em;width:100vw;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__actions{width:280px}}.interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{bottom:0;top:auto}.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:46px}@media (min-width:782px){.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{border-right:1px solid #ddd;top:32px}.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:0}}.interface-pinned-items{display:flex;gap:8px}.interface-pinned-items .components-button{display:none;margin:0}.interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{display:flex}.interface-pinned-items .components-button svg{max-height:24px;max-width:24px}@media (min-width:600px){.interface-pinned-items .components-button{display:flex}}.wp-block[data-type="core/widget-area"]{margin-left:auto;margin-right:auto;max-width:700px}.wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title{background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;height:48px;margin:0;position:relative;transform:translateZ(0);z-index:1}.wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title:hover{background:#fff}.wp-block[data-type="core/widget-area"] .block-list-appender.wp-block{position:relative;width:auto}.wp-block[data-type="core/widget-area"] .editor-styles-wrapper .wp-block.wp-block.wp-block.wp-block.wp-block{max-width:100%}.wp-block[data-type="core/widget-area"] .components-panel__body.is-opened{padding:0}.blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper{margin:0;padding:0}.blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper>.block-editor-block-list__layout{margin-top:-48px;min-height:32px;padding:72px 16px 16px}.wp-block-widget-area__highlight-drop-zone{outline:var(--wp-admin-border-width-focus) solid var(--wp-admin-theme-color)}body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title,body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title *{pointer-events:none}.edit-widgets-error-boundary{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;margin:60px auto auto;max-width:780px;padding:20px}.edit-widgets-header{align-items:center;background:#fff;display:flex;height:60px;justify-content:space-between;overflow:auto}@media (min-width:600px){.edit-widgets-header{overflow:visible}}.edit-widgets-header .selected-block-tools-wrapper{align-items:center;display:flex;height:60px;overflow:hidden}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-contextual-toolbar{border-bottom:0;height:100%}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar{height:100%;padding-top:15px}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){height:32px}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group{border-left:none}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar:after{background-color:#ddd;content:"";height:24px;margin-right:8px;margin-top:4px;width:1px}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar .components-toolbar-group.components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{display:none}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{height:32px;overflow:visible}@media (min-width:600px){.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{position:relative;top:-10px}}.edit-widgets-header__navigable-toolbar-wrapper{align-items:center;display:flex;flex-shrink:2;height:60px;justify-content:center;overflow:hidden;padding-left:8px;padding-right:16px}.edit-widgets-header__title{font-size:20px;margin:0 0 0 20px;padding:0}.edit-widgets-header__actions{align-items:center;display:flex;gap:8px;padding-left:4px}@media (min-width:600px){.edit-widgets-header__actions{padding-left:8px}}.edit-widgets-header-toolbar{gap:8px;margin-left:8px}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon{height:32px;min-width:32px;padding:4px}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon.is-pressed,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon.is-pressed{background:#1e1e1e}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:focus:not(:disabled),.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 1px #fff;outline:1px solid #0000}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:before,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:before{display:none}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{padding-left:8px;padding-right:8px}@media (min-width:600px){.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{padding-left:12px;padding-right:12px}}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle:after{content:none}@media not (prefers-reduced-motion){.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle.is-pressed svg{transform:rotate(-45deg)}.edit-widgets-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.edit-widgets-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.edit-widgets-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.edit-widgets-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.edit-widgets-keyboard-shortcut-help-modal__shortcut:empty{display:none}.edit-widgets-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 1rem 0 0;text-align:left}.edit-widgets-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 .2rem 0 0}.components-panel__header.edit-widgets-sidebar__panel-tabs{padding-right:0}.edit-widgets-widget-areas__top-container{display:flex;padding:16px}.edit-widgets-widget-areas__top-container .block-editor-block-icon{margin-left:16px}.edit-widgets-notices__snackbar{bottom:20px;left:0;padding-left:16px;padding-right:16px;position:fixed;right:0}@media (min-width:783px){.edit-widgets-notices__snackbar{right:160px}}@media (min-width:783px){.auto-fold .edit-widgets-notices__snackbar{right:36px}}@media (min-width:961px){.auto-fold .edit-widgets-notices__snackbar{right:160px}}.folded .edit-widgets-notices__snackbar{right:0}@media (min-width:783px){.folded .edit-widgets-notices__snackbar{right:36px}}body.is-fullscreen-mode .edit-widgets-notices__snackbar{right:0!important}.edit-widgets-notices__dismissible .components-notice,.edit-widgets-notices__pinned .components-notice{border-bottom:1px solid #0003;box-sizing:border-box;min-height:60px;padding:0 12px}.edit-widgets-notices__dismissible .components-notice .components-notice__dismiss,.edit-widgets-notices__pinned .components-notice .components-notice__dismiss{margin-top:12px}.edit-widgets-layout__inserter-panel{display:flex;flex-direction:column;height:100%}.edit-widgets-layout__inserter-panel .block-editor-inserter__menu{overflow:hidden}.edit-widgets-layout__inserter-panel-content{height:calc(100% - 44px)}.edit-widgets-layout__inserter-panel-content .block-editor-inserter__tablist-and-close{display:none}@media (min-width:782px){.edit-widgets-layout__inserter-panel-content{height:100%}}.components-popover.more-menu-dropdown__content{z-index:99998}.edit-widgets-welcome-guide{width:312px}.edit-widgets-welcome-guide__image{background:#00a0d2;margin:0 0 16px}.edit-widgets-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-widgets-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-widgets-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 24px;padding:0 32px}.edit-widgets-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-widgets-block-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;position:relative}.edit-widgets-block-editor,.edit-widgets-block-editor .block-editor-writing-flow,.edit-widgets-block-editor>div:last-of-type{display:flex;flex-direction:column;flex-grow:1}.edit-widgets-block-editor .edit-widgets-main-block-list{height:100%}.edit-widgets-block-editor .components-button{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.edit-widgets-block-editor .components-button.has-icon,.edit-widgets-block-editor .components-button.is-tertiary{padding:6px}.edit-widgets-editor__list-view-panel{display:flex;flex-direction:column;height:100%;min-width:350px}.edit-widgets-editor__list-view-panel-content{height:calc(100% - 44px);overflow-y:auto;padding:8px}.edit-widgets-editor__list-view-panel-header{align-items:center;border-bottom:1px solid #ddd;display:flex;height:48px;justify-content:space-between;padding-left:8px;padding-right:16px}body.js.appearance_page_gutenberg-widgets,body.js.widgets-php{background:#fff}body.js.appearance_page_gutenberg-widgets #wpcontent,body.js.widgets-php #wpcontent{padding-right:0}body.js.appearance_page_gutenberg-widgets #wpbody-content,body.js.widgets-php #wpbody-content{padding-bottom:0}body.js.appearance_page_gutenberg-widgets #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.appearance_page_gutenberg-widgets #wpfooter,body.js.widgets-php #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.widgets-php #wpfooter{display:none}body.js.appearance_page_gutenberg-widgets .a11y-speak-region,body.js.widgets-php .a11y-speak-region{right:-1px;top:-1px}body.js.appearance_page_gutenberg-widgets ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-widgets ul#adminmenu>li.current>a.current:after,body.js.widgets-php ul#adminmenu a.wp-has-current-submenu:after,body.js.widgets-php ul#adminmenu>li.current>a.current:after{border-left-color:#fff}body.js.appearance_page_gutenberg-widgets .media-frame select.attachment-filters:last-of-type,body.js.widgets-php .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}.blocks-widgets-container{box-sizing:border-box}.blocks-widgets-container *,.blocks-widgets-container :after,.blocks-widgets-container :before{box-sizing:inherit}@media (min-width:600px){.blocks-widgets-container{bottom:0;left:0;min-height:calc(100vh - 46px);position:absolute;right:0;top:0}}@media (min-width:782px){.blocks-widgets-container{min-height:calc(100vh - 32px)}}.blocks-widgets-container .interface-interface-skeleton__content{background-color:#f0f0f0}.blocks-widgets-container .editor-styles-wrapper{margin:auto;max-width:700px}.edit-widgets-sidebar .components-button.interface-complementary-area__pin-unpin-item{display:none}.js .widgets-php .notice{display:none!important}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.interface-complementary-area-header{background:#fff;gap:4px;padding-right:8px}.interface-complementary-area-header .interface-complementary-area-header__title{margin:0 auto 0 0}.interface-complementary-area{background:#fff;color:#1e1e1e;height:100%;overflow:auto}@media (min-width:600px){.interface-complementary-area{-webkit-overflow-scrolling:touch}}@media (min-width:782px){.interface-complementary-area{width:280px}}.interface-complementary-area .components-panel{border:none;position:relative;z-index:0}.interface-complementary-area .components-panel__header{position:sticky;top:0;z-index:1}.interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{top:0}.interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){margin-top:0}.interface-complementary-area h2{color:#1e1e1e;font-size:13px;font-weight:500;margin-bottom:1.5em}.interface-complementary-area h3{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.interface-complementary-area hr{border-bottom:1px solid #f0f0f0;border-top:none;margin:1.5em 0}.interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{box-shadow:none;margin-bottom:1.5em}.interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{margin-bottom:0}.interface-complementary-area .block-editor-skip-to-selected-block:focus{bottom:10px;left:auto;right:10px;top:auto}.interface-complementary-area__fill{height:100%}@media (min-width:782px){body.js.is-fullscreen-mode{height:calc(100% + 32px);margin-top:-32px}body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{display:none}body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{margin-left:0}}html.interface-interface-skeleton__html-container{position:fixed;width:100%}@media (min-width:782px){html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){position:static;width:auto}}.interface-interface-skeleton{bottom:0;display:flex;flex-direction:row;height:auto;max-height:100%;position:fixed;right:0;top:46px}@media (min-width:783px){.interface-interface-skeleton{top:32px}.is-fullscreen-mode .interface-interface-skeleton{top:0}}.interface-interface-skeleton__editor{display:flex;flex:0 1 100%;flex-direction:column;overflow:hidden}.interface-interface-skeleton{left:0}@media (min-width:783px){.interface-interface-skeleton{left:160px}}@media (min-width:783px){.auto-fold .interface-interface-skeleton{left:36px}}@media (min-width:961px){.auto-fold .interface-interface-skeleton{left:160px}}.folded .interface-interface-skeleton{left:0}@media (min-width:783px){.folded .interface-interface-skeleton{left:36px}}body.is-fullscreen-mode .interface-interface-skeleton{left:0!important}.interface-interface-skeleton__body{display:flex;flex-grow:1;overflow:auto;overscroll-behavior-y:none;position:relative}@media (min-width:782px){.has-footer .interface-interface-skeleton__body{padding-bottom:25px}}.interface-interface-skeleton__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;z-index:20}@media (min-width:782px){.interface-interface-skeleton__content{z-index:auto}}.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{background:#fff;bottom:0;color:#1e1e1e;flex-shrink:0;left:0;position:absolute;top:0;width:auto;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{position:relative!important}}.interface-interface-skeleton__sidebar{border-top:1px solid #e0e0e0;overflow:hidden}@media (min-width:782px){.interface-interface-skeleton__sidebar{box-shadow:-1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__secondary-sidebar{border-top:1px solid #e0e0e0;right:0}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar{box-shadow:1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);color:#1e1e1e;flex-shrink:0;height:auto;outline:1px solid #0000;z-index:30}.interface-interface-skeleton__footer{background-color:#fff;border-top:1px solid #e0e0e0;bottom:0;color:#1e1e1e;display:none;flex-shrink:0;height:auto;left:0;position:absolute;width:100%;z-index:90}@media (min-width:782px){.interface-interface-skeleton__footer{display:flex}}.interface-interface-skeleton__footer .block-editor-block-breadcrumb{align-items:center;background:#fff;display:flex;font-size:13px;height:24px;padding:0 18px;z-index:30}.interface-interface-skeleton__actions{background:#fff;bottom:auto;color:#1e1e1e;left:auto;position:fixed!important;right:0;top:-9999em;width:100vw;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__actions{width:280px}}.interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{bottom:0;top:auto}.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:46px}@media (min-width:782px){.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{border-left:1px solid #ddd;top:32px}.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:0}}.interface-pinned-items{display:flex;gap:8px}.interface-pinned-items .components-button{display:none;margin:0}.interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{display:flex}.interface-pinned-items .components-button svg{max-height:24px;max-width:24px}@media (min-width:600px){.interface-pinned-items .components-button{display:flex}}.wp-block[data-type="core/widget-area"]{margin-left:auto;margin-right:auto;max-width:700px}.wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title{background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;height:48px;margin:0;position:relative;transform:translateZ(0);z-index:1}.wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title:hover{background:#fff}.wp-block[data-type="core/widget-area"] .block-list-appender.wp-block{position:relative;width:auto}.wp-block[data-type="core/widget-area"] .editor-styles-wrapper .wp-block.wp-block.wp-block.wp-block.wp-block{max-width:100%}.wp-block[data-type="core/widget-area"] .components-panel__body.is-opened{padding:0}.blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper{margin:0;padding:0}.blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper>.block-editor-block-list__layout{margin-top:-48px;min-height:32px;padding:72px 16px 16px}.wp-block-widget-area__highlight-drop-zone{outline:var(--wp-admin-border-width-focus) solid var(--wp-admin-theme-color)}body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title,body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title *{pointer-events:none}.edit-widgets-error-boundary{box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;margin:60px auto auto;max-width:780px;padding:20px}.edit-widgets-header{align-items:center;background:#fff;display:flex;height:60px;justify-content:space-between;overflow:auto}@media (min-width:600px){.edit-widgets-header{overflow:visible}}.edit-widgets-header .selected-block-tools-wrapper{align-items:center;display:flex;height:60px;overflow:hidden}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-contextual-toolbar{border-bottom:0;height:100%}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar{height:100%;padding-top:15px}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){height:32px}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group{border-right:none}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar:after{background-color:#ddd;content:"";height:24px;margin-left:8px;margin-top:4px;width:1px}.edit-widgets-header .selected-block-tools-wrapper .components-toolbar .components-toolbar-group.components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{display:none}.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{height:32px;overflow:visible}@media (min-width:600px){.edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{position:relative;top:-10px}}.edit-widgets-header__navigable-toolbar-wrapper{align-items:center;display:flex;flex-shrink:2;height:60px;justify-content:center;overflow:hidden;padding-left:16px;padding-right:8px}.edit-widgets-header__title{font-size:20px;margin:0 20px 0 0;padding:0}.edit-widgets-header__actions{align-items:center;display:flex;gap:8px;padding-right:4px}@media (min-width:600px){.edit-widgets-header__actions{padding-right:8px}}.edit-widgets-header-toolbar{gap:8px;margin-right:8px}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon{height:32px;min-width:32px;padding:4px}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon.is-pressed,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon.is-pressed{background:#1e1e1e}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:focus:not(:disabled),.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 1px #fff;outline:1px solid #0000}.edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:before,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:before{display:none}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{padding-left:8px;padding-right:8px}@media (min-width:600px){.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{padding-left:12px;padding-right:12px}}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle:after{content:none}@media not (prefers-reduced-motion){.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle.is-pressed svg{transform:rotate(45deg)}.edit-widgets-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.edit-widgets-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.edit-widgets-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.edit-widgets-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.edit-widgets-keyboard-shortcut-help-modal__shortcut:empty{display:none}.edit-widgets-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 0 0 1rem;text-align:right}.edit-widgets-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.edit-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 0 0 .2rem}.components-panel__header.edit-widgets-sidebar__panel-tabs{padding-left:0}.edit-widgets-widget-areas__top-container{display:flex;padding:16px}.edit-widgets-widget-areas__top-container .block-editor-block-icon{margin-right:16px}.edit-widgets-notices__snackbar{bottom:20px;left:0;padding-left:16px;padding-right:16px;position:fixed;right:0}@media (min-width:783px){.edit-widgets-notices__snackbar{left:160px}}@media (min-width:783px){.auto-fold .edit-widgets-notices__snackbar{left:36px}}@media (min-width:961px){.auto-fold .edit-widgets-notices__snackbar{left:160px}}.folded .edit-widgets-notices__snackbar{left:0}@media (min-width:783px){.folded .edit-widgets-notices__snackbar{left:36px}}body.is-fullscreen-mode .edit-widgets-notices__snackbar{left:0!important}.edit-widgets-notices__dismissible .components-notice,.edit-widgets-notices__pinned .components-notice{border-bottom:1px solid #0003;box-sizing:border-box;min-height:60px;padding:0 12px}.edit-widgets-notices__dismissible .components-notice .components-notice__dismiss,.edit-widgets-notices__pinned .components-notice .components-notice__dismiss{margin-top:12px}.edit-widgets-layout__inserter-panel{display:flex;flex-direction:column;height:100%}.edit-widgets-layout__inserter-panel .block-editor-inserter__menu{overflow:hidden}.edit-widgets-layout__inserter-panel-content{height:calc(100% - 44px)}.edit-widgets-layout__inserter-panel-content .block-editor-inserter__tablist-and-close{display:none}@media (min-width:782px){.edit-widgets-layout__inserter-panel-content{height:100%}}.components-popover.more-menu-dropdown__content{z-index:99998}.edit-widgets-welcome-guide{width:312px}.edit-widgets-welcome-guide__image{background:#00a0d2;margin:0 0 16px}.edit-widgets-welcome-guide__image>img{display:block;max-width:100%;object-fit:cover}.edit-widgets-welcome-guide__heading{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:24px;line-height:1.4;margin:16px 0;padding:0 32px}.edit-widgets-welcome-guide__text{font-size:13px;line-height:1.4;margin:0 0 24px;padding:0 32px}.edit-widgets-welcome-guide__inserter-icon{margin:0 4px;vertical-align:text-top}.edit-widgets-block-editor{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;position:relative}.edit-widgets-block-editor,.edit-widgets-block-editor .block-editor-writing-flow,.edit-widgets-block-editor>div:last-of-type{display:flex;flex-direction:column;flex-grow:1}.edit-widgets-block-editor .edit-widgets-main-block-list{height:100%}.edit-widgets-block-editor .components-button{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.edit-widgets-block-editor .components-button.has-icon,.edit-widgets-block-editor .components-button.is-tertiary{padding:6px}.edit-widgets-editor__list-view-panel{display:flex;flex-direction:column;height:100%;min-width:350px}.edit-widgets-editor__list-view-panel-content{height:calc(100% - 44px);overflow-y:auto;padding:8px}.edit-widgets-editor__list-view-panel-header{align-items:center;border-bottom:1px solid #ddd;display:flex;height:48px;justify-content:space-between;padding-left:16px;padding-right:8px}body.js.appearance_page_gutenberg-widgets,body.js.widgets-php{background:#fff}body.js.appearance_page_gutenberg-widgets #wpcontent,body.js.widgets-php #wpcontent{padding-left:0}body.js.appearance_page_gutenberg-widgets #wpbody-content,body.js.widgets-php #wpbody-content{padding-bottom:0}body.js.appearance_page_gutenberg-widgets #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.appearance_page_gutenberg-widgets #wpfooter,body.js.widgets-php #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.widgets-php #wpfooter{display:none}body.js.appearance_page_gutenberg-widgets .a11y-speak-region,body.js.widgets-php .a11y-speak-region{left:-1px;top:-1px}body.js.appearance_page_gutenberg-widgets ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-widgets ul#adminmenu>li.current>a.current:after,body.js.widgets-php ul#adminmenu a.wp-has-current-submenu:after,body.js.widgets-php ul#adminmenu>li.current>a.current:after{border-right-color:#fff}body.js.appearance_page_gutenberg-widgets .media-frame select.attachment-filters:last-of-type,body.js.widgets-php .media-frame select.attachment-filters:last-of-type{max-width:100%;width:auto}.blocks-widgets-container{box-sizing:border-box}.blocks-widgets-container *,.blocks-widgets-container :after,.blocks-widgets-container :before{box-sizing:inherit}@media (min-width:600px){.blocks-widgets-container{bottom:0;left:0;min-height:calc(100vh - 46px);position:absolute;right:0;top:0}}@media (min-width:782px){.blocks-widgets-container{min-height:calc(100vh - 32px)}}.blocks-widgets-container .interface-interface-skeleton__content{background-color:#f0f0f0}.blocks-widgets-container .editor-styles-wrapper{margin:auto;max-width:700px}.edit-widgets-sidebar .components-button.interface-complementary-area__pin-unpin-item{display:none}.js .widgets-php .notice{display:none!important}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .interface-complementary-area-header{ background:#fff; gap:4px; padding-left:8px; } .interface-complementary-area-header .interface-complementary-area-header__title{ margin:0 0 0 auto; } .interface-complementary-area{ background:#fff; color:#1e1e1e; height:100%; overflow:auto; } @media (min-width:600px){ .interface-complementary-area{ -webkit-overflow-scrolling:touch; } } @media (min-width:782px){ .interface-complementary-area{ width:280px; } } .interface-complementary-area .components-panel{ border:none; position:relative; z-index:0; } .interface-complementary-area .components-panel__header{ position:sticky; top:0; z-index:1; } .interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{ top:0; } .interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){ margin-top:0; } .interface-complementary-area h2{ color:#1e1e1e; font-size:13px; font-weight:500; margin-bottom:1.5em; } .interface-complementary-area h3{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .interface-complementary-area hr{ border-bottom:1px solid #f0f0f0; border-top:none; margin:1.5em 0; } .interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{ box-shadow:none; margin-bottom:1.5em; } .interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{ margin-bottom:0; } .interface-complementary-area .block-editor-skip-to-selected-block:focus{ bottom:10px; left:10px; right:auto; top:auto; } .interface-complementary-area__fill{ height:100%; } @media (min-width:782px){ body.js.is-fullscreen-mode{ height:calc(100% + 32px); margin-top:-32px; } body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{ display:none; } body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{ margin-right:0; } } html.interface-interface-skeleton__html-container{ position:fixed; width:100%; } @media (min-width:782px){ html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){ position:static; width:auto; } } .interface-interface-skeleton{ bottom:0; display:flex; flex-direction:row; height:auto; left:0; max-height:100%; position:fixed; top:46px; } @media (min-width:783px){ .interface-interface-skeleton{ top:32px; } .is-fullscreen-mode .interface-interface-skeleton{ top:0; } } .interface-interface-skeleton__editor{ display:flex; flex:0 1 100%; flex-direction:column; overflow:hidden; } .interface-interface-skeleton{ right:0; } @media (min-width:783px){ .interface-interface-skeleton{ right:160px; } } @media (min-width:783px){ .auto-fold .interface-interface-skeleton{ right:36px; } } @media (min-width:961px){ .auto-fold .interface-interface-skeleton{ right:160px; } } .folded .interface-interface-skeleton{ right:0; } @media (min-width:783px){ .folded .interface-interface-skeleton{ right:36px; } } body.is-fullscreen-mode .interface-interface-skeleton{ right:0 !important; } .interface-interface-skeleton__body{ display:flex; flex-grow:1; overflow:auto; overscroll-behavior-y:none; position:relative; } @media (min-width:782px){ .has-footer .interface-interface-skeleton__body{ padding-bottom:25px; } } .interface-interface-skeleton__content{ display:flex; flex-direction:column; flex-grow:1; overflow:auto; z-index:20; } @media (min-width:782px){ .interface-interface-skeleton__content{ z-index:auto; } } .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ background:#fff; bottom:0; color:#1e1e1e; flex-shrink:0; position:absolute; right:0; top:0; width:auto; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ position:relative !important; } } .interface-interface-skeleton__sidebar{ border-top:1px solid #e0e0e0; overflow:hidden; } @media (min-width:782px){ .interface-interface-skeleton__sidebar{ box-shadow:1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__secondary-sidebar{ border-top:1px solid #e0e0e0; left:0; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar{ box-shadow:-1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); color:#1e1e1e; flex-shrink:0; height:auto; outline:1px solid #0000; z-index:30; } .interface-interface-skeleton__footer{ background-color:#fff; border-top:1px solid #e0e0e0; bottom:0; color:#1e1e1e; display:none; flex-shrink:0; height:auto; position:absolute; right:0; width:100%; z-index:90; } @media (min-width:782px){ .interface-interface-skeleton__footer{ display:flex; } } .interface-interface-skeleton__footer .block-editor-block-breadcrumb{ align-items:center; background:#fff; display:flex; font-size:13px; height:24px; padding:0 18px; z-index:30; } .interface-interface-skeleton__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:0; position:fixed !important; right:auto; top:-9999em; width:100vw; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__actions{ width:280px; } } .interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{ bottom:0; top:auto; } .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:46px; } @media (min-width:782px){ .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ border-right:1px solid #ddd; top:32px; } .is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:0; } } .interface-pinned-items{ display:flex; gap:8px; } .interface-pinned-items .components-button{ display:none; margin:0; } .interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{ display:flex; } .interface-pinned-items .components-button svg{ max-height:24px; max-width:24px; } @media (min-width:600px){ .interface-pinned-items .components-button{ display:flex; } } .wp-block[data-type="core/widget-area"]{ margin-left:auto; margin-right:auto; max-width:700px; } .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title{ background:#fff; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; height:48px; margin:0; position:relative; transform:translateZ(0); z-index:1; } .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title:hover{ background:#fff; } .wp-block[data-type="core/widget-area"] .block-list-appender.wp-block{ position:relative; width:auto; } .wp-block[data-type="core/widget-area"] .editor-styles-wrapper .wp-block.wp-block.wp-block.wp-block.wp-block{ max-width:100%; } .wp-block[data-type="core/widget-area"] .components-panel__body.is-opened{ padding:0; } .blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper{ margin:0; padding:0; } .blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper>.block-editor-block-list__layout{ margin-top:-48px; min-height:32px; padding:72px 16px 16px; } .wp-block-widget-area__highlight-drop-zone{ outline:var(--wp-admin-border-width-focus) solid var(--wp-admin-theme-color); } body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title,body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title *{ pointer-events:none; } .edit-widgets-error-boundary{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; margin:60px auto auto; max-width:780px; padding:20px; } .edit-widgets-header{ align-items:center; background:#fff; display:flex; height:60px; justify-content:space-between; overflow:auto; } @media (min-width:600px){ .edit-widgets-header{ overflow:visible; } } .edit-widgets-header .selected-block-tools-wrapper{ align-items:center; display:flex; height:60px; overflow:hidden; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-contextual-toolbar{ border-bottom:0; height:100%; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar{ height:100%; padding-top:15px; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){ height:32px; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group{ border-left:none; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar:after{ background-color:#ddd; content:""; height:24px; margin-right:8px; margin-top:4px; width:1px; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar .components-toolbar-group.components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{ display:none; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{ height:32px; overflow:visible; } @media (min-width:600px){ .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ position:relative; top:-10px; } } .edit-widgets-header__navigable-toolbar-wrapper{ align-items:center; display:flex; flex-shrink:2; height:60px; justify-content:center; overflow:hidden; padding-left:8px; padding-right:16px; } .edit-widgets-header__title{ font-size:20px; margin:0 0 0 20px; padding:0; } .edit-widgets-header__actions{ align-items:center; display:flex; gap:8px; padding-left:4px; } @media (min-width:600px){ .edit-widgets-header__actions{ padding-left:8px; } } .edit-widgets-header-toolbar{ gap:8px; margin-left:8px; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon{ height:32px; min-width:32px; padding:4px; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon.is-pressed,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon.is-pressed{ background:#1e1e1e; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:focus:not(:disabled),.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 1px #fff; outline:1px solid #0000; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:before,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:before{ display:none; } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{ padding-left:8px; padding-right:8px; } @media (min-width:600px){ .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{ padding-left:12px; padding-right:12px; } } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle:after{ content:none; } @media not (prefers-reduced-motion){ .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle.is-pressed svg{ transform:rotate(-45deg); } .edit-widgets-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .edit-widgets-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .edit-widgets-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .edit-widgets-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 1rem 0 0; text-align:left; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 .2rem 0 0; } .components-panel__header.edit-widgets-sidebar__panel-tabs{ padding-right:0; } .edit-widgets-widget-areas__top-container{ display:flex; padding:16px; } .edit-widgets-widget-areas__top-container .block-editor-block-icon{ margin-left:16px; } .edit-widgets-notices__snackbar{ bottom:20px; left:0; padding-left:16px; padding-right:16px; position:fixed; right:0; } @media (min-width:783px){ .edit-widgets-notices__snackbar{ right:160px; } } @media (min-width:783px){ .auto-fold .edit-widgets-notices__snackbar{ right:36px; } } @media (min-width:961px){ .auto-fold .edit-widgets-notices__snackbar{ right:160px; } } .folded .edit-widgets-notices__snackbar{ right:0; } @media (min-width:783px){ .folded .edit-widgets-notices__snackbar{ right:36px; } } body.is-fullscreen-mode .edit-widgets-notices__snackbar{ right:0 !important; } .edit-widgets-notices__dismissible .components-notice,.edit-widgets-notices__pinned .components-notice{ border-bottom:1px solid #0003; box-sizing:border-box; min-height:60px; padding:0 12px; } .edit-widgets-notices__dismissible .components-notice .components-notice__dismiss,.edit-widgets-notices__pinned .components-notice .components-notice__dismiss{ margin-top:12px; } .edit-widgets-layout__inserter-panel{ display:flex; flex-direction:column; height:100%; } .edit-widgets-layout__inserter-panel .block-editor-inserter__menu{ overflow:hidden; } .edit-widgets-layout__inserter-panel-content{ height:calc(100% - 44px); } .edit-widgets-layout__inserter-panel-content .block-editor-inserter__tablist-and-close{ display:none; } @media (min-width:782px){ .edit-widgets-layout__inserter-panel-content{ height:100%; } } .components-popover.more-menu-dropdown__content{ z-index:99998; } .edit-widgets-welcome-guide{ width:312px; } .edit-widgets-welcome-guide__image{ background:#00a0d2; margin:0 0 16px; } .edit-widgets-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-widgets-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-widgets-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 24px; padding:0 32px; } .edit-widgets-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-widgets-block-editor{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; position:relative; } .edit-widgets-block-editor,.edit-widgets-block-editor .block-editor-writing-flow,.edit-widgets-block-editor>div:last-of-type{ display:flex; flex-direction:column; flex-grow:1; } .edit-widgets-block-editor .edit-widgets-main-block-list{ height:100%; } .edit-widgets-block-editor .components-button{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .edit-widgets-block-editor .components-button.has-icon,.edit-widgets-block-editor .components-button.is-tertiary{ padding:6px; } .edit-widgets-editor__list-view-panel{ display:flex; flex-direction:column; height:100%; min-width:350px; } .edit-widgets-editor__list-view-panel-content{ height:calc(100% - 44px); overflow-y:auto; padding:8px; } .edit-widgets-editor__list-view-panel-header{ align-items:center; border-bottom:1px solid #ddd; display:flex; height:48px; justify-content:space-between; padding-left:8px; padding-right:16px; } body.js.appearance_page_gutenberg-widgets,body.js.widgets-php{ background:#fff; } body.js.appearance_page_gutenberg-widgets #wpcontent,body.js.widgets-php #wpcontent{ padding-right:0; } body.js.appearance_page_gutenberg-widgets #wpbody-content,body.js.widgets-php #wpbody-content{ padding-bottom:0; } body.js.appearance_page_gutenberg-widgets #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.appearance_page_gutenberg-widgets #wpfooter,body.js.widgets-php #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.widgets-php #wpfooter{ display:none; } body.js.appearance_page_gutenberg-widgets .a11y-speak-region,body.js.widgets-php .a11y-speak-region{ right:-1px; top:-1px; } body.js.appearance_page_gutenberg-widgets ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-widgets ul#adminmenu>li.current>a.current:after,body.js.widgets-php ul#adminmenu a.wp-has-current-submenu:after,body.js.widgets-php ul#adminmenu>li.current>a.current:after{ border-left-color:#fff; } body.js.appearance_page_gutenberg-widgets .media-frame select.attachment-filters:last-of-type,body.js.widgets-php .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } .blocks-widgets-container{ box-sizing:border-box; } .blocks-widgets-container *,.blocks-widgets-container :after,.blocks-widgets-container :before{ box-sizing:inherit; } @media (min-width:600px){ .blocks-widgets-container{ bottom:0; left:0; min-height:calc(100vh - 46px); position:absolute; right:0; top:0; } } @media (min-width:782px){ .blocks-widgets-container{ min-height:calc(100vh - 32px); } } .blocks-widgets-container .interface-interface-skeleton__content{ background-color:#f0f0f0; } .blocks-widgets-container .editor-styles-wrapper{ margin:auto; max-width:700px; } .edit-widgets-sidebar .components-button.interface-complementary-area__pin-unpin-item{ display:none; } .js .widgets-php .notice{ display:none !important; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .interface-complementary-area-header{ background:#fff; gap:4px; padding-right:8px; } .interface-complementary-area-header .interface-complementary-area-header__title{ margin:0 auto 0 0; } .interface-complementary-area{ background:#fff; color:#1e1e1e; height:100%; overflow:auto; } @media (min-width:600px){ .interface-complementary-area{ -webkit-overflow-scrolling:touch; } } @media (min-width:782px){ .interface-complementary-area{ width:280px; } } .interface-complementary-area .components-panel{ border:none; position:relative; z-index:0; } .interface-complementary-area .components-panel__header{ position:sticky; top:0; z-index:1; } .interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{ top:0; } .interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){ margin-top:0; } .interface-complementary-area h2{ color:#1e1e1e; font-size:13px; font-weight:500; margin-bottom:1.5em; } .interface-complementary-area h3{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .interface-complementary-area hr{ border-bottom:1px solid #f0f0f0; border-top:none; margin:1.5em 0; } .interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{ box-shadow:none; margin-bottom:1.5em; } .interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{ margin-bottom:0; } .interface-complementary-area .block-editor-skip-to-selected-block:focus{ bottom:10px; left:auto; right:10px; top:auto; } .interface-complementary-area__fill{ height:100%; } @media (min-width:782px){ body.js.is-fullscreen-mode{ height:calc(100% + 32px); margin-top:-32px; } body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{ display:none; } body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{ margin-left:0; } } html.interface-interface-skeleton__html-container{ position:fixed; width:100%; } @media (min-width:782px){ html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){ position:static; width:auto; } } .interface-interface-skeleton{ bottom:0; display:flex; flex-direction:row; height:auto; max-height:100%; position:fixed; right:0; top:46px; } @media (min-width:783px){ .interface-interface-skeleton{ top:32px; } .is-fullscreen-mode .interface-interface-skeleton{ top:0; } } .interface-interface-skeleton__editor{ display:flex; flex:0 1 100%; flex-direction:column; overflow:hidden; } .interface-interface-skeleton{ left:0; } @media (min-width:783px){ .interface-interface-skeleton{ left:160px; } } @media (min-width:783px){ .auto-fold .interface-interface-skeleton{ left:36px; } } @media (min-width:961px){ .auto-fold .interface-interface-skeleton{ left:160px; } } .folded .interface-interface-skeleton{ left:0; } @media (min-width:783px){ .folded .interface-interface-skeleton{ left:36px; } } body.is-fullscreen-mode .interface-interface-skeleton{ left:0 !important; } .interface-interface-skeleton__body{ display:flex; flex-grow:1; overflow:auto; overscroll-behavior-y:none; position:relative; } @media (min-width:782px){ .has-footer .interface-interface-skeleton__body{ padding-bottom:25px; } } .interface-interface-skeleton__content{ display:flex; flex-direction:column; flex-grow:1; overflow:auto; z-index:20; } @media (min-width:782px){ .interface-interface-skeleton__content{ z-index:auto; } } .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ background:#fff; bottom:0; color:#1e1e1e; flex-shrink:0; left:0; position:absolute; top:0; width:auto; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ position:relative !important; } } .interface-interface-skeleton__sidebar{ border-top:1px solid #e0e0e0; overflow:hidden; } @media (min-width:782px){ .interface-interface-skeleton__sidebar{ box-shadow:-1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__secondary-sidebar{ border-top:1px solid #e0e0e0; right:0; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar{ box-shadow:1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); color:#1e1e1e; flex-shrink:0; height:auto; outline:1px solid #0000; z-index:30; } .interface-interface-skeleton__footer{ background-color:#fff; border-top:1px solid #e0e0e0; bottom:0; color:#1e1e1e; display:none; flex-shrink:0; height:auto; left:0; position:absolute; width:100%; z-index:90; } @media (min-width:782px){ .interface-interface-skeleton__footer{ display:flex; } } .interface-interface-skeleton__footer .block-editor-block-breadcrumb{ align-items:center; background:#fff; display:flex; font-size:13px; height:24px; padding:0 18px; z-index:30; } .interface-interface-skeleton__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:auto; position:fixed !important; right:0; top:-9999em; width:100vw; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__actions{ width:280px; } } .interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{ bottom:0; top:auto; } .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:46px; } @media (min-width:782px){ .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ border-left:1px solid #ddd; top:32px; } .is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:0; } } .interface-pinned-items{ display:flex; gap:8px; } .interface-pinned-items .components-button{ display:none; margin:0; } .interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{ display:flex; } .interface-pinned-items .components-button svg{ max-height:24px; max-width:24px; } @media (min-width:600px){ .interface-pinned-items .components-button{ display:flex; } } .wp-block[data-type="core/widget-area"]{ margin-left:auto; margin-right:auto; max-width:700px; } .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title{ background:#fff; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; height:48px; margin:0; position:relative; transform:translateZ(0); z-index:1; } .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title:hover{ background:#fff; } .wp-block[data-type="core/widget-area"] .block-list-appender.wp-block{ position:relative; width:auto; } .wp-block[data-type="core/widget-area"] .editor-styles-wrapper .wp-block.wp-block.wp-block.wp-block.wp-block{ max-width:100%; } .wp-block[data-type="core/widget-area"] .components-panel__body.is-opened{ padding:0; } .blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper{ margin:0; padding:0; } .blocks-widgets-container .wp-block-widget-area__inner-blocks.editor-styles-wrapper>.block-editor-block-list__layout{ margin-top:-48px; min-height:32px; padding:72px 16px 16px; } .wp-block-widget-area__highlight-drop-zone{ outline:var(--wp-admin-border-width-focus) solid var(--wp-admin-theme-color); } body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title,body.is-dragging-components-draggable .wp-block[data-type="core/widget-area"] .components-panel__body>.components-panel__body-title *{ pointer-events:none; } .edit-widgets-error-boundary{ box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; margin:60px auto auto; max-width:780px; padding:20px; } .edit-widgets-header{ align-items:center; background:#fff; display:flex; height:60px; justify-content:space-between; overflow:auto; } @media (min-width:600px){ .edit-widgets-header{ overflow:visible; } } .edit-widgets-header .selected-block-tools-wrapper{ align-items:center; display:flex; height:60px; overflow:hidden; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-contextual-toolbar{ border-bottom:0; height:100%; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar{ height:100%; padding-top:15px; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){ height:32px; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group{ border-right:none; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar:after{ background-color:#ddd; content:""; height:24px; margin-left:8px; margin-top:4px; width:1px; } .edit-widgets-header .selected-block-tools-wrapper .components-toolbar .components-toolbar-group.components-toolbar-group:after,.edit-widgets-header .selected-block-tools-wrapper .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{ display:none; } .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{ height:32px; overflow:visible; } @media (min-width:600px){ .edit-widgets-header .selected-block-tools-wrapper .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ position:relative; top:-10px; } } .edit-widgets-header__navigable-toolbar-wrapper{ align-items:center; display:flex; flex-shrink:2; height:60px; justify-content:center; overflow:hidden; padding-left:16px; padding-right:8px; } .edit-widgets-header__title{ font-size:20px; margin:0 20px 0 0; padding:0; } .edit-widgets-header__actions{ align-items:center; display:flex; gap:8px; padding-right:4px; } @media (min-width:600px){ .edit-widgets-header__actions{ padding-right:8px; } } .edit-widgets-header-toolbar{ gap:8px; margin-right:8px; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon{ height:32px; min-width:32px; padding:4px; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon.is-pressed,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon.is-pressed{ background:#1e1e1e; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:focus:not(:disabled),.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 1px #fff; outline:1px solid #0000; } .edit-widgets-header-toolbar>.components-button.has-icon.has-icon.has-icon:before,.edit-widgets-header-toolbar>.components-dropdown>.components-button.has-icon.has-icon:before{ display:none; } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{ padding-left:8px; padding-right:8px; } @media (min-width:600px){ .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle{ padding-left:12px; padding-right:12px; } } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle:after{ content:none; } @media not (prefers-reduced-motion){ .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .edit-widgets-header-toolbar__inserter-toggle.edit-widgets-header-toolbar__inserter-toggle.is-pressed svg{ transform:rotate(45deg); } .edit-widgets-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .edit-widgets-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .edit-widgets-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .edit-widgets-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 0 0 1rem; text-align:right; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.edit-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .edit-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 0 0 .2rem; } .components-panel__header.edit-widgets-sidebar__panel-tabs{ padding-left:0; } .edit-widgets-widget-areas__top-container{ display:flex; padding:16px; } .edit-widgets-widget-areas__top-container .block-editor-block-icon{ margin-right:16px; } .edit-widgets-notices__snackbar{ bottom:20px; left:0; padding-left:16px; padding-right:16px; position:fixed; right:0; } @media (min-width:783px){ .edit-widgets-notices__snackbar{ left:160px; } } @media (min-width:783px){ .auto-fold .edit-widgets-notices__snackbar{ left:36px; } } @media (min-width:961px){ .auto-fold .edit-widgets-notices__snackbar{ left:160px; } } .folded .edit-widgets-notices__snackbar{ left:0; } @media (min-width:783px){ .folded .edit-widgets-notices__snackbar{ left:36px; } } body.is-fullscreen-mode .edit-widgets-notices__snackbar{ left:0 !important; } .edit-widgets-notices__dismissible .components-notice,.edit-widgets-notices__pinned .components-notice{ border-bottom:1px solid #0003; box-sizing:border-box; min-height:60px; padding:0 12px; } .edit-widgets-notices__dismissible .components-notice .components-notice__dismiss,.edit-widgets-notices__pinned .components-notice .components-notice__dismiss{ margin-top:12px; } .edit-widgets-layout__inserter-panel{ display:flex; flex-direction:column; height:100%; } .edit-widgets-layout__inserter-panel .block-editor-inserter__menu{ overflow:hidden; } .edit-widgets-layout__inserter-panel-content{ height:calc(100% - 44px); } .edit-widgets-layout__inserter-panel-content .block-editor-inserter__tablist-and-close{ display:none; } @media (min-width:782px){ .edit-widgets-layout__inserter-panel-content{ height:100%; } } .components-popover.more-menu-dropdown__content{ z-index:99998; } .edit-widgets-welcome-guide{ width:312px; } .edit-widgets-welcome-guide__image{ background:#00a0d2; margin:0 0 16px; } .edit-widgets-welcome-guide__image>img{ display:block; max-width:100%; object-fit:cover; } .edit-widgets-welcome-guide__heading{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:24px; line-height:1.4; margin:16px 0; padding:0 32px; } .edit-widgets-welcome-guide__text{ font-size:13px; line-height:1.4; margin:0 0 24px; padding:0 32px; } .edit-widgets-welcome-guide__inserter-icon{ margin:0 4px; vertical-align:text-top; } .edit-widgets-block-editor{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; position:relative; } .edit-widgets-block-editor,.edit-widgets-block-editor .block-editor-writing-flow,.edit-widgets-block-editor>div:last-of-type{ display:flex; flex-direction:column; flex-grow:1; } .edit-widgets-block-editor .edit-widgets-main-block-list{ height:100%; } .edit-widgets-block-editor .components-button{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .edit-widgets-block-editor .components-button.has-icon,.edit-widgets-block-editor .components-button.is-tertiary{ padding:6px; } .edit-widgets-editor__list-view-panel{ display:flex; flex-direction:column; height:100%; min-width:350px; } .edit-widgets-editor__list-view-panel-content{ height:calc(100% - 44px); overflow-y:auto; padding:8px; } .edit-widgets-editor__list-view-panel-header{ align-items:center; border-bottom:1px solid #ddd; display:flex; height:48px; justify-content:space-between; padding-left:16px; padding-right:8px; } body.js.appearance_page_gutenberg-widgets,body.js.widgets-php{ background:#fff; } body.js.appearance_page_gutenberg-widgets #wpcontent,body.js.widgets-php #wpcontent{ padding-left:0; } body.js.appearance_page_gutenberg-widgets #wpbody-content,body.js.widgets-php #wpbody-content{ padding-bottom:0; } body.js.appearance_page_gutenberg-widgets #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.appearance_page_gutenberg-widgets #wpfooter,body.js.widgets-php #wpbody-content>div:not(.blocks-widgets-container):not(#screen-meta),body.js.widgets-php #wpfooter{ display:none; } body.js.appearance_page_gutenberg-widgets .a11y-speak-region,body.js.widgets-php .a11y-speak-region{ left:-1px; top:-1px; } body.js.appearance_page_gutenberg-widgets ul#adminmenu a.wp-has-current-submenu:after,body.js.appearance_page_gutenberg-widgets ul#adminmenu>li.current>a.current:after,body.js.widgets-php ul#adminmenu a.wp-has-current-submenu:after,body.js.widgets-php ul#adminmenu>li.current>a.current:after{ border-right-color:#fff; } body.js.appearance_page_gutenberg-widgets .media-frame select.attachment-filters:last-of-type,body.js.widgets-php .media-frame select.attachment-filters:last-of-type{ max-width:100%; width:auto; } .blocks-widgets-container{ box-sizing:border-box; } .blocks-widgets-container *,.blocks-widgets-container :after,.blocks-widgets-container :before{ box-sizing:inherit; } @media (min-width:600px){ .blocks-widgets-container{ bottom:0; left:0; min-height:calc(100vh - 46px); position:absolute; right:0; top:0; } } @media (min-width:782px){ .blocks-widgets-container{ min-height:calc(100vh - 32px); } } .blocks-widgets-container .interface-interface-skeleton__content{ background-color:#f0f0f0; } .blocks-widgets-container .editor-styles-wrapper{ margin:auto; max-width:700px; } .edit-widgets-sidebar .components-button.interface-complementary-area__pin-unpin-item{ display:none; } .js .widgets-php .notice{ display:none !important; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.nux-dot-tip:after,.nux-dot-tip:before{border-radius:100%;content:" ";pointer-events:none;position:absolute}.nux-dot-tip:before{background:#00739ce6;height:24px;opacity:.9;right:-12px;top:-12px;transform:scale(.3333333333);width:24px}@media not (prefers-reduced-motion){.nux-dot-tip:before{animation:nux-pulse 1.6s cubic-bezier(.17,.67,.92,.62) infinite}}.nux-dot-tip:after{background:#00739c;height:8px;right:-4px;top:-4px;width:8px}@keyframes nux-pulse{to{background:#00739c00;transform:scale(1)}}.nux-dot-tip .components-popover__content{padding:20px 18px;width:350px}@media (min-width:600px){.nux-dot-tip .components-popover__content{width:450px}}.nux-dot-tip .components-popover__content .nux-dot-tip__disable{left:0;position:absolute;top:0}.nux-dot-tip[data-y-axis=top]{margin-top:-4px}.nux-dot-tip[data-y-axis=bottom]{margin-top:4px}.nux-dot-tip[data-y-axis=middle][data-y-axis=left]{margin-right:-4px}.nux-dot-tip[data-y-axis=middle][data-y-axis=right]{margin-right:4px}.nux-dot-tip[data-y-axis=top] .components-popover__content{margin-bottom:20px}.nux-dot-tip[data-y-axis=bottom] .components-popover__content{margin-top:20px}.nux-dot-tip[data-y-axis=middle][data-y-axis=left] .components-popover__content{margin-left:20px}.nux-dot-tip[data-y-axis=middle][data-y-axis=right] .components-popover__content{margin-right:20px}.nux-dot-tip[data-y-axis=center],.nux-dot-tip[data-y-axis=left],.nux-dot-tip[data-y-axis=right]{z-index:1000001}@media (max-width:600px){.nux-dot-tip[data-y-axis=center] .components-popover__content,.nux-dot-tip[data-y-axis=left] .components-popover__content,.nux-dot-tip[data-y-axis=right] .components-popover__content{align-self:end;left:5px;margin:20px 0 0;max-width:none!important;position:fixed;right:5px;width:auto}}.nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{margin-left:0}.nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{margin-right:0}.nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{margin-left:-12px}.nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{margin-right:-12px}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.nux-dot-tip:after,.nux-dot-tip:before{border-radius:100%;content:" ";pointer-events:none;position:absolute}.nux-dot-tip:before{background:#00739ce6;height:24px;left:-12px;opacity:.9;top:-12px;transform:scale(.3333333333);width:24px}@media not (prefers-reduced-motion){.nux-dot-tip:before{animation:nux-pulse 1.6s cubic-bezier(.17,.67,.92,.62) infinite}}.nux-dot-tip:after{background:#00739c;height:8px;left:-4px;top:-4px;width:8px}@keyframes nux-pulse{to{background:#00739c00;transform:scale(1)}}.nux-dot-tip .components-popover__content{padding:20px 18px;width:350px}@media (min-width:600px){.nux-dot-tip .components-popover__content{width:450px}}.nux-dot-tip .components-popover__content .nux-dot-tip__disable{position:absolute;right:0;top:0}.nux-dot-tip[data-y-axis=top]{margin-top:-4px}.nux-dot-tip[data-y-axis=bottom]{margin-top:4px}.nux-dot-tip[data-y-axis=middle][data-y-axis=left]{margin-left:-4px}.nux-dot-tip[data-y-axis=middle][data-y-axis=right]{margin-left:4px}.nux-dot-tip[data-y-axis=top] .components-popover__content{margin-bottom:20px}.nux-dot-tip[data-y-axis=bottom] .components-popover__content{margin-top:20px}.nux-dot-tip[data-y-axis=middle][data-y-axis=left] .components-popover__content{margin-right:20px}.nux-dot-tip[data-y-axis=middle][data-y-axis=right] .components-popover__content{margin-left:20px}.nux-dot-tip[data-y-axis=center],.nux-dot-tip[data-y-axis=left],.nux-dot-tip[data-y-axis=right]{z-index:1000001}@media (max-width:600px){.nux-dot-tip[data-y-axis=center] .components-popover__content,.nux-dot-tip[data-y-axis=left] .components-popover__content,.nux-dot-tip[data-y-axis=right] .components-popover__content{align-self:end;left:5px;margin:20px 0 0;max-width:none!important;position:fixed;right:5px;width:auto}}.nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ /*!rtl:ignore*/margin-left:0}.nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ /*!rtl:ignore*/margin-right:0}.nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ /*!rtl:ignore*/margin-left:-12px}.nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ /*!rtl:ignore*/margin-right:-12px}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .nux-dot-tip:after,.nux-dot-tip:before{ border-radius:100%; content:" "; pointer-events:none; position:absolute; } .nux-dot-tip:before{ background:#00739ce6; height:24px; opacity:.9; right:-12px; top:-12px; transform:scale(.3333333333); width:24px; } @media not (prefers-reduced-motion){ .nux-dot-tip:before{ animation:nux-pulse 1.6s cubic-bezier(.17, .67, .92, .62) infinite; } } .nux-dot-tip:after{ background:#00739c; height:8px; right:-4px; top:-4px; width:8px; } @keyframes nux-pulse{ to{ background:#00739c00; transform:scale(1); } } .nux-dot-tip .components-popover__content{ padding:20px 18px; width:350px; } @media (min-width:600px){ .nux-dot-tip .components-popover__content{ width:450px; } } .nux-dot-tip .components-popover__content .nux-dot-tip__disable{ left:0; position:absolute; top:0; } .nux-dot-tip[data-y-axis=top]{ margin-top:-4px; } .nux-dot-tip[data-y-axis=bottom]{ margin-top:4px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=left]{ margin-right:-4px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=right]{ margin-right:4px; } .nux-dot-tip[data-y-axis=top] .components-popover__content{ margin-bottom:20px; } .nux-dot-tip[data-y-axis=bottom] .components-popover__content{ margin-top:20px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=left] .components-popover__content{ margin-left:20px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=right] .components-popover__content{ margin-right:20px; } .nux-dot-tip[data-y-axis=center],.nux-dot-tip[data-y-axis=left],.nux-dot-tip[data-y-axis=right]{ z-index:1000001; } @media (max-width:600px){ .nux-dot-tip[data-y-axis=center] .components-popover__content,.nux-dot-tip[data-y-axis=left] .components-popover__content,.nux-dot-tip[data-y-axis=right] .components-popover__content{ align-self:end; left:5px; margin:20px 0 0; max-width:none !important; position:fixed; right:5px; width:auto; } } .nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ margin-left:0; } .nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ margin-right:0; } .nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ margin-left:-12px; } .nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ margin-right:-12px; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .nux-dot-tip:after,.nux-dot-tip:before{ border-radius:100%; content:" "; pointer-events:none; position:absolute; } .nux-dot-tip:before{ background:#00739ce6; height:24px; left:-12px; opacity:.9; top:-12px; transform:scale(.3333333333); width:24px; } @media not (prefers-reduced-motion){ .nux-dot-tip:before{ animation:nux-pulse 1.6s cubic-bezier(.17, .67, .92, .62) infinite; } } .nux-dot-tip:after{ background:#00739c; height:8px; left:-4px; top:-4px; width:8px; } @keyframes nux-pulse{ to{ background:#00739c00; transform:scale(1); } } .nux-dot-tip .components-popover__content{ padding:20px 18px; width:350px; } @media (min-width:600px){ .nux-dot-tip .components-popover__content{ width:450px; } } .nux-dot-tip .components-popover__content .nux-dot-tip__disable{ position:absolute; right:0; top:0; } .nux-dot-tip[data-y-axis=top]{ margin-top:-4px; } .nux-dot-tip[data-y-axis=bottom]{ margin-top:4px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=left]{ margin-left:-4px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=right]{ margin-left:4px; } .nux-dot-tip[data-y-axis=top] .components-popover__content{ margin-bottom:20px; } .nux-dot-tip[data-y-axis=bottom] .components-popover__content{ margin-top:20px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=left] .components-popover__content{ margin-right:20px; } .nux-dot-tip[data-y-axis=middle][data-y-axis=right] .components-popover__content{ margin-left:20px; } .nux-dot-tip[data-y-axis=center],.nux-dot-tip[data-y-axis=left],.nux-dot-tip[data-y-axis=right]{ z-index:1000001; } @media (max-width:600px){ .nux-dot-tip[data-y-axis=center] .components-popover__content,.nux-dot-tip[data-y-axis=left] .components-popover__content,.nux-dot-tip[data-y-axis=right] .components-popover__content{ align-self:end; left:5px; margin:20px 0 0; max-width:none !important; position:fixed; right:5px; width:auto; } } .nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ margin-left:0; } .nux-dot-tip.components-popover:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ margin-right:0; } .nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=right] .components-popover__content{ margin-left:-12px; } .nux-dot-tip.components-popover.interface-more-menu-dropdown__content:not([data-y-axis=middle])[data-y-axis=left] .components-popover__content{ margin-right:-12px; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector{background:#fff;box-sizing:border-box}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector *{box-sizing:inherit}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector{margin:-12px}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector h3{margin-bottom:0}#customize-theme-controls .customize-pane-child.control-section-sidebar.is-sub-section-open{transform:translateX(100%)}.customize-widgets-header{background:#f0f0f1;border-bottom:1px solid #e0e0e0;display:flex;justify-content:flex-end;margin:-15px -12px 0;z-index:8}@media (min-width:600px){.customize-widgets-header{margin-bottom:44px}}.customize-widgets-header.is-fixed-toolbar-active{margin-bottom:0}.customize-widgets-header-toolbar{align-items:center;border:none;display:flex;width:100%}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon{border-radius:2px;color:#fff;height:32px;margin:12px auto 12px 0;min-width:32px;padding:0}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon:before{content:none}@media not (prefers-reduced-motion){.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed{background:#1e1e1e}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed svg{transform:rotate(-45deg)}.customize-widgets-header-toolbar .components-button.has-icon.customize-widgets-editor-history-button.redo-button{margin-right:-12px}#customize-sidebar-outer-content{min-width:100%;width:auto}#customize-outer-theme-controls .widgets-inserter{padding:0}#customize-outer-theme-controls .widgets-inserter .customize-section-description-container{display:none}.customize-widgets-layout__inserter-panel{background:#fff}.customize-widgets-layout__inserter-panel-header{align-items:center;border-bottom:1px solid #ddd;box-sizing:border-box;display:flex;height:46px;justify-content:space-between;padding:16px}.customize-widgets-layout__inserter-panel-header .customize-widgets-layout__inserter-panel-header-title{margin:0}.block-editor-inserter__quick-inserter .block-editor-inserter__panel-content{background:#fff}.customize-widgets-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.customize-widgets-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.customize-widgets-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.customize-widgets-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.customize-widgets-keyboard-shortcut-help-modal__shortcut:empty{display:none}.customize-widgets-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 1rem 0 0;text-align:left}.customize-widgets-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 .2rem 0 0}.components-popover.more-menu-dropdown__content{z-index:99998}.customize-control-sidebar_block_editor .block-editor-block-list__block-popover{position:fixed!important;z-index:7}.customize-control-sidebar_block_editor .components-popover,.customize-widgets-popover .components-popover{position:fixed!important}.customize-widgets-welcome-guide__image__wrapper{background:#00a0d2;margin-bottom:8px;text-align:center}.customize-widgets-welcome-guide__image{height:auto}.wrap .customize-widgets-welcome-guide__heading{font-size:18px;font-weight:600}.customize-widgets-welcome-guide__text{line-height:1.7}.customize-widgets-welcome-guide__button{justify-content:center;margin:1em 0;width:100%}.customize-widgets-welcome-guide__separator{margin:1em 0}.customize-widgets-welcome-guide__more-info{line-height:1.4}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section{background-color:#fff;min-height:100%;padding-top:12px!important}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section.open{overflow:unset}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section .customize-section-title{margin-top:-12px!important;position:static!important;width:unset!important}.components-modal__screen-overlay{z-index:999999}.customize-control-sidebar_block_editor,.customize-widgets-layout__inspector{box-sizing:border-box}.customize-control-sidebar_block_editor *,.customize-control-sidebar_block_editor :after,.customize-control-sidebar_block_editor :before,.customize-widgets-layout__inspector *,.customize-widgets-layout__inspector :after,.customize-widgets-layout__inspector :before{box-sizing:inherit}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector{background:#fff;box-sizing:border-box}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector *{box-sizing:inherit}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector{margin:-12px}#customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector h3{margin-bottom:0}#customize-theme-controls .customize-pane-child.control-section-sidebar.is-sub-section-open{transform:translateX(-100%)}.customize-widgets-header{background:#f0f0f1;border-bottom:1px solid #e0e0e0;display:flex;justify-content:flex-end;margin:-15px -12px 0;z-index:8}@media (min-width:600px){.customize-widgets-header{margin-bottom:44px}}.customize-widgets-header.is-fixed-toolbar-active{margin-bottom:0}.customize-widgets-header-toolbar{align-items:center;border:none;display:flex;width:100%}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon{border-radius:2px;color:#fff;height:32px;margin:12px 0 12px auto;min-width:32px;padding:0}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon:before{content:none}@media not (prefers-reduced-motion){.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed{background:#1e1e1e}.customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed svg{transform:rotate(45deg)}.customize-widgets-header-toolbar .components-button.has-icon.customize-widgets-editor-history-button.redo-button{margin-left:-12px}#customize-sidebar-outer-content{min-width:100%;width:auto}#customize-outer-theme-controls .widgets-inserter{padding:0}#customize-outer-theme-controls .widgets-inserter .customize-section-description-container{display:none}.customize-widgets-layout__inserter-panel{background:#fff}.customize-widgets-layout__inserter-panel-header{align-items:center;border-bottom:1px solid #ddd;box-sizing:border-box;display:flex;height:46px;justify-content:space-between;padding:16px}.customize-widgets-layout__inserter-panel-header .customize-widgets-layout__inserter-panel-header-title{margin:0}.block-editor-inserter__quick-inserter .block-editor-inserter__panel-content{background:#fff}.customize-widgets-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.customize-widgets-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.customize-widgets-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.customize-widgets-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.customize-widgets-keyboard-shortcut-help-modal__shortcut:empty{display:none}.customize-widgets-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 0 0 1rem;text-align:right}.customize-widgets-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.customize-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 0 0 .2rem}.components-popover.more-menu-dropdown__content{z-index:99998}.customize-control-sidebar_block_editor .block-editor-block-list__block-popover{position:fixed!important;z-index:7}.customize-control-sidebar_block_editor .components-popover,.customize-widgets-popover .components-popover{position:fixed!important}.customize-widgets-welcome-guide__image__wrapper{background:#00a0d2;margin-bottom:8px;text-align:center}.customize-widgets-welcome-guide__image{height:auto}.wrap .customize-widgets-welcome-guide__heading{font-size:18px;font-weight:600}.customize-widgets-welcome-guide__text{line-height:1.7}.customize-widgets-welcome-guide__button{justify-content:center;margin:1em 0;width:100%}.customize-widgets-welcome-guide__separator{margin:1em 0}.customize-widgets-welcome-guide__more-info{line-height:1.4}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section{background-color:#fff;min-height:100%;padding-top:12px!important}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section.open{overflow:unset}#customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section .customize-section-title{margin-top:-12px!important;position:static!important;width:unset!important}.components-modal__screen-overlay{z-index:999999}.customize-control-sidebar_block_editor,.customize-widgets-layout__inspector{box-sizing:border-box}.customize-control-sidebar_block_editor *,.customize-control-sidebar_block_editor :after,.customize-control-sidebar_block_editor :before,.customize-widgets-layout__inspector *,.customize-widgets-layout__inspector :after,.customize-widgets-layout__inspector :before{box-sizing:inherit}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector{ background:#fff; box-sizing:border-box; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector *{ box-sizing:inherit; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector{ margin:-12px; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector h3{ margin-bottom:0; } #customize-theme-controls .customize-pane-child.control-section-sidebar.is-sub-section-open{ transform:translateX(100%); } .customize-widgets-header{ background:#f0f0f1; border-bottom:1px solid #e0e0e0; display:flex; justify-content:flex-end; margin:-15px -12px 0; z-index:8; } @media (min-width:600px){ .customize-widgets-header{ margin-bottom:44px; } } .customize-widgets-header.is-fixed-toolbar-active{ margin-bottom:0; } .customize-widgets-header-toolbar{ align-items:center; border:none; display:flex; width:100%; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon{ border-radius:2px; color:#fff; height:32px; margin:12px auto 12px 0; min-width:32px; padding:0; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon:before{ content:none; } @media not (prefers-reduced-motion){ .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed{ background:#1e1e1e; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed svg{ transform:rotate(-45deg); } .customize-widgets-header-toolbar .components-button.has-icon.customize-widgets-editor-history-button.redo-button{ margin-right:-12px; } #customize-sidebar-outer-content{ min-width:100%; width:auto; } #customize-outer-theme-controls .widgets-inserter{ padding:0; } #customize-outer-theme-controls .widgets-inserter .customize-section-description-container{ display:none; } .customize-widgets-layout__inserter-panel{ background:#fff; } .customize-widgets-layout__inserter-panel-header{ align-items:center; border-bottom:1px solid #ddd; box-sizing:border-box; display:flex; height:46px; justify-content:space-between; padding:16px; } .customize-widgets-layout__inserter-panel-header .customize-widgets-layout__inserter-panel-header-title{ margin:0; } .block-editor-inserter__quick-inserter .block-editor-inserter__panel-content{ background:#fff; } .customize-widgets-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .customize-widgets-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .customize-widgets-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .customize-widgets-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 1rem 0 0; text-align:left; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 .2rem 0 0; } .components-popover.more-menu-dropdown__content{ z-index:99998; } .customize-control-sidebar_block_editor .block-editor-block-list__block-popover{ position:fixed !important; z-index:7; } .customize-control-sidebar_block_editor .components-popover,.customize-widgets-popover .components-popover{ position:fixed !important; } .customize-widgets-welcome-guide__image__wrapper{ background:#00a0d2; margin-bottom:8px; text-align:center; } .customize-widgets-welcome-guide__image{ height:auto; } .wrap .customize-widgets-welcome-guide__heading{ font-size:18px; font-weight:600; } .customize-widgets-welcome-guide__text{ line-height:1.7; } .customize-widgets-welcome-guide__button{ justify-content:center; margin:1em 0; width:100%; } .customize-widgets-welcome-guide__separator{ margin:1em 0; } .customize-widgets-welcome-guide__more-info{ line-height:1.4; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section{ background-color:#fff; min-height:100%; padding-top:12px !important; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section.open{ overflow:unset; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section .customize-section-title{ margin-top:-12px !important; position:static !important; width:unset !important; } .components-modal__screen-overlay{ z-index:999999; } .customize-control-sidebar_block_editor,.customize-widgets-layout__inspector{ box-sizing:border-box; } .customize-control-sidebar_block_editor *,.customize-control-sidebar_block_editor :after,.customize-control-sidebar_block_editor :before,.customize-widgets-layout__inspector *,.customize-widgets-layout__inspector :after,.customize-widgets-layout__inspector :before{ box-sizing:inherit; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector{ background:#fff; box-sizing:border-box; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector *{ box-sizing:inherit; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector{ margin:-12px; } #customize-theme-controls .customize-pane-child.accordion-section-content.customize-widgets-layout__inspector .block-editor-block-inspector h3{ margin-bottom:0; } #customize-theme-controls .customize-pane-child.control-section-sidebar.is-sub-section-open{ transform:translateX(-100%); } .customize-widgets-header{ background:#f0f0f1; border-bottom:1px solid #e0e0e0; display:flex; justify-content:flex-end; margin:-15px -12px 0; z-index:8; } @media (min-width:600px){ .customize-widgets-header{ margin-bottom:44px; } } .customize-widgets-header.is-fixed-toolbar-active{ margin-bottom:0; } .customize-widgets-header-toolbar{ align-items:center; border:none; display:flex; width:100%; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon{ border-radius:2px; color:#fff; height:32px; margin:12px 0 12px auto; min-width:32px; padding:0; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon:before{ content:none; } @media not (prefers-reduced-motion){ .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed{ background:#1e1e1e; } .customize-widgets-header-toolbar .customize-widgets-header-toolbar__inserter-toggle.components-button.has-icon.is-pressed svg{ transform:rotate(45deg); } .customize-widgets-header-toolbar .components-button.has-icon.customize-widgets-editor-history-button.redo-button{ margin-left:-12px; } #customize-sidebar-outer-content{ min-width:100%; width:auto; } #customize-outer-theme-controls .widgets-inserter{ padding:0; } #customize-outer-theme-controls .widgets-inserter .customize-section-description-container{ display:none; } .customize-widgets-layout__inserter-panel{ background:#fff; } .customize-widgets-layout__inserter-panel-header{ align-items:center; border-bottom:1px solid #ddd; box-sizing:border-box; display:flex; height:46px; justify-content:space-between; padding:16px; } .customize-widgets-layout__inserter-panel-header .customize-widgets-layout__inserter-panel-header-title{ margin:0; } .block-editor-inserter__quick-inserter .block-editor-inserter__panel-content{ background:#fff; } .customize-widgets-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .customize-widgets-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .customize-widgets-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .customize-widgets-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 0 0 1rem; text-align:right; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination+.customize-widgets-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .customize-widgets-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 0 0 .2rem; } .components-popover.more-menu-dropdown__content{ z-index:99998; } .customize-control-sidebar_block_editor .block-editor-block-list__block-popover{ position:fixed !important; z-index:7; } .customize-control-sidebar_block_editor .components-popover,.customize-widgets-popover .components-popover{ position:fixed !important; } .customize-widgets-welcome-guide__image__wrapper{ background:#00a0d2; margin-bottom:8px; text-align:center; } .customize-widgets-welcome-guide__image{ height:auto; } .wrap .customize-widgets-welcome-guide__heading{ font-size:18px; font-weight:600; } .customize-widgets-welcome-guide__text{ line-height:1.7; } .customize-widgets-welcome-guide__button{ justify-content:center; margin:1em 0; width:100%; } .customize-widgets-welcome-guide__separator{ margin:1em 0; } .customize-widgets-welcome-guide__more-info{ line-height:1.4; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section{ background-color:#fff; min-height:100%; padding-top:12px !important; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section.open{ overflow:unset; } #customize-theme-controls .customize-pane-child.customize-widgets__sidebar-section .customize-section-title{ margin-top:-12px !important; position:static !important; width:unset !important; } .components-modal__screen-overlay{ z-index:999999; } .customize-control-sidebar_block_editor,.customize-widgets-layout__inspector{ box-sizing:border-box; } .customize-control-sidebar_block_editor *,.customize-control-sidebar_block_editor :after,.customize-control-sidebar_block_editor :before,.customize-widgets-layout__inspector *,.customize-widgets-layout__inspector :after,.customize-widgets-layout__inspector :before{ box-sizing:inherit; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-directory-block-ratings>span{display:flex}.block-directory-block-ratings svg{fill:#1e1e1e;margin-right:-4px}.block-directory-block-ratings .block-directory-block-ratings__star-empty{fill:#ccc}.block-directory-compact-list{list-style:none;margin:0}.block-directory-compact-list__item{align-items:center;display:flex;flex-direction:row;margin-bottom:16px}.block-directory-compact-list__item:last-child{margin-bottom:0}.block-directory-compact-list__item-details{margin-right:8px}.block-directory-compact-list__item-title{font-weight:500}.block-directory-compact-list__item-author{color:#757575;font-size:11px}.block-directory-downloadable-block-icon{border:1px solid #ddd;height:54px;min-width:54px;vertical-align:middle;width:54px}.block-directory-downloadable-block-list-item{appearance:none;background:none;border:0;display:grid;grid-template-columns:auto 1fr;height:auto;margin:0;padding:12px;position:relative;text-align:right;width:100%}.block-directory-downloadable-block-list-item+.block-directory-downloadable-block-list-item{margin-top:4px}@media not (prefers-reduced-motion){.block-directory-downloadable-block-list-item{transition:box-shadow .1s linear}}.block-directory-downloadable-block-list-item:not([aria-disabled=true]){cursor:pointer}.block-directory-downloadable-block-list-item:hover,.block-directory-downloadable-block-list-item[data-focus-visible]{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-directory-downloadable-block-list-item.is-installing .block-directory-downloadable-block-list-item__author{display:none}.block-directory-downloadable-block-list-item__icon{align-self:flex-start;margin-left:16px;position:relative}.block-directory-downloadable-block-list-item__icon .block-directory-downloadable-block-list-item__spinner{align-items:center;background:#ffffffbf;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.is-installing .block-directory-downloadable-block-list-item__icon{margin-left:22px}.block-directory-block-ratings{display:block;margin-top:4px}.block-directory-downloadable-block-list-item__details{color:#1e1e1e}.block-directory-downloadable-block-list-item__title{display:block;font-weight:600}.block-directory-downloadable-block-list-item__author{display:block;font-weight:400;margin-top:4px}.block-directory-downloadable-block-list-item__desc{display:block;margin-top:8px}.block-directory-downloadable-block-notice{color:#cc1818;margin:8px 0 0}.block-directory-downloadable-block-notice__content{margin-bottom:8px;padding-left:12px}.block-directory-downloadable-blocks-panel{padding:16px}.block-directory-downloadable-blocks-panel.has-blocks-loading{color:#757575;font-style:normal;margin:112px 0;padding:0;text-align:center}.block-directory-downloadable-blocks-panel.has-blocks-loading .components-spinner{float:inherit}.block-directory-downloadable-blocks-panel__no-local{color:#757575;margin:48px 0;padding:0 64px;text-align:center}.block-directory-downloadable-blocks-panel__title{font-size:14px;margin:0 0 4px}.block-directory-downloadable-blocks-panel__description,.installed-blocks-pre-publish-panel__copy{margin-top:0}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-directory-block-ratings>span{display:flex}.block-directory-block-ratings svg{fill:#1e1e1e;margin-left:-4px}.block-directory-block-ratings .block-directory-block-ratings__star-empty{fill:#ccc}.block-directory-compact-list{list-style:none;margin:0}.block-directory-compact-list__item{align-items:center;display:flex;flex-direction:row;margin-bottom:16px}.block-directory-compact-list__item:last-child{margin-bottom:0}.block-directory-compact-list__item-details{margin-left:8px}.block-directory-compact-list__item-title{font-weight:500}.block-directory-compact-list__item-author{color:#757575;font-size:11px}.block-directory-downloadable-block-icon{border:1px solid #ddd;height:54px;min-width:54px;vertical-align:middle;width:54px}.block-directory-downloadable-block-list-item{appearance:none;background:none;border:0;display:grid;grid-template-columns:auto 1fr;height:auto;margin:0;padding:12px;position:relative;text-align:left;width:100%}.block-directory-downloadable-block-list-item+.block-directory-downloadable-block-list-item{margin-top:4px}@media not (prefers-reduced-motion){.block-directory-downloadable-block-list-item{transition:box-shadow .1s linear}}.block-directory-downloadable-block-list-item:not([aria-disabled=true]){cursor:pointer}.block-directory-downloadable-block-list-item:hover,.block-directory-downloadable-block-list-item[data-focus-visible]{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-directory-downloadable-block-list-item.is-installing .block-directory-downloadable-block-list-item__author{display:none}.block-directory-downloadable-block-list-item__icon{align-self:flex-start;margin-right:16px;position:relative}.block-directory-downloadable-block-list-item__icon .block-directory-downloadable-block-list-item__spinner{align-items:center;background:#ffffffbf;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0}.is-installing .block-directory-downloadable-block-list-item__icon{margin-right:22px}.block-directory-block-ratings{display:block;margin-top:4px}.block-directory-downloadable-block-list-item__details{color:#1e1e1e}.block-directory-downloadable-block-list-item__title{display:block;font-weight:600}.block-directory-downloadable-block-list-item__author{display:block;font-weight:400;margin-top:4px}.block-directory-downloadable-block-list-item__desc{display:block;margin-top:8px}.block-directory-downloadable-block-notice{color:#cc1818;margin:8px 0 0}.block-directory-downloadable-block-notice__content{margin-bottom:8px;padding-right:12px}.block-directory-downloadable-blocks-panel{padding:16px}.block-directory-downloadable-blocks-panel.has-blocks-loading{color:#757575;font-style:normal;margin:112px 0;padding:0;text-align:center}.block-directory-downloadable-blocks-panel.has-blocks-loading .components-spinner{float:inherit}.block-directory-downloadable-blocks-panel__no-local{color:#757575;margin:48px 0;padding:0 64px;text-align:center}.block-directory-downloadable-blocks-panel__title{font-size:14px;margin:0 0 4px}.block-directory-downloadable-blocks-panel__description,.installed-blocks-pre-publish-panel__copy{margin-top:0}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-directory-block-ratings>span{ display:flex; } .block-directory-block-ratings svg{ fill:#1e1e1e; margin-right:-4px; } .block-directory-block-ratings .block-directory-block-ratings__star-empty{ fill:#ccc; } .block-directory-compact-list{ list-style:none; margin:0; } .block-directory-compact-list__item{ align-items:center; display:flex; flex-direction:row; margin-bottom:16px; } .block-directory-compact-list__item:last-child{ margin-bottom:0; } .block-directory-compact-list__item-details{ margin-right:8px; } .block-directory-compact-list__item-title{ font-weight:500; } .block-directory-compact-list__item-author{ color:#757575; font-size:11px; } .block-directory-downloadable-block-icon{ border:1px solid #ddd; height:54px; min-width:54px; vertical-align:middle; width:54px; } .block-directory-downloadable-block-list-item{ appearance:none; background:none; border:0; display:grid; grid-template-columns:auto 1fr; height:auto; margin:0; padding:12px; position:relative; text-align:right; width:100%; } .block-directory-downloadable-block-list-item+.block-directory-downloadable-block-list-item{ margin-top:4px; } @media not (prefers-reduced-motion){ .block-directory-downloadable-block-list-item{ transition:box-shadow .1s linear; } } .block-directory-downloadable-block-list-item:not([aria-disabled=true]){ cursor:pointer; } .block-directory-downloadable-block-list-item:hover,.block-directory-downloadable-block-list-item[data-focus-visible]{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-directory-downloadable-block-list-item.is-installing .block-directory-downloadable-block-list-item__author{ display:none; } .block-directory-downloadable-block-list-item__icon{ align-self:flex-start; margin-left:16px; position:relative; } .block-directory-downloadable-block-list-item__icon .block-directory-downloadable-block-list-item__spinner{ align-items:center; background:#ffffffbf; bottom:0; display:flex; justify-content:center; left:0; position:absolute; right:0; top:0; } .is-installing .block-directory-downloadable-block-list-item__icon{ margin-left:22px; } .block-directory-block-ratings{ display:block; margin-top:4px; } .block-directory-downloadable-block-list-item__details{ color:#1e1e1e; } .block-directory-downloadable-block-list-item__title{ display:block; font-weight:600; } .block-directory-downloadable-block-list-item__author{ display:block; font-weight:400; margin-top:4px; } .block-directory-downloadable-block-list-item__desc{ display:block; margin-top:8px; } .block-directory-downloadable-block-notice{ color:#cc1818; margin:8px 0 0; } .block-directory-downloadable-block-notice__content{ margin-bottom:8px; padding-left:12px; } .block-directory-downloadable-blocks-panel{ padding:16px; } .block-directory-downloadable-blocks-panel.has-blocks-loading{ color:#757575; font-style:normal; margin:112px 0; padding:0; text-align:center; } .block-directory-downloadable-blocks-panel.has-blocks-loading .components-spinner{ float:inherit; } .block-directory-downloadable-blocks-panel__no-local{ color:#757575; margin:48px 0; padding:0 64px; text-align:center; } .block-directory-downloadable-blocks-panel__title{ font-size:14px; margin:0 0 4px; } .block-directory-downloadable-blocks-panel__description,.installed-blocks-pre-publish-panel__copy{ margin-top:0; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-directory-block-ratings>span{ display:flex; } .block-directory-block-ratings svg{ fill:#1e1e1e; margin-left:-4px; } .block-directory-block-ratings .block-directory-block-ratings__star-empty{ fill:#ccc; } .block-directory-compact-list{ list-style:none; margin:0; } .block-directory-compact-list__item{ align-items:center; display:flex; flex-direction:row; margin-bottom:16px; } .block-directory-compact-list__item:last-child{ margin-bottom:0; } .block-directory-compact-list__item-details{ margin-left:8px; } .block-directory-compact-list__item-title{ font-weight:500; } .block-directory-compact-list__item-author{ color:#757575; font-size:11px; } .block-directory-downloadable-block-icon{ border:1px solid #ddd; height:54px; min-width:54px; vertical-align:middle; width:54px; } .block-directory-downloadable-block-list-item{ appearance:none; background:none; border:0; display:grid; grid-template-columns:auto 1fr; height:auto; margin:0; padding:12px; position:relative; text-align:left; width:100%; } .block-directory-downloadable-block-list-item+.block-directory-downloadable-block-list-item{ margin-top:4px; } @media not (prefers-reduced-motion){ .block-directory-downloadable-block-list-item{ transition:box-shadow .1s linear; } } .block-directory-downloadable-block-list-item:not([aria-disabled=true]){ cursor:pointer; } .block-directory-downloadable-block-list-item:hover,.block-directory-downloadable-block-list-item[data-focus-visible]{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-directory-downloadable-block-list-item.is-installing .block-directory-downloadable-block-list-item__author{ display:none; } .block-directory-downloadable-block-list-item__icon{ align-self:flex-start; margin-right:16px; position:relative; } .block-directory-downloadable-block-list-item__icon .block-directory-downloadable-block-list-item__spinner{ align-items:center; background:#ffffffbf; bottom:0; display:flex; justify-content:center; left:0; position:absolute; right:0; top:0; } .is-installing .block-directory-downloadable-block-list-item__icon{ margin-right:22px; } .block-directory-block-ratings{ display:block; margin-top:4px; } .block-directory-downloadable-block-list-item__details{ color:#1e1e1e; } .block-directory-downloadable-block-list-item__title{ display:block; font-weight:600; } .block-directory-downloadable-block-list-item__author{ display:block; font-weight:400; margin-top:4px; } .block-directory-downloadable-block-list-item__desc{ display:block; margin-top:8px; } .block-directory-downloadable-block-notice{ color:#cc1818; margin:8px 0 0; } .block-directory-downloadable-block-notice__content{ margin-bottom:8px; padding-right:12px; } .block-directory-downloadable-blocks-panel{ padding:16px; } .block-directory-downloadable-blocks-panel.has-blocks-loading{ color:#757575; font-style:normal; margin:112px 0; padding:0; text-align:center; } .block-directory-downloadable-blocks-panel.has-blocks-loading .components-spinner{ float:inherit; } .block-directory-downloadable-blocks-panel__no-local{ color:#757575; margin:48px 0; padding:0 64px; text-align:center; } .block-directory-downloadable-blocks-panel__title{ font-size:14px; margin:0 0 4px; } .block-directory-downloadable-blocks-panel__description,.installed-blocks-pre-publish-panel__copy{ margin-top:0; }@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.interface-complementary-area-header{background:#fff;gap:4px;padding-left:8px}.interface-complementary-area-header .interface-complementary-area-header__title{margin:0 0 0 auto}.interface-complementary-area{background:#fff;color:#1e1e1e;height:100%;overflow:auto}@media (min-width:600px){.interface-complementary-area{-webkit-overflow-scrolling:touch}}@media (min-width:782px){.interface-complementary-area{width:280px}}.interface-complementary-area .components-panel{border:none;position:relative;z-index:0}.interface-complementary-area .components-panel__header{position:sticky;top:0;z-index:1}.interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{top:0}.interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){margin-top:0}.interface-complementary-area h2{color:#1e1e1e;font-size:13px;font-weight:500;margin-bottom:1.5em}.interface-complementary-area h3{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.interface-complementary-area hr{border-bottom:1px solid #f0f0f0;border-top:none;margin:1.5em 0}.interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{box-shadow:none;margin-bottom:1.5em}.interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{margin-bottom:0}.interface-complementary-area .block-editor-skip-to-selected-block:focus{bottom:10px;left:10px;right:auto;top:auto}.interface-complementary-area__fill{height:100%}@media (min-width:782px){body.js.is-fullscreen-mode{height:calc(100% + 32px);margin-top:-32px}body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{display:none}body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{margin-right:0}}html.interface-interface-skeleton__html-container{position:fixed;width:100%}@media (min-width:782px){html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){position:static;width:auto}}.interface-interface-skeleton{bottom:0;display:flex;flex-direction:row;height:auto;left:0;max-height:100%;position:fixed;top:46px}@media (min-width:783px){.interface-interface-skeleton{top:32px}.is-fullscreen-mode .interface-interface-skeleton{top:0}}.interface-interface-skeleton__editor{display:flex;flex:0 1 100%;flex-direction:column;overflow:hidden}.interface-interface-skeleton{right:0}@media (min-width:783px){.interface-interface-skeleton{right:160px}}@media (min-width:783px){.auto-fold .interface-interface-skeleton{right:36px}}@media (min-width:961px){.auto-fold .interface-interface-skeleton{right:160px}}.folded .interface-interface-skeleton{right:0}@media (min-width:783px){.folded .interface-interface-skeleton{right:36px}}body.is-fullscreen-mode .interface-interface-skeleton{right:0!important}.interface-interface-skeleton__body{display:flex;flex-grow:1;overflow:auto;overscroll-behavior-y:none;position:relative}@media (min-width:782px){.has-footer .interface-interface-skeleton__body{padding-bottom:25px}}.interface-interface-skeleton__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;z-index:20}@media (min-width:782px){.interface-interface-skeleton__content{z-index:auto}}.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{background:#fff;bottom:0;color:#1e1e1e;flex-shrink:0;position:absolute;right:0;top:0;width:auto;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{position:relative!important}}.interface-interface-skeleton__sidebar{border-top:1px solid #e0e0e0;overflow:hidden}@media (min-width:782px){.interface-interface-skeleton__sidebar{box-shadow:1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__secondary-sidebar{border-top:1px solid #e0e0e0;left:0}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar{box-shadow:-1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);color:#1e1e1e;flex-shrink:0;height:auto;outline:1px solid #0000;z-index:30}.interface-interface-skeleton__footer{background-color:#fff;border-top:1px solid #e0e0e0;bottom:0;color:#1e1e1e;display:none;flex-shrink:0;height:auto;position:absolute;right:0;width:100%;z-index:90}@media (min-width:782px){.interface-interface-skeleton__footer{display:flex}}.interface-interface-skeleton__footer .block-editor-block-breadcrumb{align-items:center;background:#fff;display:flex;font-size:13px;height:24px;padding:0 18px;z-index:30}.interface-interface-skeleton__actions{background:#fff;bottom:auto;color:#1e1e1e;left:0;position:fixed!important;right:auto;top:-9999em;width:100vw;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__actions{width:280px}}.interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{bottom:0;top:auto}.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:46px}@media (min-width:782px){.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{border-right:1px solid #ddd;top:32px}.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:0}}.interface-pinned-items{display:flex;gap:8px}.interface-pinned-items .components-button{display:none;margin:0}.interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{display:flex}.interface-pinned-items .components-button svg{max-height:24px;max-width:24px}@media (min-width:600px){.interface-pinned-items .components-button{display:flex}}.editor-autocompleters__user .editor-autocompleters__no-avatar:before{content:"\f110";font:normal 20px/1 dashicons;margin-left:5px;vertical-align:middle}.editor-autocompleters__user .editor-autocompleters__user-avatar{flex-grow:0;flex-shrink:0;height:24px;margin-left:8px;max-width:none;width:24px}.editor-autocompleters__user .editor-autocompleters__user-name{flex-grow:1;flex-shrink:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.editor-autocompleters__user .editor-autocompleters__user-slug{color:#757575;flex-grow:0;flex-shrink:0;margin-right:8px;max-width:100px;overflow:none;text-overflow:ellipsis;white-space:nowrap}.editor-autocompleters__user:hover .editor-autocompleters__user-slug{color:var(--wp-admin-theme-color)}.interface-interface-skeleton__sidebar:has(.editor-collab-sidebar){box-shadow:none}.interface-interface-skeleton__sidebar:has(.editor-collab-sidebar) .interface-complementary-area-header{display:none}.editor-collab-sidebar{height:100%}.editor-collab-sidebar-panel{height:100%;padding:16px}.editor-collab-sidebar-panel__thread{background-color:#f0f0f0;border:1.5px solid #ddd;border-radius:8px;margin-bottom:16px;padding:16px;position:relative}.editor-collab-sidebar-panel__active-thread{border:1.5px solid #3858e9}.editor-collab-sidebar-panel__focus-thread{background-color:#fff;border:1.5px solid #3858e9;box-shadow:0 5.5px 7.8px -.3px rgba(0,0,0,.102)}.editor-collab-sidebar-panel__comment-field{flex:1}.editor-collab-sidebar-panel__child-thread{margin-top:15px}.editor-collab-sidebar-panel__user-name{text-transform:capitalize}.editor-collab-sidebar-panel__user-name,.editor-collab-sidebar-panel__user-time{color:#757575;font-size:12px;font-weight:400;line-height:16px;text-align:right}.editor-collab-sidebar-panel__user-comment{color:#1e1e1e;font-size:13px;font-weight:400;line-height:20px;text-align:right}.editor-collab-sidebar-panel__user-comment p{margin-bottom:0}.editor-collab-sidebar-panel__user-avatar{border-radius:50%;flex-shrink:0}.editor-collab-sidebar-panel__thread-overlay{background-color:#000000b3;border-radius:8px;color:#fff;height:100%;padding:15px;position:absolute;right:0;text-align:center;top:0;width:100%;z-index:1}.editor-collab-sidebar-panel__thread-overlay p{margin-bottom:15px}.editor-collab-sidebar-panel__thread-overlay button{color:#fff;padding:4px 10px}.editor-collab-sidebar-panel__comment-status{margin-right:auto}.editor-collab-sidebar-panel__comment-status button.has-icon:not(.has-text){flex-shrink:0;height:24px;min-width:24px;padding:0;width:24px}.editor-collab-sidebar-panel__comment-dropdown-menu{flex-shrink:0}.editor-collab-sidebar-panel__comment-dropdown-menu button.has-icon{height:24px;min-width:24px;padding:0;width:24px}.editor-collab-sidebar-panel__show-more-reply{font-style:italic;font-weight:500;padding:0}.editor-collapsible-block-toolbar{align-items:center;display:flex;height:60px;overflow:hidden}.editor-collapsible-block-toolbar .block-editor-block-contextual-toolbar{background:#0000;border-bottom:0;height:100%}.editor-collapsible-block-toolbar .block-editor-block-toolbar{height:100%;padding-top:15px}.editor-collapsible-block-toolbar .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){height:32px}.editor-collapsible-block-toolbar:after{background-color:#ddd;content:"";height:24px;margin-left:7px;width:1px}.editor-collapsible-block-toolbar .components-toolbar,.editor-collapsible-block-toolbar .components-toolbar-group{border-left:none;position:relative}.editor-collapsible-block-toolbar .components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar:after{background-color:#ddd;content:"";height:24px;left:-1px;position:absolute;top:4px;width:1px}.editor-collapsible-block-toolbar .components-toolbar .components-toolbar-group.components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{display:none}.editor-collapsible-block-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{height:32px;overflow:visible}@media (min-width:600px){.editor-collapsible-block-toolbar .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{height:40px;position:relative;top:-5px}}.editor-collapsible-block-toolbar.is-collapsed{display:none}.editor-content-only-settings-menu__description{min-width:235px;padding:8px}.editor-blog-title-dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-document-bar{align-items:center;background:#f0f0f0;border-radius:4px;display:flex;height:32px;justify-content:space-between;min-width:0;width:min(100%,450px)}.editor-document-bar:hover{background-color:#e0e0e0}.editor-document-bar .components-button{border-radius:4px}@media not (prefers-reduced-motion){.editor-document-bar .components-button{transition:all .1s ease-out}}.editor-document-bar .components-button:hover{background:#e0e0e0}@media screen and (min-width:782px) and (max-width:960px){.editor-document-bar.has-back-button .editor-document-bar__post-type-label{display:none}}.editor-document-bar__command{color:var(--wp-block-synced-color);flex-grow:1;overflow:hidden}.editor-document-bar__title{color:#1e1e1e;margin:0 auto;max-width:70%;overflow:hidden}@media (min-width:782px){.editor-document-bar__title{padding-right:24px}}.editor-document-bar__title h1{align-items:center;display:flex;font-weight:400;justify-content:center;overflow:hidden;white-space:nowrap}.editor-document-bar__post-title{color:currentColor;flex:1;overflow:hidden;text-overflow:ellipsis}.editor-document-bar__post-type-label{color:#2f2f2f;flex:0;padding-right:4px}@media screen and (max-width:600px){.editor-document-bar__post-type-label{display:none}}.editor-document-bar__shortcut{color:#2f2f2f;display:none;min-width:24px}@media (min-width:782px){.editor-document-bar__shortcut{display:initial}}.editor-document-bar__back.components-button.has-icon.has-text{color:#757575;flex-shrink:0;gap:0;min-width:36px;position:absolute;z-index:1}.editor-document-bar__back.components-button.has-icon.has-text:hover{background-color:initial;color:#1e1e1e}.editor-document-bar__icon-layout.editor-document-bar__icon-layout{display:none;margin-right:12px;pointer-events:none;position:absolute}.editor-document-bar__icon-layout.editor-document-bar__icon-layout svg{fill:#949494}@media (min-width:600px){.editor-document-bar__icon-layout.editor-document-bar__icon-layout{display:flex}}.document-outline{margin:20px 0}.document-outline ul{margin:0;padding:0}.document-outline__item{display:flex;margin:4px 0}.document-outline__item a{text-decoration:none}.document-outline__item .document-outline__emdash:before{color:#ddd;margin-left:4px}.document-outline__item.is-h2 .document-outline__emdash:before{content:"—"}.document-outline__item.is-h3 .document-outline__emdash:before{content:"——"}.document-outline__item.is-h4 .document-outline__emdash:before{content:"———"}.document-outline__item.is-h5 .document-outline__emdash:before{content:"————"}.document-outline__item.is-h6 .document-outline__emdash:before{content:"—————"}.document-outline__button{align-items:flex-start;background:none;border:none;border-radius:2px;color:#1e1e1e;cursor:pointer;display:flex;margin:0 -1px 0 0;padding:2px 1px 2px 5px;text-align:right}.document-outline__button:disabled,.document-outline__button[aria-disabled=true]{color:#757575;cursor:default}.document-outline__button:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.document-outline__level{background:#ddd;border-radius:3px;color:#1e1e1e;font-size:13px;margin-left:4px;padding:1px 6px}.is-invalid .document-outline__level{background:#f0b849}.document-outline__item-content{padding:1px 0}.editor-document-outline.has-no-headings{color:#757575;text-align:center}.editor-document-outline.has-no-headings>svg{margin-top:28px}.editor-document-outline.has-no-headings>p{padding-left:32px;padding-right:32px}.editor-document-tools{align-items:center;display:inline-flex}.editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{display:none}@media (min-width:782px){.editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{display:inline-flex}}.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle{display:inline-flex}@media not (prefers-reduced-motion){.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.is-pressed svg{transform:rotate(-45deg)}.editor-document-tools .block-editor-list-view{display:none}@media (min-width:600px){.editor-document-tools .block-editor-list-view{display:flex}}.editor-document-tools .editor-document-tools__left>.components-button.has-icon,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon{height:32px;min-width:32px;padding:4px}.editor-document-tools .editor-document-tools__left>.components-button.has-icon.is-pressed,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon.is-pressed{background:#1e1e1e}.editor-document-tools .editor-document-tools__left>.components-button.has-icon:focus:not(:disabled),.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 1px #fff;outline:1px solid #0000}.editor-document-tools .editor-document-tools__left>.components-button.has-icon:before,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:before{display:none}.editor-document-tools__left{align-items:center;display:inline-flex;gap:8px}.editor-document-tools__left:not(:last-child){margin-inline-end:8px}.show-icon-labels .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.has-icon{padding:0 8px;width:auto}.show-icon-labels .editor-document-tools__left>*+*{margin-right:8px}.editor-editor-interface .entities-saved-states__panel-header{height:61px}.editor-editor-interface .interface-interface-skeleton__content{isolation:isolate}.editor-visual-editor{flex:1 0 auto}.components-editor-notices__dismissible,.components-editor-notices__pinned{color:#1e1e1e;left:0;position:relative;right:0;top:0}.components-editor-notices__dismissible .components-notice,.components-editor-notices__pinned .components-notice{border-bottom:1px solid #0003;box-sizing:border-box;min-height:60px;padding:0 12px}.components-editor-notices__dismissible .components-notice .components-notice__dismiss,.components-editor-notices__pinned .components-notice .components-notice__dismiss{margin-top:12px}.entities-saved-states__panel-header{background:#fff;border-bottom:1px solid #ddd;box-sizing:border-box;height:60px;padding-left:16px;padding-right:16px}.entities-saved-states__text-prompt{padding:16px 16px 4px}.entities-saved-states__text-prompt .entities-saved-states__text-prompt--header{display:block;margin-bottom:12px}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt{padding:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body{border:0;padding-left:0;padding-right:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2{margin-bottom:0;margin-left:-16px;margin-right:-16px}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2 button{font-size:11px;text-transform:uppercase}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--header-wrapper{display:none}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--changes-count{margin-bottom:8px;margin-top:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-footer{margin-top:16px}.entities-saved-states__change-control{flex:1}.entities-saved-states__changes{font-size:13px;list-style:disc;margin:4px 24px 0 16px}.entities-saved-states__changes li{margin-bottom:4px}.editor-error-boundary{background-color:#fff;border:1px solid #1e1e1e;border-radius:2px;box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;margin:60px auto auto;max-width:780px;padding:1em}.editor-header{align-items:center;background:#fff;display:grid;grid-auto-flow:row;grid-template:auto/60px minmax(0,max-content) minmax(min-content,1fr) 60px;height:60px;justify-content:space-between;max-width:100vw}.editor-header:has(>.editor-header__center){grid-template:auto/60px min-content 1fr min-content 60px}@media (min-width:782px){.editor-header:has(>.editor-header__center){grid-template:auto/60px minmax(min-content,2fr) 2.5fr minmax(min-content,2fr) 60px}}@media (min-width:480px){.editor-header{gap:16px}}@media (min-width:280px){.editor-header{flex-wrap:nowrap}}.editor-header__toolbar{align-items:center;clip-path:inset(-2px);display:flex;grid-column:1/3;min-width:0}.editor-header__toolbar>:first-child{margin-inline:16px 0}.editor-header__back-button+.editor-header__toolbar{grid-column:2/3}@media (min-width:480px){.editor-header__back-button+.editor-header__toolbar>:first-child{margin-inline:0}.editor-header__toolbar{clip-path:none}}.editor-header__toolbar .table-of-contents{display:none}@media (min-width:600px){.editor-header__toolbar .table-of-contents{display:block}}.editor-header__toolbar .editor-collapsible-block-toolbar,.editor-header__toolbar .editor-collapsible-block-toolbar.is-collapsed~.editor-collapsible-block-toolbar__toggle{margin-inline:8px 0}.editor-header__center{align-items:center;clip-path:inset(-2px);display:flex;grid-column:3/4;justify-content:center;min-width:0}@media (max-width:479px){.editor-header__center>:first-child{margin-inline-start:8px}.editor-header__center>:last-child{margin-inline-end:8px}}.editor-header__settings{align-items:center;display:inline-flex;flex-wrap:nowrap;gap:8px;grid-column:3/-1;justify-self:end;padding-left:4px}.editor-header:has(>.editor-header__center) .editor-header__settings{grid-column:4/-1}@media (min-width:600px){.editor-header__settings{padding-left:8px}}.show-icon-labels .editor-header .components-button.has-icon,.show-icon-labels.interface-pinned-items .components-button.has-icon{width:auto}.show-icon-labels .editor-header .components-button.has-icon svg,.show-icon-labels.interface-pinned-items .components-button.has-icon svg{display:none}.show-icon-labels .editor-header .components-button.has-icon:after,.show-icon-labels.interface-pinned-items .components-button.has-icon:after{content:attr(aria-label);white-space:nowrap}.show-icon-labels .editor-header .components-button.has-icon[aria-disabled=true],.show-icon-labels.interface-pinned-items .components-button.has-icon[aria-disabled=true]{background-color:initial}.show-icon-labels .editor-header .is-tertiary:active,.show-icon-labels.interface-pinned-items .is-tertiary:active{background-color:initial;box-shadow:0 0 0 1.5px var(--wp-admin-theme-color)}.show-icon-labels .editor-header .components-button.has-icon.button-toggle svg,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle svg{display:block}.show-icon-labels .editor-header .components-button.has-icon.button-toggle:after,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle:after{content:none}.show-icon-labels .editor-header .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon,.show-icon-labels.interface-pinned-items .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon{display:block}.show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{padding-left:8px;padding-right:8px}@media (min-width:600px){.show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{padding-left:12px;padding-right:12px}}.show-icon-labels .editor-header .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels .editor-header .editor-post-saved-state.editor-post-saved-state:after,.show-icon-labels.interface-pinned-items .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels.interface-pinned-items .editor-post-saved-state.editor-post-saved-state:after{content:none}.show-icon-labels .editor-header__toolbar .block-editor-block-mover{border-right:none}.show-icon-labels .editor-header__toolbar .block-editor-block-mover:before{background-color:#ddd;content:"";height:24px;margin-right:8px;margin-top:4px;width:1px}.show-icon-labels .editor-header__toolbar .block-editor-block-mover .block-editor-block-mover__move-button-container:before{background:#ddd;right:calc(50% + 1px);width:calc(100% - 24px)}.show-icon-labels.interface-pinned-items{border-bottom:1px solid #ccc;display:block;margin:0 -12px;padding:6px 12px 12px}.show-icon-labels.interface-pinned-items>.components-button.has-icon{justify-content:flex-start;margin:0;padding:6px 8px 6px 6px;width:14.625rem}.show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=true] svg{display:block;max-width:24px}.show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=false]{padding-right:40px}.show-icon-labels.interface-pinned-items>.components-button.has-icon svg{margin-left:8px}@media (min-width:480px){.editor-header__post-preview-button{display:none}}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header{border-bottom:none}.editor-editor-interface.is-distraction-free .editor-header{background-color:#fff;width:100%}@media (min-width:782px){.editor-editor-interface.is-distraction-free .editor-header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);position:absolute}}.editor-editor-interface.is-distraction-free .editor-header>.edit-post-header__settings>.edit-post-header__post-preview-button{visibility:hidden}.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-preview-dropdown,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-zoom-out-toggle,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.interface-pinned-items,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__toolbar .editor-document-tools__document-overview-toggle{display:none}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within{opacity:1!important}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within div{transform:translateX(0) translateZ(0)!important}.editor-editor-interface.is-distraction-free .components-editor-notices__dismissible{position:absolute;z-index:35}.components-popover.more-menu-dropdown__content{z-index:99998}.editor-inserter-sidebar{box-sizing:border-box;display:flex;flex-direction:column;height:100%}.editor-inserter-sidebar *,.editor-inserter-sidebar :after,.editor-inserter-sidebar :before{box-sizing:inherit}.editor-inserter-sidebar__content{height:100%}.editor-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.editor-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.editor-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.editor-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.editor-keyboard-shortcut-help-modal__shortcut:empty{display:none}.editor-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 1rem 0 0;text-align:left}.editor-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.editor-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.editor-keyboard-shortcut-help-modal__shortcut-key-combination+.editor-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.editor-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.editor-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 .2rem 0 0}.editor-list-view-sidebar{height:100%}@media (min-width:782px){.editor-list-view-sidebar{width:350px}}.editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{height:100%;overflow:auto;padding:4px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:auto;scrollbar-width:thin;will-change:transform}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar{height:12px;width:12px}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-track,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-track{background-color:initial}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.editor-list-view-sidebar__list-view-container>.document-outline:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:hover::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:hover::-webkit-scrollbar-thumb{background-color:#949494}.editor-list-view-sidebar__list-view-container>.document-outline:focus,.editor-list-view-sidebar__list-view-container>.document-outline:focus-within,.editor-list-view-sidebar__list-view-container>.document-outline:hover,.editor-list-view-sidebar__list-view-panel-content:focus,.editor-list-view-sidebar__list-view-panel-content:focus-within,.editor-list-view-sidebar__list-view-panel-content:hover{scrollbar-color:#949494 #0000}@media (hover:none){.editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{scrollbar-color:#949494 #0000}}.editor-list-view-sidebar__list-view-container{display:flex;flex-direction:column;height:100%}.editor-list-view-sidebar__tab-panel{height:100%}.editor-list-view-sidebar__outline{border-bottom:1px solid #ddd;display:flex;flex-direction:column;gap:8px;padding:16px}.editor-list-view-sidebar__outline>div>span:first-child{display:inline-block;width:90px}.editor-list-view-sidebar__outline>div>span{color:#757575;font-size:12px;line-height:1.4}.editor-post-order__panel,.editor-post-parent__panel{padding-top:8px}.editor-post-order__panel .editor-post-panel__row-control>div,.editor-post-parent__panel .editor-post-panel__row-control>div{width:100%}.editor-post-order__panel-dialog .editor-post-order,.editor-post-order__panel-dialog .editor-post-parent,.editor-post-parent__panel-dialog .editor-post-order,.editor-post-parent__panel-dialog .editor-post-parent{margin:8px}.editor-post-order__panel-dialog .components-popover__content,.editor-post-parent__panel-dialog .components-popover__content{min-width:320px}.editor-post-author__panel{padding-top:8px}.editor-post-author__panel .editor-post-panel__row-control>div{width:100%}.editor-post-author__panel-dialog .editor-post-author{margin:8px;min-width:248px}.editor-action-modal{z-index:1000001}.editor-post-card-panel__content{flex-grow:1}.editor-post-card-panel__title{width:100%}.editor-post-card-panel__title.editor-post-card-panel__title{align-items:center;column-gap:8px;display:flex;flex-wrap:wrap;font-family:-apple-system,"system-ui",Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:500;line-height:20px;margin:0;row-gap:4px;word-break:break-word}.editor-post-card-panel__icon{flex:0 0 24px;height:24px;width:24px}.editor-post-card-panel__header{display:flex;justify-content:space-between}.editor-post-card-panel.has-description .editor-post-card-panel__header{margin-bottom:8px}.editor-post-card-panel .editor-post-card-panel__title-name{padding:2px 0}.editor-post-card-panel .editor-post-card-panel__description,.editor-post-content-information{color:#757575}.editor-post-content-information .components-text{color:inherit}.editor-post-discussion__panel-dialog .editor-post-discussion{margin:8px;min-width:248px}.editor-post-discussion__panel-toggle .components-text{color:inherit}.editor-post-discussion__panel-dialog .components-popover__content{min-width:320px}.editor-post-excerpt__textarea{margin-bottom:10px;width:100%}.editor-post-excerpt__dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-post-featured-image{padding:0}.editor-post-featured-image .components-spinner{margin-right:-9px;margin-top:-9px;position:absolute;right:50%;top:50%}.editor-post-featured-image__container{position:relative}.editor-post-featured-image__container:focus .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:focus-within .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:hover .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image){opacity:1}.editor-post-featured-image__container .editor-post-featured-image__actions.editor-post-featured-image__actions-missing-image{margin-top:16px;opacity:1}.editor-post-featured-image__container .components-drop-zone__content{border-radius:2px}.editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner{align-items:center;display:flex;gap:8px}.editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner .components-drop-zone__content-icon{margin:0}.editor-post-featured-image__preview,.editor-post-featured-image__toggle{box-shadow:0 0 0 0 var(--wp-admin-theme-color);display:flex;justify-content:center;min-height:40px;outline-offset:-1px;overflow:hidden;padding:0;width:100%}.editor-post-featured-image__preview{height:auto!important;outline:1px solid #0000001a}.editor-post-featured-image__preview .editor-post-featured-image__preview-image{aspect-ratio:2/1;object-fit:cover;object-position:50% 50%;width:100%}.editor-post-featured-image__toggle{box-shadow:inset 0 0 0 1px #ccc}.editor-post-featured-image__toggle:focus:not(:disabled){box-shadow:0 0 0 currentColor inset,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){bottom:0;opacity:0;padding:8px;position:absolute}@media not (prefers-reduced-motion){.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){transition:opacity 50ms ease-out}}.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image) .editor-post-featured-image__action{-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background:#ffffffbf}.editor-post-featured-image__actions .editor-post-featured-image__action{flex-grow:1;justify-content:center}[class].editor-post-format__suggestion{margin:4px 0 0}.editor-post-format__dialog .editor-post-format__dialog-content{margin:8px;min-width:248px}.editor-post-last-edited-panel{color:#757575}.editor-post-last-edited-panel .components-text{color:inherit}.editor-post-last-revision__title{font-weight:500;width:100%}.editor-post-last-revision__title.components-button.has-icon{height:100%;justify-content:space-between}.editor-post-last-revision__title.components-button.has-icon:active,.editor-post-last-revision__title.components-button.has-icon:hover{background:#f0f0f0}.editor-post-last-revision__title.components-button.has-icon:focus{border-radius:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-panel__body.is-opened.editor-post-last-revision__panel{height:48px;padding:0}.components-panel__body.is-opened.editor-post-last-revision__panel .editor-post-last-revision__title.components-button.components-button{padding:16px}.editor-private-post-last-revision__button{display:inline-block}.editor-post-locked-modal__buttons{margin-top:24px}.editor-post-locked-modal__avatar{border-radius:50%;margin-top:16px;min-width:auto!important}.editor-post-panel__row{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.editor-post-panel__row-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.editor-post-panel__row-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.editor-post-panel__row-control .components-button{height:auto;max-width:100%;min-height:32px;text-align:right;text-wrap:balance;text-wrap:pretty;white-space:normal}.editor-post-panel__row-control .components-dropdown{max-width:100%}.editor-post-panel__section{padding:16px}.editor-post-publish-panel__content{min-height:calc(100% - 144px)}.editor-post-publish-panel__content>.components-spinner{display:block;margin:100px auto 0}.editor-post-publish-panel__header{align-content:space-between;align-items:center;background:#fff;border-bottom:1px solid #ddd;display:flex;height:61px;padding-left:16px;padding-right:16px}.editor-post-publish-panel__header .components-button{justify-content:center;width:100%}.editor-post-publish-panel__header .has-icon{margin-right:auto;width:auto}.components-site-card{align-items:center;display:flex;margin:16px 0}.components-site-icon{border:none;border-radius:2px;flex-shrink:0;height:36px;margin-left:12px;width:36px}.components-site-name{display:block;font-size:14px}.components-site-home{color:#757575;display:block;font-size:12px;word-break:break-word}.editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{flex:1}@media (min-width:480px){.editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{max-width:160px}}.editor-post-publish-panel__header-publish-button{justify-content:center;padding-right:4px}.editor-post-publish-panel__header-cancel-button{padding-left:4px}.editor-post-publish-panel__header-published{flex-grow:1}.editor-post-publish-panel__footer{padding:16px}.components-button.editor-post-publish-panel__toggle.is-primary{align-items:center;display:inline-flex}.components-button.editor-post-publish-panel__toggle.is-primary.is-busy .dashicon{display:none}.components-button.editor-post-publish-panel__toggle.is-primary .dashicon{margin-left:-4px}.editor-post-publish-panel__link{font-weight:400;padding-right:4px}.editor-post-publish-panel__prepublish{padding:16px}.editor-post-publish-panel__prepublish strong{color:#1e1e1e}.editor-post-publish-panel__prepublish .components-panel__body{background:#fff;margin-left:-16px;margin-right:-16px}.editor-post-publish-panel__prepublish .editor-post-visibility__dialog-legend{display:none}.editor-post-publish-panel__prepublish .components-panel__body-title .components-button{align-items:flex-start;text-wrap:balance;text-wrap:pretty}.post-publish-panel__postpublish .components-panel__body{border-bottom:1px solid #e0e0e0;border-top:none}.post-publish-panel__postpublish-buttons{align-content:space-between;display:flex;flex-wrap:wrap;gap:16px}.post-publish-panel__postpublish-buttons .components-button{flex:1;justify-content:center}.post-publish-panel__postpublish-buttons .components-clipboard-button{width:100%}.post-publish-panel__postpublish-post-address-container{align-items:flex-end;display:flex;margin-bottom:16px}.post-publish-panel__postpublish-post-address-container .post-publish-panel__postpublish-post-address{flex:1}.post-publish-panel__postpublish-post-address-container input[readonly]{background:#f0f0f0;border-color:#ccc;height:36px;overflow:hidden;padding:12px;text-overflow:ellipsis}.post-publish-panel__postpublish-post-address__copy-button-wrap{flex-shrink:0;margin-right:16px}.post-publish-panel__postpublish-header{font-weight:500}.post-publish-panel__postpublish-subheader{margin:0 0 8px}.post-publish-panel__tip{color:#f0b849}@media screen and (max-width:782px){.post-publish-panel__postpublish-post-address__button-wrap .components-button{height:40px}}.editor-post-publish-panel{background:#fff;bottom:0;left:0;overflow:auto;position:fixed;right:0;top:46px;z-index:100001}@media (min-width:782px){.editor-post-publish-panel{border-right:1px solid #ddd;right:auto;top:32px;width:281px;z-index:99998}}@media (min-width:782px) and (not (prefers-reduced-motion)){.editor-post-publish-panel{animation:editor-post-publish-panel__slide-in-animation .1s forwards;transform:translateX(-100%)}}@media (min-width:782px){body.is-fullscreen-mode .editor-post-publish-panel{top:0}[role=region]:focus .editor-post-publish-panel{transform:translateX(0)}}@keyframes editor-post-publish-panel__slide-in-animation{to{transform:translateX(0)}}.editor-post-saved-state{align-items:center;color:#757575;display:flex;overflow:hidden;padding:12px 4px;white-space:nowrap;width:28px}.editor-post-saved-state.is-saved[aria-disabled=true],.editor-post-saved-state.is-saved[aria-disabled=true]:hover,.editor-post-saved-state.is-saving[aria-disabled=true],.editor-post-saved-state.is-saving[aria-disabled=true]:hover{background:#0000;color:#757575}.editor-post-saved-state svg{display:inline-block;flex:0 0 auto;fill:currentColor;margin-left:8px}@media (min-width:600px){.editor-post-saved-state{padding:8px 12px;text-indent:inherit;width:auto}.editor-post-saved-state svg{margin-left:0}}.editor-post-save-draft.has-text.has-icon svg{margin-left:0}.editor-post-schedule__panel-dropdown{width:100%}.editor-post-schedule__dialog .components-popover__content{min-width:320px;padding:16px}.editor-post-status{max-width:100%}.editor-post-status.is-read-only{padding:6px 12px}.editor-post-status .editor-post-status__toggle.editor-post-status__toggle{padding-bottom:4px;padding-top:4px}.editor-change-status__password-fieldset,.editor-change-status__publish-date-wrapper{border-top:1px solid #e0e0e0;padding-top:16px}.editor-change-status__content .components-popover__content{min-width:320px;padding:16px}.editor-change-status__content .editor-change-status__password-legend{margin-bottom:8px;padding:0}.editor-change-status__content p.components-base-control__help:has(.components-checkbox-control__help){margin-top:4px}.editor-post-sticky__checkbox-control{border-top:1px solid #e0e0e0;padding-top:16px}.editor-post-sync-status__value{padding:6px 12px 6px 0}.editor-post-taxonomies__hierarchical-terms-list{margin-right:-6px;margin-top:-6px;max-height:14em;overflow:auto;padding-right:6px;padding-top:6px}.editor-post-taxonomies__hierarchical-terms-choice{margin-bottom:8px}.editor-post-taxonomies__hierarchical-terms-choice:last-child{margin-bottom:4px}.editor-post-taxonomies__hierarchical-terms-subchoices{margin-right:16px;margin-top:8px}.editor-post-taxonomies__flat-term-most-used .editor-post-taxonomies__flat-term-most-used-label{margin-bottom:4px}.editor-post-taxonomies__flat-term-most-used-list{margin:0}.editor-post-taxonomies__flat-term-most-used-list li{display:inline-block;margin-left:8px}.editor-post-template__swap-template-modal{z-index:1000001}.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px;padding-top:2px}@media (min-width:782px){.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:4}}.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.editor-post-template__dropdown .components-popover__content{min-width:240px}.editor-post-template__dropdown .components-button.is-pressed,.editor-post-template__dropdown .components-button.is-pressed:hover{background:inherit;color:inherit}@media (min-width:782px){.editor-post-template__create-form{width:320px}}.editor-post-template__classic-theme-dropdown{padding:8px}textarea.editor-post-text-editor{border:1px solid #949494;border-radius:0;box-shadow:none;display:block;font-family:Menlo,Consolas,monaco,monospace;font-size:16px!important;line-height:2.4;margin:0;min-height:200px;overflow:hidden;padding:16px;resize:none;width:100%}@media not (prefers-reduced-motion){textarea.editor-post-text-editor{transition:border .1s ease-out,box-shadow .1s linear}}@media (min-width:600px){textarea.editor-post-text-editor{font-size:15px!important;padding:24px}}textarea.editor-post-text-editor:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);position:relative}textarea.editor-post-text-editor::-webkit-input-placeholder{color:#1e1e1e9e}textarea.editor-post-text-editor::-moz-placeholder{color:#1e1e1e9e}textarea.editor-post-text-editor:-ms-input-placeholder{color:#1e1e1e9e}.editor-post-title.is-raw-text{margin-bottom:24px;margin-top:2px;max-width:none}.editor-post-url__panel-dropdown{width:100%}.editor-post-url__panel-dialog .editor-post-url{margin:8px;min-width:248px}.editor-post-url__front-page-link,.editor-post-url__link{direction:ltr;word-break:break-word}.editor-post-url__front-page-link{padding:6px 12px 6px 0}.editor-post-url__link-slug{font-weight:600}.editor-post-url__input input.components-input-control__input{padding-inline-start:0!important}.editor-post-url__panel-toggle{word-break:break-word}.editor-post-url__intro{margin:0}.editor-post-url__permalink{margin-bottom:0;margin-top:8px}.editor-post-url__permalink-visual-label{display:block}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{border:1px solid #1e1e1e;border-radius:2px;border-radius:50%;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:24px;line-height:normal;margin-left:12px;margin-top:2px;max-width:24px;min-width:24px;padding:6px 8px;position:relative;transition:none;width:24px}@media not (prefers-reduced-motion){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{transition:box-shadow .1s linear}}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{font-size:13px;line-height:normal}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-webkit-input-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-moz-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{height:16px;max-width:16px;min-width:16px;width:16px}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{background-color:#fff;border:4px solid #fff;box-sizing:inherit;height:12px;margin:0;position:absolute;right:50%;top:50%;transform:translate(50%,-50%);width:12px}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{height:8px;width:8px}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color);outline:2px solid #0000}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked{background:var(--wp-admin-theme-color);border:none}.editor-post-visibility__fieldset .editor-post-visibility__info{color:#757575;margin-right:36px;margin-top:.5em}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__info{margin-right:28px}}.editor-post-visibility__fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__info{margin-bottom:0}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;margin-right:32px;padding:6px 8px;width:calc(100% - 32px)}@media not (prefers-reduced-motion){.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{transition:box-shadow .1s linear}}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{font-size:13px;line-height:normal}}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-webkit-input-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-moz-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:-ms-input-placeholder{color:#1e1e1e9e}.editor-posts-per-page-dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-post-trash.components-button{flex-grow:1;justify-content:center}.editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text{padding-left:4px;padding-right:6px}.editor-preview-dropdown__button-external{display:flex;justify-content:space-between;width:100%}.editor-resizable-editor.is-resizable{margin:0 auto;overflow:visible}.editor-resizable-editor__resize-handle{appearance:none;background:none;border:0;border-radius:9999px;bottom:0;cursor:ew-resize;height:100px;margin:auto 0;outline:none;padding:0;position:absolute;top:0;width:12px}.editor-resizable-editor__resize-handle:after{background-color:#75757566;border-radius:9999px;bottom:16px;content:"";left:0;position:absolute;right:4px;top:16px;width:4px}.editor-resizable-editor__resize-handle.is-left{right:-18px}.editor-resizable-editor__resize-handle.is-right{left:-18px}.editor-resizable-editor__resize-handle:active,.editor-resizable-editor__resize-handle:focus,.editor-resizable-editor__resize-handle:hover{opacity:1}.editor-resizable-editor__resize-handle:active:after,.editor-resizable-editor__resize-handle:focus:after,.editor-resizable-editor__resize-handle:hover:after{background-color:var(--wp-admin-theme-color)}.editor-layout__toggle-entities-saved-states-panel,.editor-layout__toggle-publish-panel,.editor-layout__toggle-sidebar-panel{background-color:#fff;border:1px dotted #ddd;bottom:auto;box-sizing:border-box;display:flex;height:auto!important;justify-content:center;left:0;padding:24px;position:fixed!important;right:auto;top:-9999em;width:280px;z-index:100000}.interface-interface-skeleton__actions:focus .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus .editor-layout__toggle-publish-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-publish-panel{bottom:0;top:auto}.editor-start-page-options__modal .editor-start-page-options__modal__actions{background-color:#fff;border-top:1px solid #ddd;bottom:0;height:92px;margin-left:-32px;margin-right:-32px;padding-left:32px;padding-right:32px;position:absolute;width:100%;z-index:1}.editor-start-page-options__modal .block-editor-block-patterns-list{padding-bottom:92px}.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:782px){.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:4}}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column;margin-bottom:24px}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__container{min-height:100px}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__content{width:100%}.editor-start-template-options__modal .editor-start-template-options__modal__actions{background-color:#fff;border-top:1px solid #ddd;bottom:0;height:92px;margin-left:-32px;margin-right:-32px;padding-left:32px;padding-right:32px;position:absolute;width:100%;z-index:1}.editor-start-template-options__modal .block-editor-block-patterns-list{padding-bottom:92px}.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:782px){.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:4}}.editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-patterns-list__item-title{display:none}.components-panel__header.editor-sidebar__panel-tabs{padding-left:8px;padding-right:0}.components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{padding:0}@media (min-width:782px){.components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{display:flex}}.editor-post-summary .components-v-stack:empty{display:none}.editor-site-discussion-dropdown__content .components-popover__content{min-width:320px;padding:16px}.table-of-contents__popover.components-popover .components-popover__content{min-width:380px}.components-popover.table-of-contents__popover{z-index:99998}.table-of-contents__popover .components-popover__content{padding:16px}@media (min-width:600px){.table-of-contents__popover .components-popover__content{max-height:calc(100vh - 120px);overflow-y:auto}}.table-of-contents__popover hr{margin:10px -16px 0}.table-of-contents__wrapper:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0}.table-of-contents__counts{display:flex;flex-wrap:wrap;margin:-8px 0 0}.table-of-contents__count{color:#1e1e1e;display:flex;flex-basis:33%;flex-direction:column;font-size:13px;margin-bottom:0;margin-top:8px;padding-left:8px}.table-of-contents__count:nth-child(4n){padding-left:0}.table-of-contents__number,.table-of-contents__popover .word-count{color:#1e1e1e;font-size:21px;font-weight:400;line-height:30px}.table-of-contents__title{display:block;font-size:15px;font-weight:600;margin-top:20px}.editor-text-editor{background-color:#fff;flex-grow:1;position:relative;width:100%}.editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){border:1px solid #949494;border-radius:0;font-family:Menlo,Consolas,monaco,monospace;font-size:2.5em;font-weight:400;line-height:1.4;max-width:none;padding:16px}@media (min-width:600px){.editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){padding:24px}}.editor-text-editor .editor-post-title.is-raw-text textarea:focus,.editor-text-editor .editor-post-title:not(.is-raw-text):focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.editor-text-editor__body{margin-left:auto;margin-right:auto;max-width:1080px;padding:0 12px 12px;width:100%}@media (min-width:960px){.editor-text-editor__body{padding:0 24px 24px}}.editor-text-editor__toolbar{background:#fffc;display:flex;left:0;padding:4px 12px;position:sticky;right:0;top:0;z-index:1}@media (min-width:600px){.editor-text-editor__toolbar{padding:12px}}@media (min-width:960px){.editor-text-editor__toolbar{padding:12px 24px}}.editor-text-editor__toolbar h2{color:#1e1e1e;font-size:13px;line-height:40px;margin:0 0 0 auto}.editor-visual-editor{align-items:center;background-color:#ddd;display:flex;position:relative}.editor-visual-editor iframe[name=editor-canvas]{background-color:initial}.editor-visual-editor.is-resizable{max-height:100%}.editor-visual-editor.has-padding{padding:24px 24px 0}.editor-visual-editor.is-iframed{overflow:hidden}.editor-visual-editor .components-button{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:6px 12px}.editor-visual-editor .components-button.has-icon,.editor-visual-editor .components-button.is-tertiary{padding:6px}.editor-fields-content-preview{border-radius:4px;display:flex;flex-direction:column;height:100%}.dataviews-view-table .editor-fields-content-preview{flex-grow:0;width:96px}.editor-fields-content-preview .block-editor-block-preview__container,.editor-fields-content-preview .editor-fields-content-preview__empty{margin-bottom:auto;margin-top:auto}.editor-fields-content-preview__empty{text-align:center}@charset "UTF-8";:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.interface-complementary-area-header{background:#fff;gap:4px;padding-right:8px}.interface-complementary-area-header .interface-complementary-area-header__title{margin:0 auto 0 0}.interface-complementary-area{background:#fff;color:#1e1e1e;height:100%;overflow:auto}@media (min-width:600px){.interface-complementary-area{-webkit-overflow-scrolling:touch}}@media (min-width:782px){.interface-complementary-area{width:280px}}.interface-complementary-area .components-panel{border:none;position:relative;z-index:0}.interface-complementary-area .components-panel__header{position:sticky;top:0;z-index:1}.interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{top:0}.interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){margin-top:0}.interface-complementary-area h2{color:#1e1e1e;font-size:13px;font-weight:500;margin-bottom:1.5em}.interface-complementary-area h3{color:#1e1e1e;font-size:11px;font-weight:500;margin-bottom:1.5em;text-transform:uppercase}.interface-complementary-area hr{border-bottom:1px solid #f0f0f0;border-top:none;margin:1.5em 0}.interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{box-shadow:none;margin-bottom:1.5em}.interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{margin-bottom:0}.interface-complementary-area .block-editor-skip-to-selected-block:focus{bottom:10px;left:auto;right:10px;top:auto}.interface-complementary-area__fill{height:100%}@media (min-width:782px){body.js.is-fullscreen-mode{height:calc(100% + 32px);margin-top:-32px}body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{display:none}body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{margin-left:0}}html.interface-interface-skeleton__html-container{position:fixed;width:100%}@media (min-width:782px){html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){position:static;width:auto}}.interface-interface-skeleton{bottom:0;display:flex;flex-direction:row;height:auto;max-height:100%;position:fixed;right:0;top:46px}@media (min-width:783px){.interface-interface-skeleton{top:32px}.is-fullscreen-mode .interface-interface-skeleton{top:0}}.interface-interface-skeleton__editor{display:flex;flex:0 1 100%;flex-direction:column;overflow:hidden}.interface-interface-skeleton{left:0}@media (min-width:783px){.interface-interface-skeleton{left:160px}}@media (min-width:783px){.auto-fold .interface-interface-skeleton{left:36px}}@media (min-width:961px){.auto-fold .interface-interface-skeleton{left:160px}}.folded .interface-interface-skeleton{left:0}@media (min-width:783px){.folded .interface-interface-skeleton{left:36px}}body.is-fullscreen-mode .interface-interface-skeleton{left:0!important}.interface-interface-skeleton__body{display:flex;flex-grow:1;overflow:auto;overscroll-behavior-y:none;position:relative}@media (min-width:782px){.has-footer .interface-interface-skeleton__body{padding-bottom:25px}}.interface-interface-skeleton__content{display:flex;flex-direction:column;flex-grow:1;overflow:auto;z-index:20}@media (min-width:782px){.interface-interface-skeleton__content{z-index:auto}}.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{background:#fff;bottom:0;color:#1e1e1e;flex-shrink:0;left:0;position:absolute;top:0;width:auto;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{position:relative!important}}.interface-interface-skeleton__sidebar{border-top:1px solid #e0e0e0;overflow:hidden}@media (min-width:782px){.interface-interface-skeleton__sidebar{box-shadow:-1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__secondary-sidebar{border-top:1px solid #e0e0e0;right:0}@media (min-width:782px){.interface-interface-skeleton__secondary-sidebar{box-shadow:1px 0 0 0 rgba(0,0,0,.133);outline:1px solid #0000}}.interface-interface-skeleton__header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);color:#1e1e1e;flex-shrink:0;height:auto;outline:1px solid #0000;z-index:30}.interface-interface-skeleton__footer{background-color:#fff;border-top:1px solid #e0e0e0;bottom:0;color:#1e1e1e;display:none;flex-shrink:0;height:auto;left:0;position:absolute;width:100%;z-index:90}@media (min-width:782px){.interface-interface-skeleton__footer{display:flex}}.interface-interface-skeleton__footer .block-editor-block-breadcrumb{align-items:center;background:#fff;display:flex;font-size:13px;height:24px;padding:0 18px;z-index:30}.interface-interface-skeleton__actions{background:#fff;bottom:auto;color:#1e1e1e;left:auto;position:fixed!important;right:0;top:-9999em;width:100vw;z-index:100000}@media (min-width:782px){.interface-interface-skeleton__actions{width:280px}}.interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{bottom:0;top:auto}.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:46px}@media (min-width:782px){.is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{border-left:1px solid #ddd;top:32px}.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{top:0}}.interface-pinned-items{display:flex;gap:8px}.interface-pinned-items .components-button{display:none;margin:0}.interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{display:flex}.interface-pinned-items .components-button svg{max-height:24px;max-width:24px}@media (min-width:600px){.interface-pinned-items .components-button{display:flex}}.editor-autocompleters__user .editor-autocompleters__no-avatar:before{content:"\f110";font:normal 20px/1 dashicons;margin-right:5px;vertical-align:middle}.editor-autocompleters__user .editor-autocompleters__user-avatar{flex-grow:0;flex-shrink:0;height:24px;margin-right:8px;max-width:none;width:24px}.editor-autocompleters__user .editor-autocompleters__user-name{flex-grow:1;flex-shrink:0;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.editor-autocompleters__user .editor-autocompleters__user-slug{color:#757575;flex-grow:0;flex-shrink:0;margin-left:8px;max-width:100px;overflow:none;text-overflow:ellipsis;white-space:nowrap}.editor-autocompleters__user:hover .editor-autocompleters__user-slug{color:var(--wp-admin-theme-color)}.interface-interface-skeleton__sidebar:has(.editor-collab-sidebar){box-shadow:none}.interface-interface-skeleton__sidebar:has(.editor-collab-sidebar) .interface-complementary-area-header{display:none}.editor-collab-sidebar{height:100%}.editor-collab-sidebar-panel{height:100%;padding:16px}.editor-collab-sidebar-panel__thread{background-color:#f0f0f0;border:1.5px solid #ddd;border-radius:8px;margin-bottom:16px;padding:16px;position:relative}.editor-collab-sidebar-panel__active-thread{border:1.5px solid #3858e9}.editor-collab-sidebar-panel__focus-thread{background-color:#fff;border:1.5px solid #3858e9;box-shadow:0 5.5px 7.8px -.3px rgba(0,0,0,.102)}.editor-collab-sidebar-panel__comment-field{flex:1}.editor-collab-sidebar-panel__child-thread{margin-top:15px}.editor-collab-sidebar-panel__user-name{text-transform:capitalize}.editor-collab-sidebar-panel__user-name,.editor-collab-sidebar-panel__user-time{color:#757575;font-size:12px;font-weight:400;line-height:16px;text-align:left}.editor-collab-sidebar-panel__user-comment{color:#1e1e1e;font-size:13px;font-weight:400;line-height:20px;text-align:left}.editor-collab-sidebar-panel__user-comment p{margin-bottom:0}.editor-collab-sidebar-panel__user-avatar{border-radius:50%;flex-shrink:0}.editor-collab-sidebar-panel__thread-overlay{background-color:#000000b3;border-radius:8px;color:#fff;height:100%;left:0;padding:15px;position:absolute;text-align:center;top:0;width:100%;z-index:1}.editor-collab-sidebar-panel__thread-overlay p{margin-bottom:15px}.editor-collab-sidebar-panel__thread-overlay button{color:#fff;padding:4px 10px}.editor-collab-sidebar-panel__comment-status{margin-left:auto}.editor-collab-sidebar-panel__comment-status button.has-icon:not(.has-text){flex-shrink:0;height:24px;min-width:24px;padding:0;width:24px}.editor-collab-sidebar-panel__comment-dropdown-menu{flex-shrink:0}.editor-collab-sidebar-panel__comment-dropdown-menu button.has-icon{height:24px;min-width:24px;padding:0;width:24px}.editor-collab-sidebar-panel__show-more-reply{font-style:italic;font-weight:500;padding:0}.editor-collapsible-block-toolbar{align-items:center;display:flex;height:60px;overflow:hidden}.editor-collapsible-block-toolbar .block-editor-block-contextual-toolbar{background:#0000;border-bottom:0;height:100%}.editor-collapsible-block-toolbar .block-editor-block-toolbar{height:100%;padding-top:15px}.editor-collapsible-block-toolbar .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){height:32px}.editor-collapsible-block-toolbar:after{background-color:#ddd;content:"";height:24px;margin-right:7px;width:1px}.editor-collapsible-block-toolbar .components-toolbar,.editor-collapsible-block-toolbar .components-toolbar-group{border-right:none;position:relative}.editor-collapsible-block-toolbar .components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar:after{background-color:#ddd;content:"";height:24px;position:absolute;right:-1px;top:4px;width:1px}.editor-collapsible-block-toolbar .components-toolbar .components-toolbar-group.components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{display:none}.editor-collapsible-block-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{height:32px;overflow:visible}@media (min-width:600px){.editor-collapsible-block-toolbar .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{height:40px;position:relative;top:-5px}}.editor-collapsible-block-toolbar.is-collapsed{display:none}.editor-content-only-settings-menu__description{min-width:235px;padding:8px}.editor-blog-title-dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-document-bar{align-items:center;background:#f0f0f0;border-radius:4px;display:flex;height:32px;justify-content:space-between;min-width:0;width:min(100%,450px)}.editor-document-bar:hover{background-color:#e0e0e0}.editor-document-bar .components-button{border-radius:4px}@media not (prefers-reduced-motion){.editor-document-bar .components-button{transition:all .1s ease-out}}.editor-document-bar .components-button:hover{background:#e0e0e0}@media screen and (min-width:782px) and (max-width:960px){.editor-document-bar.has-back-button .editor-document-bar__post-type-label{display:none}}.editor-document-bar__command{color:var(--wp-block-synced-color);flex-grow:1;overflow:hidden}.editor-document-bar__title{color:#1e1e1e;margin:0 auto;max-width:70%;overflow:hidden}@media (min-width:782px){.editor-document-bar__title{padding-left:24px}}.editor-document-bar__title h1{align-items:center;display:flex;font-weight:400;justify-content:center;overflow:hidden;white-space:nowrap}.editor-document-bar__post-title{color:currentColor;flex:1;overflow:hidden;text-overflow:ellipsis}.editor-document-bar__post-type-label{color:#2f2f2f;flex:0;padding-left:4px}@media screen and (max-width:600px){.editor-document-bar__post-type-label{display:none}}.editor-document-bar__shortcut{color:#2f2f2f;display:none;min-width:24px}@media (min-width:782px){.editor-document-bar__shortcut{display:initial}}.editor-document-bar__back.components-button.has-icon.has-text{color:#757575;flex-shrink:0;gap:0;min-width:36px;position:absolute;z-index:1}.editor-document-bar__back.components-button.has-icon.has-text:hover{background-color:initial;color:#1e1e1e}.editor-document-bar__icon-layout.editor-document-bar__icon-layout{display:none;margin-left:12px;pointer-events:none;position:absolute}.editor-document-bar__icon-layout.editor-document-bar__icon-layout svg{fill:#949494}@media (min-width:600px){.editor-document-bar__icon-layout.editor-document-bar__icon-layout{display:flex}}.document-outline{margin:20px 0}.document-outline ul{margin:0;padding:0}.document-outline__item{display:flex;margin:4px 0}.document-outline__item a{text-decoration:none}.document-outline__item .document-outline__emdash:before{color:#ddd;margin-right:4px}.document-outline__item.is-h2 .document-outline__emdash:before{content:"—"}.document-outline__item.is-h3 .document-outline__emdash:before{content:"——"}.document-outline__item.is-h4 .document-outline__emdash:before{content:"———"}.document-outline__item.is-h5 .document-outline__emdash:before{content:"————"}.document-outline__item.is-h6 .document-outline__emdash:before{content:"—————"}.document-outline__button{align-items:flex-start;background:none;border:none;border-radius:2px;color:#1e1e1e;cursor:pointer;display:flex;margin:0 0 0 -1px;padding:2px 5px 2px 1px;text-align:left}.document-outline__button:disabled,.document-outline__button[aria-disabled=true]{color:#757575;cursor:default}.document-outline__button:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.document-outline__level{background:#ddd;border-radius:3px;color:#1e1e1e;font-size:13px;margin-right:4px;padding:1px 6px}.is-invalid .document-outline__level{background:#f0b849}.document-outline__item-content{padding:1px 0}.editor-document-outline.has-no-headings{color:#757575;text-align:center}.editor-document-outline.has-no-headings>svg{margin-top:28px}.editor-document-outline.has-no-headings>p{padding-left:32px;padding-right:32px}.editor-document-tools{align-items:center;display:inline-flex}.editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{display:none}@media (min-width:782px){.editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{display:inline-flex}}.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle{display:inline-flex}@media not (prefers-reduced-motion){.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle svg{transition:transform .2s cubic-bezier(.165,.84,.44,1)}}.editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.is-pressed svg{transform:rotate(45deg)}.editor-document-tools .block-editor-list-view{display:none}@media (min-width:600px){.editor-document-tools .block-editor-list-view{display:flex}}.editor-document-tools .editor-document-tools__left>.components-button.has-icon,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon{height:32px;min-width:32px;padding:4px}.editor-document-tools .editor-document-tools__left>.components-button.has-icon.is-pressed,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon.is-pressed{background:#1e1e1e}.editor-document-tools .editor-document-tools__left>.components-button.has-icon:focus:not(:disabled),.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color),inset 0 0 0 1px #fff;outline:1px solid #0000}.editor-document-tools .editor-document-tools__left>.components-button.has-icon:before,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:before{display:none}.editor-document-tools__left{align-items:center;display:inline-flex;gap:8px}.editor-document-tools__left:not(:last-child){margin-inline-end:8px}.show-icon-labels .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.has-icon{padding:0 8px;width:auto}.show-icon-labels .editor-document-tools__left>*+*{margin-left:8px}.editor-editor-interface .entities-saved-states__panel-header{height:61px}.editor-editor-interface .interface-interface-skeleton__content{isolation:isolate}.editor-visual-editor{flex:1 0 auto}.components-editor-notices__dismissible,.components-editor-notices__pinned{color:#1e1e1e;left:0;position:relative;right:0;top:0}.components-editor-notices__dismissible .components-notice,.components-editor-notices__pinned .components-notice{border-bottom:1px solid #0003;box-sizing:border-box;min-height:60px;padding:0 12px}.components-editor-notices__dismissible .components-notice .components-notice__dismiss,.components-editor-notices__pinned .components-notice .components-notice__dismiss{margin-top:12px}.entities-saved-states__panel-header{background:#fff;border-bottom:1px solid #ddd;box-sizing:border-box;height:60px;padding-left:16px;padding-right:16px}.entities-saved-states__text-prompt{padding:16px 16px 4px}.entities-saved-states__text-prompt .entities-saved-states__text-prompt--header{display:block;margin-bottom:12px}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt{padding:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body{border:0;padding-left:0;padding-right:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2{margin-bottom:0;margin-left:-16px;margin-right:-16px}.entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2 button{font-size:11px;text-transform:uppercase}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--header-wrapper{display:none}.entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--changes-count{margin-bottom:8px;margin-top:0}.entities-saved-states__panel.is-inline .entities-saved-states__panel-footer{margin-top:16px}.entities-saved-states__change-control{flex:1}.entities-saved-states__changes{font-size:13px;list-style:disc;margin:4px 16px 0 24px}.entities-saved-states__changes li{margin-bottom:4px}.editor-error-boundary{background-color:#fff;border:1px solid #1e1e1e;border-radius:2px;box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;margin:60px auto auto;max-width:780px;padding:1em}.editor-header{align-items:center;background:#fff;display:grid;grid-auto-flow:row;grid-template:auto/60px minmax(0,max-content) minmax(min-content,1fr) 60px;height:60px;justify-content:space-between;max-width:100vw}.editor-header:has(>.editor-header__center){grid-template:auto/60px min-content 1fr min-content 60px}@media (min-width:782px){.editor-header:has(>.editor-header__center){grid-template:auto/60px minmax(min-content,2fr) 2.5fr minmax(min-content,2fr) 60px}}@media (min-width:480px){.editor-header{gap:16px}}@media (min-width:280px){.editor-header{flex-wrap:nowrap}}.editor-header__toolbar{align-items:center;clip-path:inset(-2px);display:flex;grid-column:1/3;min-width:0}.editor-header__toolbar>:first-child{margin-inline:16px 0}.editor-header__back-button+.editor-header__toolbar{grid-column:2/3}@media (min-width:480px){.editor-header__back-button+.editor-header__toolbar>:first-child{margin-inline:0}.editor-header__toolbar{clip-path:none}}.editor-header__toolbar .table-of-contents{display:none}@media (min-width:600px){.editor-header__toolbar .table-of-contents{display:block}}.editor-header__toolbar .editor-collapsible-block-toolbar,.editor-header__toolbar .editor-collapsible-block-toolbar.is-collapsed~.editor-collapsible-block-toolbar__toggle{margin-inline:8px 0}.editor-header__center{align-items:center;clip-path:inset(-2px);display:flex;grid-column:3/4;justify-content:center;min-width:0}@media (max-width:479px){.editor-header__center>:first-child{margin-inline-start:8px}.editor-header__center>:last-child{margin-inline-end:8px}}.editor-header__settings{align-items:center;display:inline-flex;flex-wrap:nowrap;gap:8px;grid-column:3/-1;justify-self:end;padding-right:4px}.editor-header:has(>.editor-header__center) .editor-header__settings{grid-column:4/-1}@media (min-width:600px){.editor-header__settings{padding-right:8px}}.show-icon-labels .editor-header .components-button.has-icon,.show-icon-labels.interface-pinned-items .components-button.has-icon{width:auto}.show-icon-labels .editor-header .components-button.has-icon svg,.show-icon-labels.interface-pinned-items .components-button.has-icon svg{display:none}.show-icon-labels .editor-header .components-button.has-icon:after,.show-icon-labels.interface-pinned-items .components-button.has-icon:after{content:attr(aria-label);white-space:nowrap}.show-icon-labels .editor-header .components-button.has-icon[aria-disabled=true],.show-icon-labels.interface-pinned-items .components-button.has-icon[aria-disabled=true]{background-color:initial}.show-icon-labels .editor-header .is-tertiary:active,.show-icon-labels.interface-pinned-items .is-tertiary:active{background-color:initial;box-shadow:0 0 0 1.5px var(--wp-admin-theme-color)}.show-icon-labels .editor-header .components-button.has-icon.button-toggle svg,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle svg{display:block}.show-icon-labels .editor-header .components-button.has-icon.button-toggle:after,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle:after{content:none}.show-icon-labels .editor-header .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon,.show-icon-labels.interface-pinned-items .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon{display:block}.show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{padding-left:8px;padding-right:8px}@media (min-width:600px){.show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{padding-left:12px;padding-right:12px}}.show-icon-labels .editor-header .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels .editor-header .editor-post-saved-state.editor-post-saved-state:after,.show-icon-labels.interface-pinned-items .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels.interface-pinned-items .editor-post-saved-state.editor-post-saved-state:after{content:none}.show-icon-labels .editor-header__toolbar .block-editor-block-mover{border-left:none}.show-icon-labels .editor-header__toolbar .block-editor-block-mover:before{background-color:#ddd;content:"";height:24px;margin-left:8px;margin-top:4px;width:1px}.show-icon-labels .editor-header__toolbar .block-editor-block-mover .block-editor-block-mover__move-button-container:before{background:#ddd;left:calc(50% + 1px);width:calc(100% - 24px)}.show-icon-labels.interface-pinned-items{border-bottom:1px solid #ccc;display:block;margin:0 -12px;padding:6px 12px 12px}.show-icon-labels.interface-pinned-items>.components-button.has-icon{justify-content:flex-start;margin:0;padding:6px 6px 6px 8px;width:14.625rem}.show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=true] svg{display:block;max-width:24px}.show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=false]{padding-left:40px}.show-icon-labels.interface-pinned-items>.components-button.has-icon svg{margin-right:8px}@media (min-width:480px){.editor-header__post-preview-button{display:none}}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header{border-bottom:none}.editor-editor-interface.is-distraction-free .editor-header{background-color:#fff;width:100%}@media (min-width:782px){.editor-editor-interface.is-distraction-free .editor-header{box-shadow:0 1px 0 0 rgba(0,0,0,.133);position:absolute}}.editor-editor-interface.is-distraction-free .editor-header>.edit-post-header__settings>.edit-post-header__post-preview-button{visibility:hidden}.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-preview-dropdown,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-zoom-out-toggle,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.interface-pinned-items,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__toolbar .editor-document-tools__document-overview-toggle{display:none}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within{opacity:1!important}.editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within div{transform:translateX(0) translateZ(0)!important}.editor-editor-interface.is-distraction-free .components-editor-notices__dismissible{position:absolute;z-index:35}.components-popover.more-menu-dropdown__content{z-index:99998}.editor-inserter-sidebar{box-sizing:border-box;display:flex;flex-direction:column;height:100%}.editor-inserter-sidebar *,.editor-inserter-sidebar :after,.editor-inserter-sidebar :before{box-sizing:inherit}.editor-inserter-sidebar__content{height:100%}.editor-keyboard-shortcut-help-modal__section{margin:0 0 2rem}.editor-keyboard-shortcut-help-modal__section-title{font-size:.9rem;font-weight:600}.editor-keyboard-shortcut-help-modal__shortcut{align-items:baseline;border-top:1px solid #ddd;display:flex;margin-bottom:0;padding:.6rem 0}.editor-keyboard-shortcut-help-modal__shortcut:last-child{border-bottom:1px solid #ddd}.editor-keyboard-shortcut-help-modal__shortcut:empty{display:none}.editor-keyboard-shortcut-help-modal__shortcut-term{font-weight:600;margin:0 0 0 1rem;text-align:right}.editor-keyboard-shortcut-help-modal__shortcut-description{flex:1;margin:0}.editor-keyboard-shortcut-help-modal__shortcut-key-combination{background:none;display:block;margin:0;padding:0}.editor-keyboard-shortcut-help-modal__shortcut-key-combination+.editor-keyboard-shortcut-help-modal__shortcut-key-combination{margin-top:10px}.editor-keyboard-shortcut-help-modal__shortcut-key{border-radius:8%;margin:0 .2rem;padding:.25rem .5rem}.editor-keyboard-shortcut-help-modal__shortcut-key:last-child{margin:0 0 0 .2rem}.editor-list-view-sidebar{height:100%}@media (min-width:782px){.editor-list-view-sidebar{width:350px}}.editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{height:100%;overflow:auto;padding:4px;scrollbar-color:#0000 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:auto;scrollbar-width:thin;will-change:transform}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar{height:12px;width:12px}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-track,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-track{background-color:initial}.editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:initial;border:3px solid #0000;border-radius:8px}.editor-list-view-sidebar__list-view-container>.document-outline:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:hover::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:hover::-webkit-scrollbar-thumb{background-color:#949494}.editor-list-view-sidebar__list-view-container>.document-outline:focus,.editor-list-view-sidebar__list-view-container>.document-outline:focus-within,.editor-list-view-sidebar__list-view-container>.document-outline:hover,.editor-list-view-sidebar__list-view-panel-content:focus,.editor-list-view-sidebar__list-view-panel-content:focus-within,.editor-list-view-sidebar__list-view-panel-content:hover{scrollbar-color:#949494 #0000}@media (hover:none){.editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{scrollbar-color:#949494 #0000}}.editor-list-view-sidebar__list-view-container{display:flex;flex-direction:column;height:100%}.editor-list-view-sidebar__tab-panel{height:100%}.editor-list-view-sidebar__outline{border-bottom:1px solid #ddd;display:flex;flex-direction:column;gap:8px;padding:16px}.editor-list-view-sidebar__outline>div>span:first-child{display:inline-block;width:90px}.editor-list-view-sidebar__outline>div>span{color:#757575;font-size:12px;line-height:1.4}.editor-post-order__panel,.editor-post-parent__panel{padding-top:8px}.editor-post-order__panel .editor-post-panel__row-control>div,.editor-post-parent__panel .editor-post-panel__row-control>div{width:100%}.editor-post-order__panel-dialog .editor-post-order,.editor-post-order__panel-dialog .editor-post-parent,.editor-post-parent__panel-dialog .editor-post-order,.editor-post-parent__panel-dialog .editor-post-parent{margin:8px}.editor-post-order__panel-dialog .components-popover__content,.editor-post-parent__panel-dialog .components-popover__content{min-width:320px}.editor-post-author__panel{padding-top:8px}.editor-post-author__panel .editor-post-panel__row-control>div{width:100%}.editor-post-author__panel-dialog .editor-post-author{margin:8px;min-width:248px}.editor-action-modal{z-index:1000001}.editor-post-card-panel__content{flex-grow:1}.editor-post-card-panel__title{width:100%}.editor-post-card-panel__title.editor-post-card-panel__title{align-items:center;column-gap:8px;display:flex;flex-wrap:wrap;font-family:-apple-system,"system-ui",Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:500;line-height:20px;margin:0;row-gap:4px;word-break:break-word}.editor-post-card-panel__icon{flex:0 0 24px;height:24px;width:24px}.editor-post-card-panel__header{display:flex;justify-content:space-between}.editor-post-card-panel.has-description .editor-post-card-panel__header{margin-bottom:8px}.editor-post-card-panel .editor-post-card-panel__title-name{padding:2px 0}.editor-post-card-panel .editor-post-card-panel__description,.editor-post-content-information{color:#757575}.editor-post-content-information .components-text{color:inherit}.editor-post-discussion__panel-dialog .editor-post-discussion{margin:8px;min-width:248px}.editor-post-discussion__panel-toggle .components-text{color:inherit}.editor-post-discussion__panel-dialog .components-popover__content{min-width:320px}.editor-post-excerpt__textarea{margin-bottom:10px;width:100%}.editor-post-excerpt__dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-post-featured-image{padding:0}.editor-post-featured-image .components-spinner{left:50%;margin-left:-9px;margin-top:-9px;position:absolute;top:50%}.editor-post-featured-image__container{position:relative}.editor-post-featured-image__container:focus .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:focus-within .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:hover .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image){opacity:1}.editor-post-featured-image__container .editor-post-featured-image__actions.editor-post-featured-image__actions-missing-image{margin-top:16px;opacity:1}.editor-post-featured-image__container .components-drop-zone__content{border-radius:2px}.editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner{align-items:center;display:flex;gap:8px}.editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner .components-drop-zone__content-icon{margin:0}.editor-post-featured-image__preview,.editor-post-featured-image__toggle{box-shadow:0 0 0 0 var(--wp-admin-theme-color);display:flex;justify-content:center;min-height:40px;outline-offset:-1px;overflow:hidden;padding:0;width:100%}.editor-post-featured-image__preview{height:auto!important;outline:1px solid #0000001a}.editor-post-featured-image__preview .editor-post-featured-image__preview-image{aspect-ratio:2/1;object-fit:cover;object-position:50% 50%;width:100%}.editor-post-featured-image__toggle{box-shadow:inset 0 0 0 1px #ccc}.editor-post-featured-image__toggle:focus:not(:disabled){box-shadow:0 0 0 currentColor inset,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){bottom:0;opacity:0;padding:8px;position:absolute}@media not (prefers-reduced-motion){.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){transition:opacity 50ms ease-out}}.editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image) .editor-post-featured-image__action{-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background:#ffffffbf}.editor-post-featured-image__actions .editor-post-featured-image__action{flex-grow:1;justify-content:center}[class].editor-post-format__suggestion{margin:4px 0 0}.editor-post-format__dialog .editor-post-format__dialog-content{margin:8px;min-width:248px}.editor-post-last-edited-panel{color:#757575}.editor-post-last-edited-panel .components-text{color:inherit}.editor-post-last-revision__title{font-weight:500;width:100%}.editor-post-last-revision__title.components-button.has-icon{height:100%;justify-content:space-between}.editor-post-last-revision__title.components-button.has-icon:active,.editor-post-last-revision__title.components-button.has-icon:hover{background:#f0f0f0}.editor-post-last-revision__title.components-button.has-icon:focus{border-radius:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-panel__body.is-opened.editor-post-last-revision__panel{height:48px;padding:0}.components-panel__body.is-opened.editor-post-last-revision__panel .editor-post-last-revision__title.components-button.components-button{padding:16px}.editor-private-post-last-revision__button{display:inline-block}.editor-post-locked-modal__buttons{margin-top:24px}.editor-post-locked-modal__avatar{border-radius:50%;margin-top:16px;min-width:auto!important}.editor-post-panel__row{align-items:flex-start!important;justify-content:flex-start!important;min-height:32px;width:100%}.editor-post-panel__row-label{align-items:center;display:flex;flex-shrink:0;hyphens:auto;line-height:20px;min-height:32px;padding:6px 0;width:38%}.editor-post-panel__row-control{align-items:center;display:flex;flex-grow:1;min-height:32px}.editor-post-panel__row-control .components-button{height:auto;max-width:100%;min-height:32px;text-align:left;text-wrap:balance;text-wrap:pretty;white-space:normal}.editor-post-panel__row-control .components-dropdown{max-width:100%}.editor-post-panel__section{padding:16px}.editor-post-publish-panel__content{min-height:calc(100% - 144px)}.editor-post-publish-panel__content>.components-spinner{display:block;margin:100px auto 0}.editor-post-publish-panel__header{align-content:space-between;align-items:center;background:#fff;border-bottom:1px solid #ddd;display:flex;height:61px;padding-left:16px;padding-right:16px}.editor-post-publish-panel__header .components-button{justify-content:center;width:100%}.editor-post-publish-panel__header .has-icon{margin-left:auto;width:auto}.components-site-card{align-items:center;display:flex;margin:16px 0}.components-site-icon{border:none;border-radius:2px;flex-shrink:0;height:36px;margin-right:12px;width:36px}.components-site-name{display:block;font-size:14px}.components-site-home{color:#757575;display:block;font-size:12px;word-break:break-word}.editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{flex:1}@media (min-width:480px){.editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{max-width:160px}}.editor-post-publish-panel__header-publish-button{justify-content:center;padding-left:4px}.editor-post-publish-panel__header-cancel-button{padding-right:4px}.editor-post-publish-panel__header-published{flex-grow:1}.editor-post-publish-panel__footer{padding:16px}.components-button.editor-post-publish-panel__toggle.is-primary{align-items:center;display:inline-flex}.components-button.editor-post-publish-panel__toggle.is-primary.is-busy .dashicon{display:none}.components-button.editor-post-publish-panel__toggle.is-primary .dashicon{margin-right:-4px}.editor-post-publish-panel__link{font-weight:400;padding-left:4px}.editor-post-publish-panel__prepublish{padding:16px}.editor-post-publish-panel__prepublish strong{color:#1e1e1e}.editor-post-publish-panel__prepublish .components-panel__body{background:#fff;margin-left:-16px;margin-right:-16px}.editor-post-publish-panel__prepublish .editor-post-visibility__dialog-legend{display:none}.editor-post-publish-panel__prepublish .components-panel__body-title .components-button{align-items:flex-start;text-wrap:balance;text-wrap:pretty}.post-publish-panel__postpublish .components-panel__body{border-bottom:1px solid #e0e0e0;border-top:none}.post-publish-panel__postpublish-buttons{align-content:space-between;display:flex;flex-wrap:wrap;gap:16px}.post-publish-panel__postpublish-buttons .components-button{flex:1;justify-content:center}.post-publish-panel__postpublish-buttons .components-clipboard-button{width:100%}.post-publish-panel__postpublish-post-address-container{align-items:flex-end;display:flex;margin-bottom:16px}.post-publish-panel__postpublish-post-address-container .post-publish-panel__postpublish-post-address{flex:1}.post-publish-panel__postpublish-post-address-container input[readonly]{background:#f0f0f0;border-color:#ccc;height:36px;overflow:hidden;padding:12px;text-overflow:ellipsis}.post-publish-panel__postpublish-post-address__copy-button-wrap{flex-shrink:0;margin-left:16px}.post-publish-panel__postpublish-header{font-weight:500}.post-publish-panel__postpublish-subheader{margin:0 0 8px}.post-publish-panel__tip{color:#f0b849}@media screen and (max-width:782px){.post-publish-panel__postpublish-post-address__button-wrap .components-button{height:40px}}.editor-post-publish-panel{background:#fff;bottom:0;left:0;overflow:auto;position:fixed;right:0;top:46px;z-index:100001}@media (min-width:782px){.editor-post-publish-panel{border-left:1px solid #ddd;left:auto;top:32px;width:281px;z-index:99998}}@media (min-width:782px) and (not (prefers-reduced-motion)){.editor-post-publish-panel{animation:editor-post-publish-panel__slide-in-animation .1s forwards;transform:translateX(100%)}}@media (min-width:782px){body.is-fullscreen-mode .editor-post-publish-panel{top:0}[role=region]:focus .editor-post-publish-panel{transform:translateX(0)}}@keyframes editor-post-publish-panel__slide-in-animation{to{transform:translateX(0)}}.editor-post-saved-state{align-items:center;color:#757575;display:flex;overflow:hidden;padding:12px 4px;white-space:nowrap;width:28px}.editor-post-saved-state.is-saved[aria-disabled=true],.editor-post-saved-state.is-saved[aria-disabled=true]:hover,.editor-post-saved-state.is-saving[aria-disabled=true],.editor-post-saved-state.is-saving[aria-disabled=true]:hover{background:#0000;color:#757575}.editor-post-saved-state svg{display:inline-block;flex:0 0 auto;fill:currentColor;margin-right:8px}@media (min-width:600px){.editor-post-saved-state{padding:8px 12px;text-indent:inherit;width:auto}.editor-post-saved-state svg{margin-right:0}}.editor-post-save-draft.has-text.has-icon svg{margin-right:0}.editor-post-schedule__panel-dropdown{width:100%}.editor-post-schedule__dialog .components-popover__content{min-width:320px;padding:16px}.editor-post-status{max-width:100%}.editor-post-status.is-read-only{padding:6px 12px}.editor-post-status .editor-post-status__toggle.editor-post-status__toggle{padding-bottom:4px;padding-top:4px}.editor-change-status__password-fieldset,.editor-change-status__publish-date-wrapper{border-top:1px solid #e0e0e0;padding-top:16px}.editor-change-status__content .components-popover__content{min-width:320px;padding:16px}.editor-change-status__content .editor-change-status__password-legend{margin-bottom:8px;padding:0}.editor-change-status__content p.components-base-control__help:has(.components-checkbox-control__help){margin-top:4px}.editor-post-sticky__checkbox-control{border-top:1px solid #e0e0e0;padding-top:16px}.editor-post-sync-status__value{padding:6px 0 6px 12px}.editor-post-taxonomies__hierarchical-terms-list{margin-left:-6px;margin-top:-6px;max-height:14em;overflow:auto;padding-left:6px;padding-top:6px}.editor-post-taxonomies__hierarchical-terms-choice{margin-bottom:8px}.editor-post-taxonomies__hierarchical-terms-choice:last-child{margin-bottom:4px}.editor-post-taxonomies__hierarchical-terms-subchoices{margin-left:16px;margin-top:8px}.editor-post-taxonomies__flat-term-most-used .editor-post-taxonomies__flat-term-most-used-label{margin-bottom:4px}.editor-post-taxonomies__flat-term-most-used-list{margin:0}.editor-post-taxonomies__flat-term-most-used-list li{display:inline-block;margin-right:8px}.editor-post-template__swap-template-modal{z-index:1000001}.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px;padding-top:2px}@media (min-width:782px){.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{column-count:4}}.editor-post-template__swap-template-modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.editor-post-template__dropdown .components-popover__content{min-width:240px}.editor-post-template__dropdown .components-button.is-pressed,.editor-post-template__dropdown .components-button.is-pressed:hover{background:inherit;color:inherit}@media (min-width:782px){.editor-post-template__create-form{width:320px}}.editor-post-template__classic-theme-dropdown{padding:8px}textarea.editor-post-text-editor{border:1px solid #949494;border-radius:0;box-shadow:none;display:block;font-family:Menlo,Consolas,monaco,monospace;font-size:16px!important;line-height:2.4;margin:0;min-height:200px;overflow:hidden;padding:16px;resize:none;width:100%}@media not (prefers-reduced-motion){textarea.editor-post-text-editor{transition:border .1s ease-out,box-shadow .1s linear}}@media (min-width:600px){textarea.editor-post-text-editor{font-size:15px!important;padding:24px}}textarea.editor-post-text-editor:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);position:relative}textarea.editor-post-text-editor::-webkit-input-placeholder{color:#1e1e1e9e}textarea.editor-post-text-editor::-moz-placeholder{color:#1e1e1e9e}textarea.editor-post-text-editor:-ms-input-placeholder{color:#1e1e1e9e}.editor-post-title.is-raw-text{margin-bottom:24px;margin-top:2px;max-width:none}.editor-post-url__panel-dropdown{width:100%}.editor-post-url__panel-dialog .editor-post-url{margin:8px;min-width:248px}.editor-post-url__front-page-link,.editor-post-url__link{direction:ltr;word-break:break-word}.editor-post-url__front-page-link{padding:6px 0 6px 12px}.editor-post-url__link-slug{font-weight:600}.editor-post-url__input input.components-input-control__input{padding-inline-start:0!important}.editor-post-url__panel-toggle{word-break:break-word}.editor-post-url__intro{margin:0}.editor-post-url__permalink{margin-bottom:0;margin-top:8px}.editor-post-url__permalink-visual-label{display:block}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{border:1px solid #1e1e1e;border-radius:2px;border-radius:50%;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:24px;line-height:normal;margin-right:12px;margin-top:2px;max-width:24px;min-width:24px;padding:6px 8px;position:relative;transition:none;width:24px}@media not (prefers-reduced-motion){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{transition:box-shadow .1s linear}}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{font-size:13px;line-height:normal}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-webkit-input-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-moz-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{height:16px;max-width:16px;min-width:16px;width:16px}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{background-color:#fff;border:4px solid #fff;box-sizing:inherit;height:12px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{height:8px;width:8px}}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color);outline:2px solid #0000}.editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked{background:var(--wp-admin-theme-color);border:none}.editor-post-visibility__fieldset .editor-post-visibility__info{color:#757575;margin-left:36px;margin-top:.5em}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__info{margin-left:28px}}.editor-post-visibility__fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__info{margin-bottom:0}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;margin-left:32px;padding:6px 8px;width:calc(100% - 32px)}@media not (prefers-reduced-motion){.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{transition:box-shadow .1s linear}}@media (min-width:600px){.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{font-size:13px;line-height:normal}}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-webkit-input-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-moz-placeholder{color:#1e1e1e9e}.editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:-ms-input-placeholder{color:#1e1e1e9e}.editor-posts-per-page-dropdown__content .components-popover__content{min-width:320px;padding:16px}.editor-post-trash.components-button{flex-grow:1;justify-content:center}.editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text{padding-left:6px;padding-right:4px}.editor-preview-dropdown__button-external{display:flex;justify-content:space-between;width:100%}.editor-resizable-editor.is-resizable{margin:0 auto;overflow:visible}.editor-resizable-editor__resize-handle{appearance:none;background:none;border:0;border-radius:9999px;bottom:0;cursor:ew-resize;height:100px;margin:auto 0;outline:none;padding:0;position:absolute;top:0;width:12px}.editor-resizable-editor__resize-handle:after{background-color:#75757566;border-radius:9999px;bottom:16px;content:"";left:4px;position:absolute;right:0;top:16px;width:4px}.editor-resizable-editor__resize-handle.is-left{left:-18px}.editor-resizable-editor__resize-handle.is-right{right:-18px}.editor-resizable-editor__resize-handle:active,.editor-resizable-editor__resize-handle:focus,.editor-resizable-editor__resize-handle:hover{opacity:1}.editor-resizable-editor__resize-handle:active:after,.editor-resizable-editor__resize-handle:focus:after,.editor-resizable-editor__resize-handle:hover:after{background-color:var(--wp-admin-theme-color)}.editor-layout__toggle-entities-saved-states-panel,.editor-layout__toggle-publish-panel,.editor-layout__toggle-sidebar-panel{background-color:#fff;border:1px dotted #ddd;bottom:auto;box-sizing:border-box;display:flex;height:auto!important;justify-content:center;left:auto;padding:24px;position:fixed!important;right:0;top:-9999em;width:280px;z-index:100000}.interface-interface-skeleton__actions:focus .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus .editor-layout__toggle-publish-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-publish-panel{bottom:0;top:auto}.editor-start-page-options__modal .editor-start-page-options__modal__actions{background-color:#fff;border-top:1px solid #ddd;bottom:0;height:92px;margin-left:-32px;margin-right:-32px;padding-left:32px;padding-right:32px;position:absolute;width:100%;z-index:1}.editor-start-page-options__modal .block-editor-block-patterns-list{padding-bottom:92px}.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:782px){.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-start-page-options__modal-content .block-editor-block-patterns-list{column-count:4}}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column;margin-bottom:24px}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__container{min-height:100px}.editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__content{width:100%}.editor-start-template-options__modal .editor-start-template-options__modal__actions{background-color:#fff;border-top:1px solid #ddd;bottom:0;height:92px;margin-left:-32px;margin-right:-32px;padding-left:32px;padding-right:32px;position:absolute;width:100%;z-index:1}.editor-start-template-options__modal .block-editor-block-patterns-list{padding-bottom:92px}.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:2;column-gap:24px}@media (min-width:782px){.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:3}}@media (min-width:1280px){.editor-start-template-options__modal-content .block-editor-block-patterns-list{column-count:4}}.editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{break-inside:avoid-column}.editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-patterns-list__item-title{display:none}.components-panel__header.editor-sidebar__panel-tabs{padding-left:0;padding-right:8px}.components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{padding:0}@media (min-width:782px){.components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{display:flex}}.editor-post-summary .components-v-stack:empty{display:none}.editor-site-discussion-dropdown__content .components-popover__content{min-width:320px;padding:16px}.table-of-contents__popover.components-popover .components-popover__content{min-width:380px}.components-popover.table-of-contents__popover{z-index:99998}.table-of-contents__popover .components-popover__content{padding:16px}@media (min-width:600px){.table-of-contents__popover .components-popover__content{max-height:calc(100vh - 120px);overflow-y:auto}}.table-of-contents__popover hr{margin:10px -16px 0}.table-of-contents__wrapper:focus:before{bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";display:block;left:0;pointer-events:none;position:absolute;right:0;top:0}.table-of-contents__counts{display:flex;flex-wrap:wrap;margin:-8px 0 0}.table-of-contents__count{color:#1e1e1e;display:flex;flex-basis:33%;flex-direction:column;font-size:13px;margin-bottom:0;margin-top:8px;padding-right:8px}.table-of-contents__count:nth-child(4n){padding-right:0}.table-of-contents__number,.table-of-contents__popover .word-count{color:#1e1e1e;font-size:21px;font-weight:400;line-height:30px}.table-of-contents__title{display:block;font-size:15px;font-weight:600;margin-top:20px}.editor-text-editor{background-color:#fff;flex-grow:1;position:relative;width:100%}.editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){border:1px solid #949494;border-radius:0;font-family:Menlo,Consolas,monaco,monospace;font-size:2.5em;font-weight:400;line-height:1.4;max-width:none;padding:16px}@media (min-width:600px){.editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){padding:24px}}.editor-text-editor .editor-post-title.is-raw-text textarea:focus,.editor-text-editor .editor-post-title:not(.is-raw-text):focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.editor-text-editor__body{margin-left:auto;margin-right:auto;max-width:1080px;padding:0 12px 12px;width:100%}@media (min-width:960px){.editor-text-editor__body{padding:0 24px 24px}}.editor-text-editor__toolbar{background:#fffc;display:flex;left:0;padding:4px 12px;position:sticky;right:0;top:0;z-index:1}@media (min-width:600px){.editor-text-editor__toolbar{padding:12px}}@media (min-width:960px){.editor-text-editor__toolbar{padding:12px 24px}}.editor-text-editor__toolbar h2{color:#1e1e1e;font-size:13px;line-height:40px;margin:0 auto 0 0}.editor-visual-editor{align-items:center;background-color:#ddd;display:flex;position:relative}.editor-visual-editor iframe[name=editor-canvas]{background-color:initial}.editor-visual-editor.is-resizable{max-height:100%}.editor-visual-editor.has-padding{padding:24px 24px 0}.editor-visual-editor.is-iframed{overflow:hidden}.editor-visual-editor .components-button{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:6px 12px}.editor-visual-editor .components-button.has-icon,.editor-visual-editor .components-button.is-tertiary{padding:6px}.editor-fields-content-preview{border-radius:4px;display:flex;flex-direction:column;height:100%}.dataviews-view-table .editor-fields-content-preview{flex-grow:0;width:96px}.editor-fields-content-preview .block-editor-block-preview__container,.editor-fields-content-preview .editor-fields-content-preview__empty{margin-bottom:auto;margin-top:auto}.editor-fields-content-preview__empty{text-align:center}@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .interface-complementary-area-header{ background:#fff; gap:4px; padding-left:8px; } .interface-complementary-area-header .interface-complementary-area-header__title{ margin:0 0 0 auto; } .interface-complementary-area{ background:#fff; color:#1e1e1e; height:100%; overflow:auto; } @media (min-width:600px){ .interface-complementary-area{ -webkit-overflow-scrolling:touch; } } @media (min-width:782px){ .interface-complementary-area{ width:280px; } } .interface-complementary-area .components-panel{ border:none; position:relative; z-index:0; } .interface-complementary-area .components-panel__header{ position:sticky; top:0; z-index:1; } .interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{ top:0; } .interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){ margin-top:0; } .interface-complementary-area h2{ color:#1e1e1e; font-size:13px; font-weight:500; margin-bottom:1.5em; } .interface-complementary-area h3{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .interface-complementary-area hr{ border-bottom:1px solid #f0f0f0; border-top:none; margin:1.5em 0; } .interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{ box-shadow:none; margin-bottom:1.5em; } .interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{ margin-bottom:0; } .interface-complementary-area .block-editor-skip-to-selected-block:focus{ bottom:10px; left:10px; right:auto; top:auto; } .interface-complementary-area__fill{ height:100%; } @media (min-width:782px){ body.js.is-fullscreen-mode{ height:calc(100% + 32px); margin-top:-32px; } body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{ display:none; } body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{ margin-right:0; } } html.interface-interface-skeleton__html-container{ position:fixed; width:100%; } @media (min-width:782px){ html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){ position:static; width:auto; } } .interface-interface-skeleton{ bottom:0; display:flex; flex-direction:row; height:auto; left:0; max-height:100%; position:fixed; top:46px; } @media (min-width:783px){ .interface-interface-skeleton{ top:32px; } .is-fullscreen-mode .interface-interface-skeleton{ top:0; } } .interface-interface-skeleton__editor{ display:flex; flex:0 1 100%; flex-direction:column; overflow:hidden; } .interface-interface-skeleton{ right:0; } @media (min-width:783px){ .interface-interface-skeleton{ right:160px; } } @media (min-width:783px){ .auto-fold .interface-interface-skeleton{ right:36px; } } @media (min-width:961px){ .auto-fold .interface-interface-skeleton{ right:160px; } } .folded .interface-interface-skeleton{ right:0; } @media (min-width:783px){ .folded .interface-interface-skeleton{ right:36px; } } body.is-fullscreen-mode .interface-interface-skeleton{ right:0 !important; } .interface-interface-skeleton__body{ display:flex; flex-grow:1; overflow:auto; overscroll-behavior-y:none; position:relative; } @media (min-width:782px){ .has-footer .interface-interface-skeleton__body{ padding-bottom:25px; } } .interface-interface-skeleton__content{ display:flex; flex-direction:column; flex-grow:1; overflow:auto; z-index:20; } @media (min-width:782px){ .interface-interface-skeleton__content{ z-index:auto; } } .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ background:#fff; bottom:0; color:#1e1e1e; flex-shrink:0; position:absolute; right:0; top:0; width:auto; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ position:relative !important; } } .interface-interface-skeleton__sidebar{ border-top:1px solid #e0e0e0; overflow:hidden; } @media (min-width:782px){ .interface-interface-skeleton__sidebar{ box-shadow:1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__secondary-sidebar{ border-top:1px solid #e0e0e0; left:0; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar{ box-shadow:-1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); color:#1e1e1e; flex-shrink:0; height:auto; outline:1px solid #0000; z-index:30; } .interface-interface-skeleton__footer{ background-color:#fff; border-top:1px solid #e0e0e0; bottom:0; color:#1e1e1e; display:none; flex-shrink:0; height:auto; position:absolute; right:0; width:100%; z-index:90; } @media (min-width:782px){ .interface-interface-skeleton__footer{ display:flex; } } .interface-interface-skeleton__footer .block-editor-block-breadcrumb{ align-items:center; background:#fff; display:flex; font-size:13px; height:24px; padding:0 18px; z-index:30; } .interface-interface-skeleton__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:0; position:fixed !important; right:auto; top:-9999em; width:100vw; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__actions{ width:280px; } } .interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{ bottom:0; top:auto; } .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:46px; } @media (min-width:782px){ .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ border-right:1px solid #ddd; top:32px; } .is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:0; } } .interface-pinned-items{ display:flex; gap:8px; } .interface-pinned-items .components-button{ display:none; margin:0; } .interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{ display:flex; } .interface-pinned-items .components-button svg{ max-height:24px; max-width:24px; } @media (min-width:600px){ .interface-pinned-items .components-button{ display:flex; } } .editor-autocompleters__user .editor-autocompleters__no-avatar:before{ content:"\f110"; font:normal 20px/1 dashicons; margin-left:5px; vertical-align:middle; } .editor-autocompleters__user .editor-autocompleters__user-avatar{ flex-grow:0; flex-shrink:0; height:24px; margin-left:8px; max-width:none; width:24px; } .editor-autocompleters__user .editor-autocompleters__user-name{ flex-grow:1; flex-shrink:0; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .editor-autocompleters__user .editor-autocompleters__user-slug{ color:#757575; flex-grow:0; flex-shrink:0; margin-right:8px; max-width:100px; overflow:none; text-overflow:ellipsis; white-space:nowrap; } .editor-autocompleters__user:hover .editor-autocompleters__user-slug{ color:var(--wp-admin-theme-color); } .interface-interface-skeleton__sidebar:has(.editor-collab-sidebar){ box-shadow:none; } .interface-interface-skeleton__sidebar:has(.editor-collab-sidebar) .interface-complementary-area-header{ display:none; } .editor-collab-sidebar{ height:100%; } .editor-collab-sidebar-panel{ height:100%; padding:16px; } .editor-collab-sidebar-panel__thread{ background-color:#f0f0f0; border:1.5px solid #ddd; border-radius:8px; margin-bottom:16px; padding:16px; position:relative; } .editor-collab-sidebar-panel__active-thread{ border:1.5px solid #3858e9; } .editor-collab-sidebar-panel__focus-thread{ background-color:#fff; border:1.5px solid #3858e9; box-shadow:0 5.5px 7.8px -.3px rgba(0,0,0,.102); } .editor-collab-sidebar-panel__comment-field{ flex:1; } .editor-collab-sidebar-panel__child-thread{ margin-top:15px; } .editor-collab-sidebar-panel__user-name{ text-transform:capitalize; } .editor-collab-sidebar-panel__user-name,.editor-collab-sidebar-panel__user-time{ color:#757575; font-size:12px; font-weight:400; line-height:16px; text-align:right; } .editor-collab-sidebar-panel__user-comment{ color:#1e1e1e; font-size:13px; font-weight:400; line-height:20px; text-align:right; } .editor-collab-sidebar-panel__user-comment p{ margin-bottom:0; } .editor-collab-sidebar-panel__user-avatar{ border-radius:50%; flex-shrink:0; } .editor-collab-sidebar-panel__thread-overlay{ background-color:#000000b3; border-radius:8px; color:#fff; height:100%; padding:15px; position:absolute; right:0; text-align:center; top:0; width:100%; z-index:1; } .editor-collab-sidebar-panel__thread-overlay p{ margin-bottom:15px; } .editor-collab-sidebar-panel__thread-overlay button{ color:#fff; padding:4px 10px; } .editor-collab-sidebar-panel__comment-status{ margin-right:auto; } .editor-collab-sidebar-panel__comment-status button.has-icon:not(.has-text){ flex-shrink:0; height:24px; min-width:24px; padding:0; width:24px; } .editor-collab-sidebar-panel__comment-dropdown-menu{ flex-shrink:0; } .editor-collab-sidebar-panel__comment-dropdown-menu button.has-icon{ height:24px; min-width:24px; padding:0; width:24px; } .editor-collab-sidebar-panel__show-more-reply{ font-style:italic; font-weight:500; padding:0; } .editor-collapsible-block-toolbar{ align-items:center; display:flex; height:60px; overflow:hidden; } .editor-collapsible-block-toolbar .block-editor-block-contextual-toolbar{ background:#0000; border-bottom:0; height:100%; } .editor-collapsible-block-toolbar .block-editor-block-toolbar{ height:100%; padding-top:15px; } .editor-collapsible-block-toolbar .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){ height:32px; } .editor-collapsible-block-toolbar:after{ background-color:#ddd; content:""; height:24px; margin-left:7px; width:1px; } .editor-collapsible-block-toolbar .components-toolbar,.editor-collapsible-block-toolbar .components-toolbar-group{ border-left:none; position:relative; } .editor-collapsible-block-toolbar .components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar:after{ background-color:#ddd; content:""; height:24px; left:-1px; position:absolute; top:4px; width:1px; } .editor-collapsible-block-toolbar .components-toolbar .components-toolbar-group.components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{ display:none; } .editor-collapsible-block-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{ height:32px; overflow:visible; } @media (min-width:600px){ .editor-collapsible-block-toolbar .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ height:40px; position:relative; top:-5px; } } .editor-collapsible-block-toolbar.is-collapsed{ display:none; } .editor-content-only-settings-menu__description{ min-width:235px; padding:8px; } .editor-blog-title-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-document-bar{ align-items:center; background:#f0f0f0; border-radius:4px; display:flex; height:32px; justify-content:space-between; min-width:0; width:min(100%, 450px); } .editor-document-bar:hover{ background-color:#e0e0e0; } .editor-document-bar .components-button{ border-radius:4px; } @media not (prefers-reduced-motion){ .editor-document-bar .components-button{ transition:all .1s ease-out; } } .editor-document-bar .components-button:hover{ background:#e0e0e0; } @media screen and (min-width:782px) and (max-width:960px){ .editor-document-bar.has-back-button .editor-document-bar__post-type-label{ display:none; } } .editor-document-bar__command{ color:var(--wp-block-synced-color); flex-grow:1; overflow:hidden; } .editor-document-bar__title{ color:#1e1e1e; margin:0 auto; max-width:70%; overflow:hidden; } @media (min-width:782px){ .editor-document-bar__title{ padding-right:24px; } } .editor-document-bar__title h1{ align-items:center; display:flex; font-weight:400; justify-content:center; overflow:hidden; white-space:nowrap; } .editor-document-bar__post-title{ color:currentColor; flex:1; overflow:hidden; text-overflow:ellipsis; } .editor-document-bar__post-type-label{ color:#2f2f2f; flex:0; padding-right:4px; } @media screen and (max-width:600px){ .editor-document-bar__post-type-label{ display:none; } } .editor-document-bar__shortcut{ color:#2f2f2f; display:none; min-width:24px; } @media (min-width:782px){ .editor-document-bar__shortcut{ display:initial; } } .editor-document-bar__back.components-button.has-icon.has-text{ color:#757575; flex-shrink:0; gap:0; min-width:36px; position:absolute; z-index:1; } .editor-document-bar__back.components-button.has-icon.has-text:hover{ background-color:initial; color:#1e1e1e; } .editor-document-bar__icon-layout.editor-document-bar__icon-layout{ display:none; margin-right:12px; pointer-events:none; position:absolute; } .editor-document-bar__icon-layout.editor-document-bar__icon-layout svg{ fill:#949494; } @media (min-width:600px){ .editor-document-bar__icon-layout.editor-document-bar__icon-layout{ display:flex; } } .document-outline{ margin:20px 0; } .document-outline ul{ margin:0; padding:0; } .document-outline__item{ display:flex; margin:4px 0; } .document-outline__item a{ text-decoration:none; } .document-outline__item .document-outline__emdash:before{ color:#ddd; margin-left:4px; } .document-outline__item.is-h2 .document-outline__emdash:before{ content:"—"; } .document-outline__item.is-h3 .document-outline__emdash:before{ content:"——"; } .document-outline__item.is-h4 .document-outline__emdash:before{ content:"———"; } .document-outline__item.is-h5 .document-outline__emdash:before{ content:"————"; } .document-outline__item.is-h6 .document-outline__emdash:before{ content:"—————"; } .document-outline__button{ align-items:flex-start; background:none; border:none; border-radius:2px; color:#1e1e1e; cursor:pointer; display:flex; margin:0 -1px 0 0; padding:2px 1px 2px 5px; text-align:right; } .document-outline__button:disabled,.document-outline__button[aria-disabled=true]{ color:#757575; cursor:default; } .document-outline__button:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .document-outline__level{ background:#ddd; border-radius:3px; color:#1e1e1e; font-size:13px; margin-left:4px; padding:1px 6px; } .is-invalid .document-outline__level{ background:#f0b849; } .document-outline__item-content{ padding:1px 0; } .editor-document-outline.has-no-headings{ color:#757575; text-align:center; } .editor-document-outline.has-no-headings>svg{ margin-top:28px; } .editor-document-outline.has-no-headings>p{ padding-left:32px; padding-right:32px; } .editor-document-tools{ align-items:center; display:inline-flex; } .editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{ display:none; } @media (min-width:782px){ .editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{ display:inline-flex; } } .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle{ display:inline-flex; } @media not (prefers-reduced-motion){ .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.is-pressed svg{ transform:rotate(-45deg); } .editor-document-tools .block-editor-list-view{ display:none; } @media (min-width:600px){ .editor-document-tools .block-editor-list-view{ display:flex; } } .editor-document-tools .editor-document-tools__left>.components-button.has-icon,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon{ height:32px; min-width:32px; padding:4px; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon.is-pressed,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon.is-pressed{ background:#1e1e1e; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon:focus:not(:disabled),.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 1px #fff; outline:1px solid #0000; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon:before,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:before{ display:none; } .editor-document-tools__left{ align-items:center; display:inline-flex; gap:8px; } .editor-document-tools__left:not(:last-child){ margin-inline-end:8px; } .show-icon-labels .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.has-icon{ padding:0 8px; width:auto; } .show-icon-labels .editor-document-tools__left>*+*{ margin-right:8px; } .editor-editor-interface .entities-saved-states__panel-header{ height:61px; } .editor-editor-interface .interface-interface-skeleton__content{ isolation:isolate; } .editor-visual-editor{ flex:1 0 auto; } .components-editor-notices__dismissible,.components-editor-notices__pinned{ color:#1e1e1e; left:0; position:relative; right:0; top:0; } .components-editor-notices__dismissible .components-notice,.components-editor-notices__pinned .components-notice{ border-bottom:1px solid #0003; box-sizing:border-box; min-height:60px; padding:0 12px; } .components-editor-notices__dismissible .components-notice .components-notice__dismiss,.components-editor-notices__pinned .components-notice .components-notice__dismiss{ margin-top:12px; } .entities-saved-states__panel-header{ background:#fff; border-bottom:1px solid #ddd; box-sizing:border-box; height:60px; padding-left:16px; padding-right:16px; } .entities-saved-states__text-prompt{ padding:16px 16px 4px; } .entities-saved-states__text-prompt .entities-saved-states__text-prompt--header{ display:block; margin-bottom:12px; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt{ padding:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body{ border:0; padding-left:0; padding-right:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2{ margin-bottom:0; margin-left:-16px; margin-right:-16px; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2 button{ font-size:11px; text-transform:uppercase; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--header-wrapper{ display:none; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--changes-count{ margin-bottom:8px; margin-top:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-footer{ margin-top:16px; } .entities-saved-states__change-control{ flex:1; } .entities-saved-states__changes{ font-size:13px; list-style:disc; margin:4px 24px 0 16px; } .entities-saved-states__changes li{ margin-bottom:4px; } .editor-error-boundary{ background-color:#fff; border:1px solid #1e1e1e; border-radius:2px; box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; margin:60px auto auto; max-width:780px; padding:1em; } .editor-header{ align-items:center; background:#fff; display:grid; grid-auto-flow:row; grid-template:auto/60px minmax(0, max-content) minmax(min-content, 1fr) 60px; height:60px; justify-content:space-between; max-width:100vw; } .editor-header:has(>.editor-header__center){ grid-template:auto/60px min-content 1fr min-content 60px; } @media (min-width:782px){ .editor-header:has(>.editor-header__center){ grid-template:auto/60px minmax(min-content, 2fr) 2.5fr minmax(min-content, 2fr) 60px; } } @media (min-width:480px){ .editor-header{ gap:16px; } } @media (min-width:280px){ .editor-header{ flex-wrap:nowrap; } } .editor-header__toolbar{ align-items:center; clip-path:inset(-2px); display:flex; grid-column:1 / 3; min-width:0; } .editor-header__toolbar>:first-child{ margin-inline:16px 0; } .editor-header__back-button+.editor-header__toolbar{ grid-column:2 / 3; } @media (min-width:480px){ .editor-header__back-button+.editor-header__toolbar>:first-child{ margin-inline:0; } .editor-header__toolbar{ clip-path:none; } } .editor-header__toolbar .table-of-contents{ display:none; } @media (min-width:600px){ .editor-header__toolbar .table-of-contents{ display:block; } } .editor-header__toolbar .editor-collapsible-block-toolbar,.editor-header__toolbar .editor-collapsible-block-toolbar.is-collapsed~.editor-collapsible-block-toolbar__toggle{ margin-inline:8px 0; } .editor-header__center{ align-items:center; clip-path:inset(-2px); display:flex; grid-column:3 / 4; justify-content:center; min-width:0; } @media (max-width:479px){ .editor-header__center>:first-child{ margin-inline-start:8px; } .editor-header__center>:last-child{ margin-inline-end:8px; } } .editor-header__settings{ align-items:center; display:inline-flex; flex-wrap:nowrap; gap:8px; grid-column:3 / -1; justify-self:end; padding-left:4px; } .editor-header:has(>.editor-header__center) .editor-header__settings{ grid-column:4 / -1; } @media (min-width:600px){ .editor-header__settings{ padding-left:8px; } } .show-icon-labels .editor-header .components-button.has-icon,.show-icon-labels.interface-pinned-items .components-button.has-icon{ width:auto; } .show-icon-labels .editor-header .components-button.has-icon svg,.show-icon-labels.interface-pinned-items .components-button.has-icon svg{ display:none; } .show-icon-labels .editor-header .components-button.has-icon:after,.show-icon-labels.interface-pinned-items .components-button.has-icon:after{ content:attr(aria-label); white-space:nowrap; } .show-icon-labels .editor-header .components-button.has-icon[aria-disabled=true],.show-icon-labels.interface-pinned-items .components-button.has-icon[aria-disabled=true]{ background-color:initial; } .show-icon-labels .editor-header .is-tertiary:active,.show-icon-labels.interface-pinned-items .is-tertiary:active{ background-color:initial; box-shadow:0 0 0 1.5px var(--wp-admin-theme-color); } .show-icon-labels .editor-header .components-button.has-icon.button-toggle svg,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle svg{ display:block; } .show-icon-labels .editor-header .components-button.has-icon.button-toggle:after,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle:after{ content:none; } .show-icon-labels .editor-header .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon,.show-icon-labels.interface-pinned-items .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon{ display:block; } .show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{ padding-left:8px; padding-right:8px; } @media (min-width:600px){ .show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{ padding-left:12px; padding-right:12px; } } .show-icon-labels .editor-header .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels .editor-header .editor-post-saved-state.editor-post-saved-state:after,.show-icon-labels.interface-pinned-items .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels.interface-pinned-items .editor-post-saved-state.editor-post-saved-state:after{ content:none; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover{ border-right:none; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover:before{ background-color:#ddd; content:""; height:24px; margin-right:8px; margin-top:4px; width:1px; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover .block-editor-block-mover__move-button-container:before{ background:#ddd; right:calc(50% + 1px); width:calc(100% - 24px); } .show-icon-labels.interface-pinned-items{ border-bottom:1px solid #ccc; display:block; margin:0 -12px; padding:6px 12px 12px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon{ justify-content:flex-start; margin:0; padding:6px 8px 6px 6px; width:14.625rem; } .show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=true] svg{ display:block; max-width:24px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=false]{ padding-right:40px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon svg{ margin-left:8px; } @media (min-width:480px){ .editor-header__post-preview-button{ display:none; } } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header{ border-bottom:none; } .editor-editor-interface.is-distraction-free .editor-header{ background-color:#fff; width:100%; } @media (min-width:782px){ .editor-editor-interface.is-distraction-free .editor-header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); position:absolute; } } .editor-editor-interface.is-distraction-free .editor-header>.edit-post-header__settings>.edit-post-header__post-preview-button{ visibility:hidden; } .editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-preview-dropdown,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-zoom-out-toggle,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.interface-pinned-items,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__toolbar .editor-document-tools__document-overview-toggle{ display:none; } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within{ opacity:1 !important; } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within div{ transform:translateX(0) translateZ(0) !important; } .editor-editor-interface.is-distraction-free .components-editor-notices__dismissible{ position:absolute; z-index:35; } .components-popover.more-menu-dropdown__content{ z-index:99998; } .editor-inserter-sidebar{ box-sizing:border-box; display:flex; flex-direction:column; height:100%; } .editor-inserter-sidebar *,.editor-inserter-sidebar :after,.editor-inserter-sidebar :before{ box-sizing:inherit; } .editor-inserter-sidebar__content{ height:100%; } .editor-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .editor-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .editor-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .editor-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .editor-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .editor-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 1rem 0 0; text-align:left; } .editor-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .editor-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .editor-keyboard-shortcut-help-modal__shortcut-key-combination+.editor-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .editor-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .editor-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 .2rem 0 0; } .editor-list-view-sidebar{ height:100%; } @media (min-width:782px){ .editor-list-view-sidebar{ width:350px; } } .editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{ height:100%; overflow:auto; padding:4px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:auto; scrollbar-width:thin; will-change:transform; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar{ height:12px; width:12px; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-track,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-track{ background-color:initial; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .editor-list-view-sidebar__list-view-container>.document-outline:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:hover::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .editor-list-view-sidebar__list-view-container>.document-outline:focus,.editor-list-view-sidebar__list-view-container>.document-outline:focus-within,.editor-list-view-sidebar__list-view-container>.document-outline:hover,.editor-list-view-sidebar__list-view-panel-content:focus,.editor-list-view-sidebar__list-view-panel-content:focus-within,.editor-list-view-sidebar__list-view-panel-content:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{ scrollbar-color:#949494 #0000; } } .editor-list-view-sidebar__list-view-container{ display:flex; flex-direction:column; height:100%; } .editor-list-view-sidebar__tab-panel{ height:100%; } .editor-list-view-sidebar__outline{ border-bottom:1px solid #ddd; display:flex; flex-direction:column; gap:8px; padding:16px; } .editor-list-view-sidebar__outline>div>span:first-child{ display:inline-block; width:90px; } .editor-list-view-sidebar__outline>div>span{ color:#757575; font-size:12px; line-height:1.4; } .editor-post-order__panel,.editor-post-parent__panel{ padding-top:8px; } .editor-post-order__panel .editor-post-panel__row-control>div,.editor-post-parent__panel .editor-post-panel__row-control>div{ width:100%; } .editor-post-order__panel-dialog .editor-post-order,.editor-post-order__panel-dialog .editor-post-parent,.editor-post-parent__panel-dialog .editor-post-order,.editor-post-parent__panel-dialog .editor-post-parent{ margin:8px; } .editor-post-order__panel-dialog .components-popover__content,.editor-post-parent__panel-dialog .components-popover__content{ min-width:320px; } .editor-post-author__panel{ padding-top:8px; } .editor-post-author__panel .editor-post-panel__row-control>div{ width:100%; } .editor-post-author__panel-dialog .editor-post-author{ margin:8px; min-width:248px; } .editor-action-modal{ z-index:1000001; } .editor-post-card-panel__content{ flex-grow:1; } .editor-post-card-panel__title{ width:100%; } .editor-post-card-panel__title.editor-post-card-panel__title{ align-items:center; column-gap:8px; display:flex; flex-wrap:wrap; font-family:-apple-system,"system-ui",Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:500; line-height:20px; margin:0; row-gap:4px; word-break:break-word; } .editor-post-card-panel__icon{ flex:0 0 24px; height:24px; width:24px; } .editor-post-card-panel__header{ display:flex; justify-content:space-between; } .editor-post-card-panel.has-description .editor-post-card-panel__header{ margin-bottom:8px; } .editor-post-card-panel .editor-post-card-panel__title-name{ padding:2px 0; } .editor-post-card-panel .editor-post-card-panel__description,.editor-post-content-information{ color:#757575; } .editor-post-content-information .components-text{ color:inherit; } .editor-post-discussion__panel-dialog .editor-post-discussion{ margin:8px; min-width:248px; } .editor-post-discussion__panel-toggle .components-text{ color:inherit; } .editor-post-discussion__panel-dialog .components-popover__content{ min-width:320px; } .editor-post-excerpt__textarea{ margin-bottom:10px; width:100%; } .editor-post-excerpt__dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-post-featured-image{ padding:0; } .editor-post-featured-image .components-spinner{ margin-right:-9px; margin-top:-9px; position:absolute; right:50%; top:50%; } .editor-post-featured-image__container{ position:relative; } .editor-post-featured-image__container:focus .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:focus-within .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:hover .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image){ opacity:1; } .editor-post-featured-image__container .editor-post-featured-image__actions.editor-post-featured-image__actions-missing-image{ margin-top:16px; opacity:1; } .editor-post-featured-image__container .components-drop-zone__content{ border-radius:2px; } .editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner{ align-items:center; display:flex; gap:8px; } .editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner .components-drop-zone__content-icon{ margin:0; } .editor-post-featured-image__preview,.editor-post-featured-image__toggle{ box-shadow:0 0 0 0 var(--wp-admin-theme-color); display:flex; justify-content:center; min-height:40px; outline-offset:-1px; overflow:hidden; padding:0; width:100%; } .editor-post-featured-image__preview{ height:auto !important; outline:1px solid #0000001a; } .editor-post-featured-image__preview .editor-post-featured-image__preview-image{ aspect-ratio:2/1; object-fit:cover; object-position:50% 50%; width:100%; } .editor-post-featured-image__toggle{ box-shadow:inset 0 0 0 1px #ccc; } .editor-post-featured-image__toggle:focus:not(:disabled){ box-shadow:0 0 0 currentColor inset, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){ bottom:0; opacity:0; padding:8px; position:absolute; } @media not (prefers-reduced-motion){ .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){ transition:opacity 50ms ease-out; } } .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image) .editor-post-featured-image__action{ -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background:#ffffffbf; } .editor-post-featured-image__actions .editor-post-featured-image__action{ flex-grow:1; justify-content:center; } [class].editor-post-format__suggestion{ margin:4px 0 0; } .editor-post-format__dialog .editor-post-format__dialog-content{ margin:8px; min-width:248px; } .editor-post-last-edited-panel{ color:#757575; } .editor-post-last-edited-panel .components-text{ color:inherit; } .editor-post-last-revision__title{ font-weight:500; width:100%; } .editor-post-last-revision__title.components-button.has-icon{ height:100%; justify-content:space-between; } .editor-post-last-revision__title.components-button.has-icon:active,.editor-post-last-revision__title.components-button.has-icon:hover{ background:#f0f0f0; } .editor-post-last-revision__title.components-button.has-icon:focus{ border-radius:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-panel__body.is-opened.editor-post-last-revision__panel{ height:48px; padding:0; } .components-panel__body.is-opened.editor-post-last-revision__panel .editor-post-last-revision__title.components-button.components-button{ padding:16px; } .editor-private-post-last-revision__button{ display:inline-block; } .editor-post-locked-modal__buttons{ margin-top:24px; } .editor-post-locked-modal__avatar{ border-radius:50%; margin-top:16px; min-width:auto !important; } .editor-post-panel__row{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .editor-post-panel__row-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .editor-post-panel__row-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .editor-post-panel__row-control .components-button{ height:auto; max-width:100%; min-height:32px; text-align:right; text-wrap:balance; text-wrap:pretty; white-space:normal; } .editor-post-panel__row-control .components-dropdown{ max-width:100%; } .editor-post-panel__section{ padding:16px; } .editor-post-publish-panel__content{ min-height:calc(100% - 144px); } .editor-post-publish-panel__content>.components-spinner{ display:block; margin:100px auto 0; } .editor-post-publish-panel__header{ align-content:space-between; align-items:center; background:#fff; border-bottom:1px solid #ddd; display:flex; height:61px; padding-left:16px; padding-right:16px; } .editor-post-publish-panel__header .components-button{ justify-content:center; width:100%; } .editor-post-publish-panel__header .has-icon{ margin-right:auto; width:auto; } .components-site-card{ align-items:center; display:flex; margin:16px 0; } .components-site-icon{ border:none; border-radius:2px; flex-shrink:0; height:36px; margin-left:12px; width:36px; } .components-site-name{ display:block; font-size:14px; } .components-site-home{ color:#757575; display:block; font-size:12px; word-break:break-word; } .editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{ flex:1; } @media (min-width:480px){ .editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{ max-width:160px; } } .editor-post-publish-panel__header-publish-button{ justify-content:center; padding-right:4px; } .editor-post-publish-panel__header-cancel-button{ padding-left:4px; } .editor-post-publish-panel__header-published{ flex-grow:1; } .editor-post-publish-panel__footer{ padding:16px; } .components-button.editor-post-publish-panel__toggle.is-primary{ align-items:center; display:inline-flex; } .components-button.editor-post-publish-panel__toggle.is-primary.is-busy .dashicon{ display:none; } .components-button.editor-post-publish-panel__toggle.is-primary .dashicon{ margin-left:-4px; } .editor-post-publish-panel__link{ font-weight:400; padding-right:4px; } .editor-post-publish-panel__prepublish{ padding:16px; } .editor-post-publish-panel__prepublish strong{ color:#1e1e1e; } .editor-post-publish-panel__prepublish .components-panel__body{ background:#fff; margin-left:-16px; margin-right:-16px; } .editor-post-publish-panel__prepublish .editor-post-visibility__dialog-legend{ display:none; } .editor-post-publish-panel__prepublish .components-panel__body-title .components-button{ align-items:flex-start; text-wrap:balance; text-wrap:pretty; } .post-publish-panel__postpublish .components-panel__body{ border-bottom:1px solid #e0e0e0; border-top:none; } .post-publish-panel__postpublish-buttons{ align-content:space-between; display:flex; flex-wrap:wrap; gap:16px; } .post-publish-panel__postpublish-buttons .components-button{ flex:1; justify-content:center; } .post-publish-panel__postpublish-buttons .components-clipboard-button{ width:100%; } .post-publish-panel__postpublish-post-address-container{ align-items:flex-end; display:flex; margin-bottom:16px; } .post-publish-panel__postpublish-post-address-container .post-publish-panel__postpublish-post-address{ flex:1; } .post-publish-panel__postpublish-post-address-container input[readonly]{ background:#f0f0f0; border-color:#ccc; height:36px; overflow:hidden; padding:12px; text-overflow:ellipsis; } .post-publish-panel__postpublish-post-address__copy-button-wrap{ flex-shrink:0; margin-right:16px; } .post-publish-panel__postpublish-header{ font-weight:500; } .post-publish-panel__postpublish-subheader{ margin:0 0 8px; } .post-publish-panel__tip{ color:#f0b849; } @media screen and (max-width:782px){ .post-publish-panel__postpublish-post-address__button-wrap .components-button{ height:40px; } } .editor-post-publish-panel{ background:#fff; bottom:0; left:0; overflow:auto; position:fixed; right:0; top:46px; z-index:100001; } @media (min-width:782px){ .editor-post-publish-panel{ border-right:1px solid #ddd; right:auto; top:32px; width:281px; z-index:99998; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .editor-post-publish-panel{ animation:editor-post-publish-panel__slide-in-animation .1s forwards; transform:translateX(-100%); } } @media (min-width:782px){ body.is-fullscreen-mode .editor-post-publish-panel{ top:0; } [role=region]:focus .editor-post-publish-panel{ transform:translateX(0); } } @keyframes editor-post-publish-panel__slide-in-animation{ to{ transform:translateX(0); } } .editor-post-saved-state{ align-items:center; color:#757575; display:flex; overflow:hidden; padding:12px 4px; white-space:nowrap; width:28px; } .editor-post-saved-state.is-saved[aria-disabled=true],.editor-post-saved-state.is-saved[aria-disabled=true]:hover,.editor-post-saved-state.is-saving[aria-disabled=true],.editor-post-saved-state.is-saving[aria-disabled=true]:hover{ background:#0000; color:#757575; } .editor-post-saved-state svg{ display:inline-block; flex:0 0 auto; fill:currentColor; margin-left:8px; } @media (min-width:600px){ .editor-post-saved-state{ padding:8px 12px; text-indent:inherit; width:auto; } .editor-post-saved-state svg{ margin-left:0; } } .editor-post-save-draft.has-text.has-icon svg{ margin-left:0; } .editor-post-schedule__panel-dropdown{ width:100%; } .editor-post-schedule__dialog .components-popover__content{ min-width:320px; padding:16px; } .editor-post-status{ max-width:100%; } .editor-post-status.is-read-only{ padding:6px 12px; } .editor-post-status .editor-post-status__toggle.editor-post-status__toggle{ padding-bottom:4px; padding-top:4px; } .editor-change-status__password-fieldset,.editor-change-status__publish-date-wrapper{ border-top:1px solid #e0e0e0; padding-top:16px; } .editor-change-status__content .components-popover__content{ min-width:320px; padding:16px; } .editor-change-status__content .editor-change-status__password-legend{ margin-bottom:8px; padding:0; } .editor-change-status__content p.components-base-control__help:has(.components-checkbox-control__help){ margin-top:4px; } .editor-post-sticky__checkbox-control{ border-top:1px solid #e0e0e0; padding-top:16px; } .editor-post-sync-status__value{ padding:6px 12px 6px 0; } .editor-post-taxonomies__hierarchical-terms-list{ margin-right:-6px; margin-top:-6px; max-height:14em; overflow:auto; padding-right:6px; padding-top:6px; } .editor-post-taxonomies__hierarchical-terms-choice{ margin-bottom:8px; } .editor-post-taxonomies__hierarchical-terms-choice:last-child{ margin-bottom:4px; } .editor-post-taxonomies__hierarchical-terms-subchoices{ margin-right:16px; margin-top:8px; } .editor-post-taxonomies__flat-term-most-used .editor-post-taxonomies__flat-term-most-used-label{ margin-bottom:4px; } .editor-post-taxonomies__flat-term-most-used-list{ margin:0; } .editor-post-taxonomies__flat-term-most-used-list li{ display:inline-block; margin-left:8px; } .editor-post-template__swap-template-modal{ z-index:1000001; } .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; padding-top:2px; } @media (min-width:782px){ .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .editor-post-template__dropdown .components-popover__content{ min-width:240px; } .editor-post-template__dropdown .components-button.is-pressed,.editor-post-template__dropdown .components-button.is-pressed:hover{ background:inherit; color:inherit; } @media (min-width:782px){ .editor-post-template__create-form{ width:320px; } } .editor-post-template__classic-theme-dropdown{ padding:8px; } textarea.editor-post-text-editor{ border:1px solid #949494; border-radius:0; box-shadow:none; display:block; font-family:Menlo,Consolas,monaco,monospace; font-size:16px !important; line-height:2.4; margin:0; min-height:200px; overflow:hidden; padding:16px; resize:none; width:100%; } @media not (prefers-reduced-motion){ textarea.editor-post-text-editor{ transition:border .1s ease-out,box-shadow .1s linear; } } @media (min-width:600px){ textarea.editor-post-text-editor{ font-size:15px !important; padding:24px; } } textarea.editor-post-text-editor:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); position:relative; } textarea.editor-post-text-editor::-webkit-input-placeholder{ color:#1e1e1e9e; } textarea.editor-post-text-editor::-moz-placeholder{ color:#1e1e1e9e; } textarea.editor-post-text-editor:-ms-input-placeholder{ color:#1e1e1e9e; } .editor-post-title.is-raw-text{ margin-bottom:24px; margin-top:2px; max-width:none; } .editor-post-url__panel-dropdown{ width:100%; } .editor-post-url__panel-dialog .editor-post-url{ margin:8px; min-width:248px; } .editor-post-url__front-page-link,.editor-post-url__link{ direction:ltr; word-break:break-word; } .editor-post-url__front-page-link{ padding:6px 12px 6px 0; } .editor-post-url__link-slug{ font-weight:600; } .editor-post-url__input input.components-input-control__input{ padding-inline-start:0 !important; } .editor-post-url__panel-toggle{ word-break:break-word; } .editor-post-url__intro{ margin:0; } .editor-post-url__permalink{ margin-bottom:0; margin-top:8px; } .editor-post-url__permalink-visual-label{ display:block; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ border:1px solid #1e1e1e; border-radius:2px; border-radius:50%; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:24px; line-height:normal; margin-left:12px; margin-top:2px; max-width:24px; min-width:24px; padding:6px 8px; position:relative; transition:none; width:24px; } @media not (prefers-reduced-motion){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ font-size:13px; line-height:normal; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-webkit-input-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-moz-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ height:16px; max-width:16px; min-width:16px; width:16px; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{ background-color:#fff; border:4px solid #fff; box-sizing:inherit; height:12px; margin:0; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); width:12px; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{ height:8px; width:8px; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); outline:2px solid #0000; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked{ background:var(--wp-admin-theme-color); border:none; } .editor-post-visibility__fieldset .editor-post-visibility__info{ color:#757575; margin-right:36px; margin-top:.5em; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__info{ margin-right:28px; } } .editor-post-visibility__fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__info{ margin-bottom:0; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; margin-right:32px; padding:6px 8px; width:calc(100% - 32px); } @media not (prefers-reduced-motion){ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ font-size:13px; line-height:normal; } } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-webkit-input-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-moz-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:-ms-input-placeholder{ color:#1e1e1e9e; } .editor-posts-per-page-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-post-trash.components-button{ flex-grow:1; justify-content:center; } .editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text{ padding-left:4px; padding-right:6px; } .editor-preview-dropdown__button-external{ display:flex; justify-content:space-between; width:100%; } .editor-resizable-editor.is-resizable{ margin:0 auto; overflow:visible; } .editor-resizable-editor__resize-handle{ appearance:none; background:none; border:0; border-radius:9999px; bottom:0; cursor:ew-resize; height:100px; margin:auto 0; outline:none; padding:0; position:absolute; top:0; width:12px; } .editor-resizable-editor__resize-handle:after{ background-color:#75757566; border-radius:9999px; bottom:16px; content:""; left:0; position:absolute; right:4px; top:16px; width:4px; } .editor-resizable-editor__resize-handle.is-left{ right:-18px; } .editor-resizable-editor__resize-handle.is-right{ left:-18px; } .editor-resizable-editor__resize-handle:active,.editor-resizable-editor__resize-handle:focus,.editor-resizable-editor__resize-handle:hover{ opacity:1; } .editor-resizable-editor__resize-handle:active:after,.editor-resizable-editor__resize-handle:focus:after,.editor-resizable-editor__resize-handle:hover:after{ background-color:var(--wp-admin-theme-color); } .editor-layout__toggle-entities-saved-states-panel,.editor-layout__toggle-publish-panel,.editor-layout__toggle-sidebar-panel{ background-color:#fff; border:1px dotted #ddd; bottom:auto; box-sizing:border-box; display:flex; height:auto !important; justify-content:center; left:0; padding:24px; position:fixed !important; right:auto; top:-9999em; width:280px; z-index:100000; } .interface-interface-skeleton__actions:focus .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus .editor-layout__toggle-publish-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-publish-panel{ bottom:0; top:auto; } .editor-start-page-options__modal .editor-start-page-options__modal__actions{ background-color:#fff; border-top:1px solid #ddd; bottom:0; height:92px; margin-left:-32px; margin-right:-32px; padding-left:32px; padding-right:32px; position:absolute; width:100%; z-index:1; } .editor-start-page-options__modal .block-editor-block-patterns-list{ padding-bottom:92px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:782px){ .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; margin-bottom:24px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__container{ min-height:100px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__content{ width:100%; } .editor-start-template-options__modal .editor-start-template-options__modal__actions{ background-color:#fff; border-top:1px solid #ddd; bottom:0; height:92px; margin-left:-32px; margin-right:-32px; padding-left:32px; padding-right:32px; position:absolute; width:100%; z-index:1; } .editor-start-template-options__modal .block-editor-block-patterns-list{ padding-bottom:92px; } .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:782px){ .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-patterns-list__item-title{ display:none; } .components-panel__header.editor-sidebar__panel-tabs{ padding-left:8px; padding-right:0; } .components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{ padding:0; } @media (min-width:782px){ .components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{ display:flex; } } .editor-post-summary .components-v-stack:empty{ display:none; } .editor-site-discussion-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .table-of-contents__popover.components-popover .components-popover__content{ min-width:380px; } .components-popover.table-of-contents__popover{ z-index:99998; } .table-of-contents__popover .components-popover__content{ padding:16px; } @media (min-width:600px){ .table-of-contents__popover .components-popover__content{ max-height:calc(100vh - 120px); overflow-y:auto; } } .table-of-contents__popover hr{ margin:10px -16px 0; } .table-of-contents__wrapper:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; display:block; left:0; pointer-events:none; position:absolute; right:0; top:0; } .table-of-contents__counts{ display:flex; flex-wrap:wrap; margin:-8px 0 0; } .table-of-contents__count{ color:#1e1e1e; display:flex; flex-basis:33%; flex-direction:column; font-size:13px; margin-bottom:0; margin-top:8px; padding-left:8px; } .table-of-contents__count:nth-child(4n){ padding-left:0; } .table-of-contents__number,.table-of-contents__popover .word-count{ color:#1e1e1e; font-size:21px; font-weight:400; line-height:30px; } .table-of-contents__title{ display:block; font-size:15px; font-weight:600; margin-top:20px; } .editor-text-editor{ background-color:#fff; flex-grow:1; position:relative; width:100%; } .editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){ border:1px solid #949494; border-radius:0; font-family:Menlo,Consolas,monaco,monospace; font-size:2.5em; font-weight:400; line-height:1.4; max-width:none; padding:16px; } @media (min-width:600px){ .editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){ padding:24px; } } .editor-text-editor .editor-post-title.is-raw-text textarea:focus,.editor-text-editor .editor-post-title:not(.is-raw-text):focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .editor-text-editor__body{ margin-left:auto; margin-right:auto; max-width:1080px; padding:0 12px 12px; width:100%; } @media (min-width:960px){ .editor-text-editor__body{ padding:0 24px 24px; } } .editor-text-editor__toolbar{ background:#fffc; display:flex; left:0; padding:4px 12px; position:sticky; right:0; top:0; z-index:1; } @media (min-width:600px){ .editor-text-editor__toolbar{ padding:12px; } } @media (min-width:960px){ .editor-text-editor__toolbar{ padding:12px 24px; } } .editor-text-editor__toolbar h2{ color:#1e1e1e; font-size:13px; line-height:40px; margin:0 0 0 auto; } .editor-visual-editor{ align-items:center; background-color:#ddd; display:flex; position:relative; } .editor-visual-editor iframe[name=editor-canvas]{ background-color:initial; } .editor-visual-editor.is-resizable{ max-height:100%; } .editor-visual-editor.has-padding{ padding:24px 24px 0; } .editor-visual-editor.is-iframed{ overflow:hidden; } .editor-visual-editor .components-button{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; padding:6px 12px; } .editor-visual-editor .components-button.has-icon,.editor-visual-editor .components-button.is-tertiary{ padding:6px; } .editor-fields-content-preview{ border-radius:4px; display:flex; flex-direction:column; height:100%; } .dataviews-view-table .editor-fields-content-preview{ flex-grow:0; width:96px; } .editor-fields-content-preview .block-editor-block-preview__container,.editor-fields-content-preview .editor-fields-content-preview__empty{ margin-bottom:auto; margin-top:auto; } .editor-fields-content-preview__empty{ text-align:center; }@charset "UTF-8"; :root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .interface-complementary-area-header{ background:#fff; gap:4px; padding-right:8px; } .interface-complementary-area-header .interface-complementary-area-header__title{ margin:0 auto 0 0; } .interface-complementary-area{ background:#fff; color:#1e1e1e; height:100%; overflow:auto; } @media (min-width:600px){ .interface-complementary-area{ -webkit-overflow-scrolling:touch; } } @media (min-width:782px){ .interface-complementary-area{ width:280px; } } .interface-complementary-area .components-panel{ border:none; position:relative; z-index:0; } .interface-complementary-area .components-panel__header{ position:sticky; top:0; z-index:1; } .interface-complementary-area .components-panel__header.editor-sidebar__panel-tabs{ top:0; } .interface-complementary-area p:not(.components-base-control__help,.components-form-token-field__help){ margin-top:0; } .interface-complementary-area h2{ color:#1e1e1e; font-size:13px; font-weight:500; margin-bottom:1.5em; } .interface-complementary-area h3{ color:#1e1e1e; font-size:11px; font-weight:500; margin-bottom:1.5em; text-transform:uppercase; } .interface-complementary-area hr{ border-bottom:1px solid #f0f0f0; border-top:none; margin:1.5em 0; } .interface-complementary-area div.components-toolbar,.interface-complementary-area div.components-toolbar-group{ box-shadow:none; margin-bottom:1.5em; } .interface-complementary-area div.components-toolbar-group:last-child,.interface-complementary-area div.components-toolbar:last-child{ margin-bottom:0; } .interface-complementary-area .block-editor-skip-to-selected-block:focus{ bottom:10px; left:auto; right:10px; top:auto; } .interface-complementary-area__fill{ height:100%; } @media (min-width:782px){ body.js.is-fullscreen-mode{ height:calc(100% + 32px); margin-top:-32px; } body.js.is-fullscreen-mode #adminmenumain,body.js.is-fullscreen-mode #wpadminbar{ display:none; } body.js.is-fullscreen-mode #wpcontent,body.js.is-fullscreen-mode #wpfooter{ margin-left:0; } } html.interface-interface-skeleton__html-container{ position:fixed; width:100%; } @media (min-width:782px){ html.interface-interface-skeleton__html-container:not(:has(.is-zoom-out)){ position:static; width:auto; } } .interface-interface-skeleton{ bottom:0; display:flex; flex-direction:row; height:auto; max-height:100%; position:fixed; right:0; top:46px; } @media (min-width:783px){ .interface-interface-skeleton{ top:32px; } .is-fullscreen-mode .interface-interface-skeleton{ top:0; } } .interface-interface-skeleton__editor{ display:flex; flex:0 1 100%; flex-direction:column; overflow:hidden; } .interface-interface-skeleton{ left:0; } @media (min-width:783px){ .interface-interface-skeleton{ left:160px; } } @media (min-width:783px){ .auto-fold .interface-interface-skeleton{ left:36px; } } @media (min-width:961px){ .auto-fold .interface-interface-skeleton{ left:160px; } } .folded .interface-interface-skeleton{ left:0; } @media (min-width:783px){ .folded .interface-interface-skeleton{ left:36px; } } body.is-fullscreen-mode .interface-interface-skeleton{ left:0 !important; } .interface-interface-skeleton__body{ display:flex; flex-grow:1; overflow:auto; overscroll-behavior-y:none; position:relative; } @media (min-width:782px){ .has-footer .interface-interface-skeleton__body{ padding-bottom:25px; } } .interface-interface-skeleton__content{ display:flex; flex-direction:column; flex-grow:1; overflow:auto; z-index:20; } @media (min-width:782px){ .interface-interface-skeleton__content{ z-index:auto; } } .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ background:#fff; bottom:0; color:#1e1e1e; flex-shrink:0; left:0; position:absolute; top:0; width:auto; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar,.interface-interface-skeleton__sidebar{ position:relative !important; } } .interface-interface-skeleton__sidebar{ border-top:1px solid #e0e0e0; overflow:hidden; } @media (min-width:782px){ .interface-interface-skeleton__sidebar{ box-shadow:-1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__secondary-sidebar{ border-top:1px solid #e0e0e0; right:0; } @media (min-width:782px){ .interface-interface-skeleton__secondary-sidebar{ box-shadow:1px 0 0 0 rgba(0,0,0,.133); outline:1px solid #0000; } } .interface-interface-skeleton__header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); color:#1e1e1e; flex-shrink:0; height:auto; outline:1px solid #0000; z-index:30; } .interface-interface-skeleton__footer{ background-color:#fff; border-top:1px solid #e0e0e0; bottom:0; color:#1e1e1e; display:none; flex-shrink:0; height:auto; left:0; position:absolute; width:100%; z-index:90; } @media (min-width:782px){ .interface-interface-skeleton__footer{ display:flex; } } .interface-interface-skeleton__footer .block-editor-block-breadcrumb{ align-items:center; background:#fff; display:flex; font-size:13px; height:24px; padding:0 18px; z-index:30; } .interface-interface-skeleton__actions{ background:#fff; bottom:auto; color:#1e1e1e; left:auto; position:fixed !important; right:0; top:-9999em; width:100vw; z-index:100000; } @media (min-width:782px){ .interface-interface-skeleton__actions{ width:280px; } } .interface-interface-skeleton__actions:focus,.interface-interface-skeleton__actions:focus-within{ bottom:0; top:auto; } .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:46px; } @media (min-width:782px){ .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ border-left:1px solid #ddd; top:32px; } .is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus,.is-fullscreen-mode .is-entity-save-view-open .interface-interface-skeleton__actions:focus-within{ top:0; } } .interface-pinned-items{ display:flex; gap:8px; } .interface-pinned-items .components-button{ display:none; margin:0; } .interface-pinned-items .components-button[aria-controls="edit-post:block"],.interface-pinned-items .components-button[aria-controls="edit-post:document"],.interface-pinned-items .components-button[aria-controls="edit-site:block-inspector"],.interface-pinned-items .components-button[aria-controls="edit-site:template"]{ display:flex; } .interface-pinned-items .components-button svg{ max-height:24px; max-width:24px; } @media (min-width:600px){ .interface-pinned-items .components-button{ display:flex; } } .editor-autocompleters__user .editor-autocompleters__no-avatar:before{ content:"\f110"; font:normal 20px/1 dashicons; margin-right:5px; vertical-align:middle; } .editor-autocompleters__user .editor-autocompleters__user-avatar{ flex-grow:0; flex-shrink:0; height:24px; margin-right:8px; max-width:none; width:24px; } .editor-autocompleters__user .editor-autocompleters__user-name{ flex-grow:1; flex-shrink:0; max-width:200px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .editor-autocompleters__user .editor-autocompleters__user-slug{ color:#757575; flex-grow:0; flex-shrink:0; margin-left:8px; max-width:100px; overflow:none; text-overflow:ellipsis; white-space:nowrap; } .editor-autocompleters__user:hover .editor-autocompleters__user-slug{ color:var(--wp-admin-theme-color); } .interface-interface-skeleton__sidebar:has(.editor-collab-sidebar){ box-shadow:none; } .interface-interface-skeleton__sidebar:has(.editor-collab-sidebar) .interface-complementary-area-header{ display:none; } .editor-collab-sidebar{ height:100%; } .editor-collab-sidebar-panel{ height:100%; padding:16px; } .editor-collab-sidebar-panel__thread{ background-color:#f0f0f0; border:1.5px solid #ddd; border-radius:8px; margin-bottom:16px; padding:16px; position:relative; } .editor-collab-sidebar-panel__active-thread{ border:1.5px solid #3858e9; } .editor-collab-sidebar-panel__focus-thread{ background-color:#fff; border:1.5px solid #3858e9; box-shadow:0 5.5px 7.8px -.3px rgba(0,0,0,.102); } .editor-collab-sidebar-panel__comment-field{ flex:1; } .editor-collab-sidebar-panel__child-thread{ margin-top:15px; } .editor-collab-sidebar-panel__user-name{ text-transform:capitalize; } .editor-collab-sidebar-panel__user-name,.editor-collab-sidebar-panel__user-time{ color:#757575; font-size:12px; font-weight:400; line-height:16px; text-align:left; } .editor-collab-sidebar-panel__user-comment{ color:#1e1e1e; font-size:13px; font-weight:400; line-height:20px; text-align:left; } .editor-collab-sidebar-panel__user-comment p{ margin-bottom:0; } .editor-collab-sidebar-panel__user-avatar{ border-radius:50%; flex-shrink:0; } .editor-collab-sidebar-panel__thread-overlay{ background-color:#000000b3; border-radius:8px; color:#fff; height:100%; left:0; padding:15px; position:absolute; text-align:center; top:0; width:100%; z-index:1; } .editor-collab-sidebar-panel__thread-overlay p{ margin-bottom:15px; } .editor-collab-sidebar-panel__thread-overlay button{ color:#fff; padding:4px 10px; } .editor-collab-sidebar-panel__comment-status{ margin-left:auto; } .editor-collab-sidebar-panel__comment-status button.has-icon:not(.has-text){ flex-shrink:0; height:24px; min-width:24px; padding:0; width:24px; } .editor-collab-sidebar-panel__comment-dropdown-menu{ flex-shrink:0; } .editor-collab-sidebar-panel__comment-dropdown-menu button.has-icon{ height:24px; min-width:24px; padding:0; width:24px; } .editor-collab-sidebar-panel__show-more-reply{ font-style:italic; font-weight:500; padding:0; } .editor-collapsible-block-toolbar{ align-items:center; display:flex; height:60px; overflow:hidden; } .editor-collapsible-block-toolbar .block-editor-block-contextual-toolbar{ background:#0000; border-bottom:0; height:100%; } .editor-collapsible-block-toolbar .block-editor-block-toolbar{ height:100%; padding-top:15px; } .editor-collapsible-block-toolbar .block-editor-block-toolbar .components-button:not(.block-editor-block-mover-button){ height:32px; } .editor-collapsible-block-toolbar:after{ background-color:#ddd; content:""; height:24px; margin-right:7px; width:1px; } .editor-collapsible-block-toolbar .components-toolbar,.editor-collapsible-block-toolbar .components-toolbar-group{ border-right:none; position:relative; } .editor-collapsible-block-toolbar .components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar:after{ background-color:#ddd; content:""; height:24px; position:absolute; right:-1px; top:4px; width:1px; } .editor-collapsible-block-toolbar .components-toolbar .components-toolbar-group.components-toolbar-group:after,.editor-collapsible-block-toolbar .components-toolbar-group .components-toolbar-group.components-toolbar-group:after{ display:none; } .editor-collapsible-block-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button{ height:32px; overflow:visible; } @media (min-width:600px){ .editor-collapsible-block-toolbar .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ height:40px; position:relative; top:-5px; } } .editor-collapsible-block-toolbar.is-collapsed{ display:none; } .editor-content-only-settings-menu__description{ min-width:235px; padding:8px; } .editor-blog-title-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-document-bar{ align-items:center; background:#f0f0f0; border-radius:4px; display:flex; height:32px; justify-content:space-between; min-width:0; width:min(100%, 450px); } .editor-document-bar:hover{ background-color:#e0e0e0; } .editor-document-bar .components-button{ border-radius:4px; } @media not (prefers-reduced-motion){ .editor-document-bar .components-button{ transition:all .1s ease-out; } } .editor-document-bar .components-button:hover{ background:#e0e0e0; } @media screen and (min-width:782px) and (max-width:960px){ .editor-document-bar.has-back-button .editor-document-bar__post-type-label{ display:none; } } .editor-document-bar__command{ color:var(--wp-block-synced-color); flex-grow:1; overflow:hidden; } .editor-document-bar__title{ color:#1e1e1e; margin:0 auto; max-width:70%; overflow:hidden; } @media (min-width:782px){ .editor-document-bar__title{ padding-left:24px; } } .editor-document-bar__title h1{ align-items:center; display:flex; font-weight:400; justify-content:center; overflow:hidden; white-space:nowrap; } .editor-document-bar__post-title{ color:currentColor; flex:1; overflow:hidden; text-overflow:ellipsis; } .editor-document-bar__post-type-label{ color:#2f2f2f; flex:0; padding-left:4px; } @media screen and (max-width:600px){ .editor-document-bar__post-type-label{ display:none; } } .editor-document-bar__shortcut{ color:#2f2f2f; display:none; min-width:24px; } @media (min-width:782px){ .editor-document-bar__shortcut{ display:initial; } } .editor-document-bar__back.components-button.has-icon.has-text{ color:#757575; flex-shrink:0; gap:0; min-width:36px; position:absolute; z-index:1; } .editor-document-bar__back.components-button.has-icon.has-text:hover{ background-color:initial; color:#1e1e1e; } .editor-document-bar__icon-layout.editor-document-bar__icon-layout{ display:none; margin-left:12px; pointer-events:none; position:absolute; } .editor-document-bar__icon-layout.editor-document-bar__icon-layout svg{ fill:#949494; } @media (min-width:600px){ .editor-document-bar__icon-layout.editor-document-bar__icon-layout{ display:flex; } } .document-outline{ margin:20px 0; } .document-outline ul{ margin:0; padding:0; } .document-outline__item{ display:flex; margin:4px 0; } .document-outline__item a{ text-decoration:none; } .document-outline__item .document-outline__emdash:before{ color:#ddd; margin-right:4px; } .document-outline__item.is-h2 .document-outline__emdash:before{ content:"—"; } .document-outline__item.is-h3 .document-outline__emdash:before{ content:"——"; } .document-outline__item.is-h4 .document-outline__emdash:before{ content:"———"; } .document-outline__item.is-h5 .document-outline__emdash:before{ content:"————"; } .document-outline__item.is-h6 .document-outline__emdash:before{ content:"—————"; } .document-outline__button{ align-items:flex-start; background:none; border:none; border-radius:2px; color:#1e1e1e; cursor:pointer; display:flex; margin:0 0 0 -1px; padding:2px 5px 2px 1px; text-align:left; } .document-outline__button:disabled,.document-outline__button[aria-disabled=true]{ color:#757575; cursor:default; } .document-outline__button:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .document-outline__level{ background:#ddd; border-radius:3px; color:#1e1e1e; font-size:13px; margin-right:4px; padding:1px 6px; } .is-invalid .document-outline__level{ background:#f0b849; } .document-outline__item-content{ padding:1px 0; } .editor-document-outline.has-no-headings{ color:#757575; text-align:center; } .editor-document-outline.has-no-headings>svg{ margin-top:28px; } .editor-document-outline.has-no-headings>p{ padding-left:32px; padding-right:32px; } .editor-document-tools{ align-items:center; display:inline-flex; } .editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{ display:none; } @media (min-width:782px){ .editor-document-tools .editor-document-tools__left>.editor-history__redo,.editor-document-tools .editor-document-tools__left>.editor-history__undo{ display:inline-flex; } } .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle{ display:inline-flex; } @media not (prefers-reduced-motion){ .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle svg{ transition:transform .2s cubic-bezier(.165, .84, .44, 1); } } .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.is-pressed svg{ transform:rotate(45deg); } .editor-document-tools .block-editor-list-view{ display:none; } @media (min-width:600px){ .editor-document-tools .block-editor-list-view{ display:flex; } } .editor-document-tools .editor-document-tools__left>.components-button.has-icon,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon{ height:32px; min-width:32px; padding:4px; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon.is-pressed,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon.is-pressed{ background:#1e1e1e; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon:focus:not(:disabled),.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), inset 0 0 0 1px #fff; outline:1px solid #0000; } .editor-document-tools .editor-document-tools__left>.components-button.has-icon:before,.editor-document-tools .editor-document-tools__left>.components-dropdown>.components-button.has-icon:before{ display:none; } .editor-document-tools__left{ align-items:center; display:inline-flex; gap:8px; } .editor-document-tools__left:not(:last-child){ margin-inline-end:8px; } .show-icon-labels .editor-document-tools .editor-document-tools__left>.editor-document-tools__inserter-toggle.has-icon{ padding:0 8px; width:auto; } .show-icon-labels .editor-document-tools__left>*+*{ margin-left:8px; } .editor-editor-interface .entities-saved-states__panel-header{ height:61px; } .editor-editor-interface .interface-interface-skeleton__content{ isolation:isolate; } .editor-visual-editor{ flex:1 0 auto; } .components-editor-notices__dismissible,.components-editor-notices__pinned{ color:#1e1e1e; left:0; position:relative; right:0; top:0; } .components-editor-notices__dismissible .components-notice,.components-editor-notices__pinned .components-notice{ border-bottom:1px solid #0003; box-sizing:border-box; min-height:60px; padding:0 12px; } .components-editor-notices__dismissible .components-notice .components-notice__dismiss,.components-editor-notices__pinned .components-notice .components-notice__dismiss{ margin-top:12px; } .entities-saved-states__panel-header{ background:#fff; border-bottom:1px solid #ddd; box-sizing:border-box; height:60px; padding-left:16px; padding-right:16px; } .entities-saved-states__text-prompt{ padding:16px 16px 4px; } .entities-saved-states__text-prompt .entities-saved-states__text-prompt--header{ display:block; margin-bottom:12px; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt{ padding:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body{ border:0; padding-left:0; padding-right:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2{ margin-bottom:0; margin-left:-16px; margin-right:-16px; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-body>h2 button{ font-size:11px; text-transform:uppercase; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--header-wrapper{ display:none; } .entities-saved-states__panel.is-inline .entities-saved-states__text-prompt--changes-count{ margin-bottom:8px; margin-top:0; } .entities-saved-states__panel.is-inline .entities-saved-states__panel-footer{ margin-top:16px; } .entities-saved-states__change-control{ flex:1; } .entities-saved-states__changes{ font-size:13px; list-style:disc; margin:4px 16px 0 24px; } .entities-saved-states__changes li{ margin-bottom:4px; } .editor-error-boundary{ background-color:#fff; border:1px solid #1e1e1e; border-radius:2px; box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; margin:60px auto auto; max-width:780px; padding:1em; } .editor-header{ align-items:center; background:#fff; display:grid; grid-auto-flow:row; grid-template:auto/60px minmax(0, max-content) minmax(min-content, 1fr) 60px; height:60px; justify-content:space-between; max-width:100vw; } .editor-header:has(>.editor-header__center){ grid-template:auto/60px min-content 1fr min-content 60px; } @media (min-width:782px){ .editor-header:has(>.editor-header__center){ grid-template:auto/60px minmax(min-content, 2fr) 2.5fr minmax(min-content, 2fr) 60px; } } @media (min-width:480px){ .editor-header{ gap:16px; } } @media (min-width:280px){ .editor-header{ flex-wrap:nowrap; } } .editor-header__toolbar{ align-items:center; clip-path:inset(-2px); display:flex; grid-column:1 / 3; min-width:0; } .editor-header__toolbar>:first-child{ margin-inline:16px 0; } .editor-header__back-button+.editor-header__toolbar{ grid-column:2 / 3; } @media (min-width:480px){ .editor-header__back-button+.editor-header__toolbar>:first-child{ margin-inline:0; } .editor-header__toolbar{ clip-path:none; } } .editor-header__toolbar .table-of-contents{ display:none; } @media (min-width:600px){ .editor-header__toolbar .table-of-contents{ display:block; } } .editor-header__toolbar .editor-collapsible-block-toolbar,.editor-header__toolbar .editor-collapsible-block-toolbar.is-collapsed~.editor-collapsible-block-toolbar__toggle{ margin-inline:8px 0; } .editor-header__center{ align-items:center; clip-path:inset(-2px); display:flex; grid-column:3 / 4; justify-content:center; min-width:0; } @media (max-width:479px){ .editor-header__center>:first-child{ margin-inline-start:8px; } .editor-header__center>:last-child{ margin-inline-end:8px; } } .editor-header__settings{ align-items:center; display:inline-flex; flex-wrap:nowrap; gap:8px; grid-column:3 / -1; justify-self:end; padding-right:4px; } .editor-header:has(>.editor-header__center) .editor-header__settings{ grid-column:4 / -1; } @media (min-width:600px){ .editor-header__settings{ padding-right:8px; } } .show-icon-labels .editor-header .components-button.has-icon,.show-icon-labels.interface-pinned-items .components-button.has-icon{ width:auto; } .show-icon-labels .editor-header .components-button.has-icon svg,.show-icon-labels.interface-pinned-items .components-button.has-icon svg{ display:none; } .show-icon-labels .editor-header .components-button.has-icon:after,.show-icon-labels.interface-pinned-items .components-button.has-icon:after{ content:attr(aria-label); white-space:nowrap; } .show-icon-labels .editor-header .components-button.has-icon[aria-disabled=true],.show-icon-labels.interface-pinned-items .components-button.has-icon[aria-disabled=true]{ background-color:initial; } .show-icon-labels .editor-header .is-tertiary:active,.show-icon-labels.interface-pinned-items .is-tertiary:active{ background-color:initial; box-shadow:0 0 0 1.5px var(--wp-admin-theme-color); } .show-icon-labels .editor-header .components-button.has-icon.button-toggle svg,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle svg{ display:block; } .show-icon-labels .editor-header .components-button.has-icon.button-toggle:after,.show-icon-labels.interface-pinned-items .components-button.has-icon.button-toggle:after{ content:none; } .show-icon-labels .editor-header .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon,.show-icon-labels.interface-pinned-items .components-menu-items-choice .components-menu-items__item-icon.components-menu-items__item-icon{ display:block; } .show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{ padding-left:8px; padding-right:8px; } @media (min-width:600px){ .show-icon-labels .editor-header .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels .editor-header .interface-pinned-items .components-button,.show-icon-labels.interface-pinned-items .editor-document-tools__inserter-toggle.editor-document-tools__inserter-toggle,.show-icon-labels.interface-pinned-items .interface-pinned-items .components-button{ padding-left:12px; padding-right:12px; } } .show-icon-labels .editor-header .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels .editor-header .editor-post-saved-state.editor-post-saved-state:after,.show-icon-labels.interface-pinned-items .editor-post-save-draft.editor-post-save-draft:after,.show-icon-labels.interface-pinned-items .editor-post-saved-state.editor-post-saved-state:after{ content:none; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover{ border-left:none; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover:before{ background-color:#ddd; content:""; height:24px; margin-left:8px; margin-top:4px; width:1px; } .show-icon-labels .editor-header__toolbar .block-editor-block-mover .block-editor-block-mover__move-button-container:before{ background:#ddd; left:calc(50% + 1px); width:calc(100% - 24px); } .show-icon-labels.interface-pinned-items{ border-bottom:1px solid #ccc; display:block; margin:0 -12px; padding:6px 12px 12px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon{ justify-content:flex-start; margin:0; padding:6px 6px 6px 8px; width:14.625rem; } .show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=true] svg{ display:block; max-width:24px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon[aria-expanded=false]{ padding-left:40px; } .show-icon-labels.interface-pinned-items>.components-button.has-icon svg{ margin-right:8px; } @media (min-width:480px){ .editor-header__post-preview-button{ display:none; } } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header{ border-bottom:none; } .editor-editor-interface.is-distraction-free .editor-header{ background-color:#fff; width:100%; } @media (min-width:782px){ .editor-editor-interface.is-distraction-free .editor-header{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); position:absolute; } } .editor-editor-interface.is-distraction-free .editor-header>.edit-post-header__settings>.edit-post-header__post-preview-button{ visibility:hidden; } .editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-preview-dropdown,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.editor-zoom-out-toggle,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__settings>.interface-pinned-items,.editor-editor-interface.is-distraction-free .editor-header>.editor-header__toolbar .editor-document-tools__document-overview-toggle{ display:none; } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within{ opacity:1 !important; } .editor-editor-interface.is-distraction-free .interface-interface-skeleton__header:focus-within div{ transform:translateX(0) translateZ(0) !important; } .editor-editor-interface.is-distraction-free .components-editor-notices__dismissible{ position:absolute; z-index:35; } .components-popover.more-menu-dropdown__content{ z-index:99998; } .editor-inserter-sidebar{ box-sizing:border-box; display:flex; flex-direction:column; height:100%; } .editor-inserter-sidebar *,.editor-inserter-sidebar :after,.editor-inserter-sidebar :before{ box-sizing:inherit; } .editor-inserter-sidebar__content{ height:100%; } .editor-keyboard-shortcut-help-modal__section{ margin:0 0 2rem; } .editor-keyboard-shortcut-help-modal__section-title{ font-size:.9rem; font-weight:600; } .editor-keyboard-shortcut-help-modal__shortcut{ align-items:baseline; border-top:1px solid #ddd; display:flex; margin-bottom:0; padding:.6rem 0; } .editor-keyboard-shortcut-help-modal__shortcut:last-child{ border-bottom:1px solid #ddd; } .editor-keyboard-shortcut-help-modal__shortcut:empty{ display:none; } .editor-keyboard-shortcut-help-modal__shortcut-term{ font-weight:600; margin:0 0 0 1rem; text-align:right; } .editor-keyboard-shortcut-help-modal__shortcut-description{ flex:1; margin:0; } .editor-keyboard-shortcut-help-modal__shortcut-key-combination{ background:none; display:block; margin:0; padding:0; } .editor-keyboard-shortcut-help-modal__shortcut-key-combination+.editor-keyboard-shortcut-help-modal__shortcut-key-combination{ margin-top:10px; } .editor-keyboard-shortcut-help-modal__shortcut-key{ border-radius:8%; margin:0 .2rem; padding:.25rem .5rem; } .editor-keyboard-shortcut-help-modal__shortcut-key:last-child{ margin:0 0 0 .2rem; } .editor-list-view-sidebar{ height:100%; } @media (min-width:782px){ .editor-list-view-sidebar{ width:350px; } } .editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{ height:100%; overflow:auto; padding:4px; scrollbar-color:#0000 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:auto; scrollbar-width:thin; will-change:transform; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar{ height:12px; width:12px; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-track,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-track{ background-color:initial; } .editor-list-view-sidebar__list-view-container>.document-outline::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:initial; border:3px solid #0000; border-radius:8px; } .editor-list-view-sidebar__list-view-container>.document-outline:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-container>.document-outline:hover::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus-within::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:focus::-webkit-scrollbar-thumb,.editor-list-view-sidebar__list-view-panel-content:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .editor-list-view-sidebar__list-view-container>.document-outline:focus,.editor-list-view-sidebar__list-view-container>.document-outline:focus-within,.editor-list-view-sidebar__list-view-container>.document-outline:hover,.editor-list-view-sidebar__list-view-panel-content:focus,.editor-list-view-sidebar__list-view-panel-content:focus-within,.editor-list-view-sidebar__list-view-panel-content:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .editor-list-view-sidebar__list-view-container>.document-outline,.editor-list-view-sidebar__list-view-panel-content{ scrollbar-color:#949494 #0000; } } .editor-list-view-sidebar__list-view-container{ display:flex; flex-direction:column; height:100%; } .editor-list-view-sidebar__tab-panel{ height:100%; } .editor-list-view-sidebar__outline{ border-bottom:1px solid #ddd; display:flex; flex-direction:column; gap:8px; padding:16px; } .editor-list-view-sidebar__outline>div>span:first-child{ display:inline-block; width:90px; } .editor-list-view-sidebar__outline>div>span{ color:#757575; font-size:12px; line-height:1.4; } .editor-post-order__panel,.editor-post-parent__panel{ padding-top:8px; } .editor-post-order__panel .editor-post-panel__row-control>div,.editor-post-parent__panel .editor-post-panel__row-control>div{ width:100%; } .editor-post-order__panel-dialog .editor-post-order,.editor-post-order__panel-dialog .editor-post-parent,.editor-post-parent__panel-dialog .editor-post-order,.editor-post-parent__panel-dialog .editor-post-parent{ margin:8px; } .editor-post-order__panel-dialog .components-popover__content,.editor-post-parent__panel-dialog .components-popover__content{ min-width:320px; } .editor-post-author__panel{ padding-top:8px; } .editor-post-author__panel .editor-post-panel__row-control>div{ width:100%; } .editor-post-author__panel-dialog .editor-post-author{ margin:8px; min-width:248px; } .editor-action-modal{ z-index:1000001; } .editor-post-card-panel__content{ flex-grow:1; } .editor-post-card-panel__title{ width:100%; } .editor-post-card-panel__title.editor-post-card-panel__title{ align-items:center; column-gap:8px; display:flex; flex-wrap:wrap; font-family:-apple-system,"system-ui",Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:500; line-height:20px; margin:0; row-gap:4px; word-break:break-word; } .editor-post-card-panel__icon{ flex:0 0 24px; height:24px; width:24px; } .editor-post-card-panel__header{ display:flex; justify-content:space-between; } .editor-post-card-panel.has-description .editor-post-card-panel__header{ margin-bottom:8px; } .editor-post-card-panel .editor-post-card-panel__title-name{ padding:2px 0; } .editor-post-card-panel .editor-post-card-panel__description,.editor-post-content-information{ color:#757575; } .editor-post-content-information .components-text{ color:inherit; } .editor-post-discussion__panel-dialog .editor-post-discussion{ margin:8px; min-width:248px; } .editor-post-discussion__panel-toggle .components-text{ color:inherit; } .editor-post-discussion__panel-dialog .components-popover__content{ min-width:320px; } .editor-post-excerpt__textarea{ margin-bottom:10px; width:100%; } .editor-post-excerpt__dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-post-featured-image{ padding:0; } .editor-post-featured-image .components-spinner{ left:50%; margin-left:-9px; margin-top:-9px; position:absolute; top:50%; } .editor-post-featured-image__container{ position:relative; } .editor-post-featured-image__container:focus .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:focus-within .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image),.editor-post-featured-image__container:hover .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-is-requesting-image){ opacity:1; } .editor-post-featured-image__container .editor-post-featured-image__actions.editor-post-featured-image__actions-missing-image{ margin-top:16px; opacity:1; } .editor-post-featured-image__container .components-drop-zone__content{ border-radius:2px; } .editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner{ align-items:center; display:flex; gap:8px; } .editor-post-featured-image__container:has(.editor-post-featured-image__toggle) .components-drop-zone .components-drop-zone__content-inner .components-drop-zone__content-icon{ margin:0; } .editor-post-featured-image__preview,.editor-post-featured-image__toggle{ box-shadow:0 0 0 0 var(--wp-admin-theme-color); display:flex; justify-content:center; min-height:40px; outline-offset:-1px; overflow:hidden; padding:0; width:100%; } .editor-post-featured-image__preview{ height:auto !important; outline:1px solid #0000001a; } .editor-post-featured-image__preview .editor-post-featured-image__preview-image{ aspect-ratio:2/1; object-fit:cover; object-position:50% 50%; width:100%; } .editor-post-featured-image__toggle{ box-shadow:inset 0 0 0 1px #ccc; } .editor-post-featured-image__toggle:focus:not(:disabled){ box-shadow:0 0 0 currentColor inset, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){ bottom:0; opacity:0; padding:8px; position:absolute; } @media not (prefers-reduced-motion){ .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image){ transition:opacity 50ms ease-out; } } .editor-post-featured-image__actions:not(.editor-post-featured-image__actions-missing-image) .editor-post-featured-image__action{ -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background:#ffffffbf; } .editor-post-featured-image__actions .editor-post-featured-image__action{ flex-grow:1; justify-content:center; } [class].editor-post-format__suggestion{ margin:4px 0 0; } .editor-post-format__dialog .editor-post-format__dialog-content{ margin:8px; min-width:248px; } .editor-post-last-edited-panel{ color:#757575; } .editor-post-last-edited-panel .components-text{ color:inherit; } .editor-post-last-revision__title{ font-weight:500; width:100%; } .editor-post-last-revision__title.components-button.has-icon{ height:100%; justify-content:space-between; } .editor-post-last-revision__title.components-button.has-icon:active,.editor-post-last-revision__title.components-button.has-icon:hover{ background:#f0f0f0; } .editor-post-last-revision__title.components-button.has-icon:focus{ border-radius:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-panel__body.is-opened.editor-post-last-revision__panel{ height:48px; padding:0; } .components-panel__body.is-opened.editor-post-last-revision__panel .editor-post-last-revision__title.components-button.components-button{ padding:16px; } .editor-private-post-last-revision__button{ display:inline-block; } .editor-post-locked-modal__buttons{ margin-top:24px; } .editor-post-locked-modal__avatar{ border-radius:50%; margin-top:16px; min-width:auto !important; } .editor-post-panel__row{ align-items:flex-start !important; justify-content:flex-start !important; min-height:32px; width:100%; } .editor-post-panel__row-label{ align-items:center; display:flex; flex-shrink:0; hyphens:auto; line-height:20px; min-height:32px; padding:6px 0; width:38%; } .editor-post-panel__row-control{ align-items:center; display:flex; flex-grow:1; min-height:32px; } .editor-post-panel__row-control .components-button{ height:auto; max-width:100%; min-height:32px; text-align:left; text-wrap:balance; text-wrap:pretty; white-space:normal; } .editor-post-panel__row-control .components-dropdown{ max-width:100%; } .editor-post-panel__section{ padding:16px; } .editor-post-publish-panel__content{ min-height:calc(100% - 144px); } .editor-post-publish-panel__content>.components-spinner{ display:block; margin:100px auto 0; } .editor-post-publish-panel__header{ align-content:space-between; align-items:center; background:#fff; border-bottom:1px solid #ddd; display:flex; height:61px; padding-left:16px; padding-right:16px; } .editor-post-publish-panel__header .components-button{ justify-content:center; width:100%; } .editor-post-publish-panel__header .has-icon{ margin-left:auto; width:auto; } .components-site-card{ align-items:center; display:flex; margin:16px 0; } .components-site-icon{ border:none; border-radius:2px; flex-shrink:0; height:36px; margin-right:12px; width:36px; } .components-site-name{ display:block; font-size:14px; } .components-site-home{ color:#757575; display:block; font-size:12px; word-break:break-word; } .editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{ flex:1; } @media (min-width:480px){ .editor-post-publish-panel__header-cancel-button,.editor-post-publish-panel__header-publish-button{ max-width:160px; } } .editor-post-publish-panel__header-publish-button{ justify-content:center; padding-left:4px; } .editor-post-publish-panel__header-cancel-button{ padding-right:4px; } .editor-post-publish-panel__header-published{ flex-grow:1; } .editor-post-publish-panel__footer{ padding:16px; } .components-button.editor-post-publish-panel__toggle.is-primary{ align-items:center; display:inline-flex; } .components-button.editor-post-publish-panel__toggle.is-primary.is-busy .dashicon{ display:none; } .components-button.editor-post-publish-panel__toggle.is-primary .dashicon{ margin-right:-4px; } .editor-post-publish-panel__link{ font-weight:400; padding-left:4px; } .editor-post-publish-panel__prepublish{ padding:16px; } .editor-post-publish-panel__prepublish strong{ color:#1e1e1e; } .editor-post-publish-panel__prepublish .components-panel__body{ background:#fff; margin-left:-16px; margin-right:-16px; } .editor-post-publish-panel__prepublish .editor-post-visibility__dialog-legend{ display:none; } .editor-post-publish-panel__prepublish .components-panel__body-title .components-button{ align-items:flex-start; text-wrap:balance; text-wrap:pretty; } .post-publish-panel__postpublish .components-panel__body{ border-bottom:1px solid #e0e0e0; border-top:none; } .post-publish-panel__postpublish-buttons{ align-content:space-between; display:flex; flex-wrap:wrap; gap:16px; } .post-publish-panel__postpublish-buttons .components-button{ flex:1; justify-content:center; } .post-publish-panel__postpublish-buttons .components-clipboard-button{ width:100%; } .post-publish-panel__postpublish-post-address-container{ align-items:flex-end; display:flex; margin-bottom:16px; } .post-publish-panel__postpublish-post-address-container .post-publish-panel__postpublish-post-address{ flex:1; } .post-publish-panel__postpublish-post-address-container input[readonly]{ background:#f0f0f0; border-color:#ccc; height:36px; overflow:hidden; padding:12px; text-overflow:ellipsis; } .post-publish-panel__postpublish-post-address__copy-button-wrap{ flex-shrink:0; margin-left:16px; } .post-publish-panel__postpublish-header{ font-weight:500; } .post-publish-panel__postpublish-subheader{ margin:0 0 8px; } .post-publish-panel__tip{ color:#f0b849; } @media screen and (max-width:782px){ .post-publish-panel__postpublish-post-address__button-wrap .components-button{ height:40px; } } .editor-post-publish-panel{ background:#fff; bottom:0; left:0; overflow:auto; position:fixed; right:0; top:46px; z-index:100001; } @media (min-width:782px){ .editor-post-publish-panel{ border-left:1px solid #ddd; left:auto; top:32px; width:281px; z-index:99998; } } @media (min-width:782px) and (not (prefers-reduced-motion)){ .editor-post-publish-panel{ animation:editor-post-publish-panel__slide-in-animation .1s forwards; transform:translateX(100%); } } @media (min-width:782px){ body.is-fullscreen-mode .editor-post-publish-panel{ top:0; } [role=region]:focus .editor-post-publish-panel{ transform:translateX(0); } } @keyframes editor-post-publish-panel__slide-in-animation{ to{ transform:translateX(0); } } .editor-post-saved-state{ align-items:center; color:#757575; display:flex; overflow:hidden; padding:12px 4px; white-space:nowrap; width:28px; } .editor-post-saved-state.is-saved[aria-disabled=true],.editor-post-saved-state.is-saved[aria-disabled=true]:hover,.editor-post-saved-state.is-saving[aria-disabled=true],.editor-post-saved-state.is-saving[aria-disabled=true]:hover{ background:#0000; color:#757575; } .editor-post-saved-state svg{ display:inline-block; flex:0 0 auto; fill:currentColor; margin-right:8px; } @media (min-width:600px){ .editor-post-saved-state{ padding:8px 12px; text-indent:inherit; width:auto; } .editor-post-saved-state svg{ margin-right:0; } } .editor-post-save-draft.has-text.has-icon svg{ margin-right:0; } .editor-post-schedule__panel-dropdown{ width:100%; } .editor-post-schedule__dialog .components-popover__content{ min-width:320px; padding:16px; } .editor-post-status{ max-width:100%; } .editor-post-status.is-read-only{ padding:6px 12px; } .editor-post-status .editor-post-status__toggle.editor-post-status__toggle{ padding-bottom:4px; padding-top:4px; } .editor-change-status__password-fieldset,.editor-change-status__publish-date-wrapper{ border-top:1px solid #e0e0e0; padding-top:16px; } .editor-change-status__content .components-popover__content{ min-width:320px; padding:16px; } .editor-change-status__content .editor-change-status__password-legend{ margin-bottom:8px; padding:0; } .editor-change-status__content p.components-base-control__help:has(.components-checkbox-control__help){ margin-top:4px; } .editor-post-sticky__checkbox-control{ border-top:1px solid #e0e0e0; padding-top:16px; } .editor-post-sync-status__value{ padding:6px 0 6px 12px; } .editor-post-taxonomies__hierarchical-terms-list{ margin-left:-6px; margin-top:-6px; max-height:14em; overflow:auto; padding-left:6px; padding-top:6px; } .editor-post-taxonomies__hierarchical-terms-choice{ margin-bottom:8px; } .editor-post-taxonomies__hierarchical-terms-choice:last-child{ margin-bottom:4px; } .editor-post-taxonomies__hierarchical-terms-subchoices{ margin-left:16px; margin-top:8px; } .editor-post-taxonomies__flat-term-most-used .editor-post-taxonomies__flat-term-most-used-label{ margin-bottom:4px; } .editor-post-taxonomies__flat-term-most-used-list{ margin:0; } .editor-post-taxonomies__flat-term-most-used-list li{ display:inline-block; margin-right:8px; } .editor-post-template__swap-template-modal{ z-index:1000001; } .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; padding-top:2px; } @media (min-width:782px){ .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-post-template__swap-template-modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .editor-post-template__dropdown .components-popover__content{ min-width:240px; } .editor-post-template__dropdown .components-button.is-pressed,.editor-post-template__dropdown .components-button.is-pressed:hover{ background:inherit; color:inherit; } @media (min-width:782px){ .editor-post-template__create-form{ width:320px; } } .editor-post-template__classic-theme-dropdown{ padding:8px; } textarea.editor-post-text-editor{ border:1px solid #949494; border-radius:0; box-shadow:none; display:block; font-family:Menlo,Consolas,monaco,monospace; font-size:16px !important; line-height:2.4; margin:0; min-height:200px; overflow:hidden; padding:16px; resize:none; width:100%; } @media not (prefers-reduced-motion){ textarea.editor-post-text-editor{ transition:border .1s ease-out,box-shadow .1s linear; } } @media (min-width:600px){ textarea.editor-post-text-editor{ font-size:15px !important; padding:24px; } } textarea.editor-post-text-editor:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); position:relative; } textarea.editor-post-text-editor::-webkit-input-placeholder{ color:#1e1e1e9e; } textarea.editor-post-text-editor::-moz-placeholder{ color:#1e1e1e9e; } textarea.editor-post-text-editor:-ms-input-placeholder{ color:#1e1e1e9e; } .editor-post-title.is-raw-text{ margin-bottom:24px; margin-top:2px; max-width:none; } .editor-post-url__panel-dropdown{ width:100%; } .editor-post-url__panel-dialog .editor-post-url{ margin:8px; min-width:248px; } .editor-post-url__front-page-link,.editor-post-url__link{ direction:ltr; word-break:break-word; } .editor-post-url__front-page-link{ padding:6px 0 6px 12px; } .editor-post-url__link-slug{ font-weight:600; } .editor-post-url__input input.components-input-control__input{ padding-inline-start:0 !important; } .editor-post-url__panel-toggle{ word-break:break-word; } .editor-post-url__intro{ margin:0; } .editor-post-url__permalink{ margin-bottom:0; margin-top:8px; } .editor-post-url__permalink-visual-label{ display:block; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ border:1px solid #1e1e1e; border-radius:2px; border-radius:50%; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:24px; line-height:normal; margin-right:12px; margin-top:2px; max-width:24px; min-width:24px; padding:6px 8px; position:relative; transition:none; width:24px; } @media not (prefers-reduced-motion){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ font-size:13px; line-height:normal; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-webkit-input-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]::-moz-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]{ height:16px; max-width:16px; min-width:16px; width:16px; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{ background-color:#fff; border:4px solid #fff; box-sizing:inherit; height:12px; left:50%; margin:0; position:absolute; top:50%; transform:translate(-50%, -50%); width:12px; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked:before{ height:8px; width:8px; } } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); outline:2px solid #0000; } .editor-post-visibility__fieldset .editor-post-visibility__radio[type=radio]:checked{ background:var(--wp-admin-theme-color); border:none; } .editor-post-visibility__fieldset .editor-post-visibility__info{ color:#757575; margin-left:36px; margin-top:.5em; } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__info{ margin-left:28px; } } .editor-post-visibility__fieldset .editor-post-visibility__choice:last-child .editor-post-visibility__info{ margin-bottom:0; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; margin-left:32px; padding:6px 8px; width:calc(100% - 32px); } @media not (prefers-reduced-motion){ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]{ font-size:13px; line-height:normal; } } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-webkit-input-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]::-moz-placeholder{ color:#1e1e1e9e; } .editor-post-visibility__fieldset .editor-post-visibility__password .editor-post-visibility__password-input[type=text]:-ms-input-placeholder{ color:#1e1e1e9e; } .editor-posts-per-page-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .editor-post-trash.components-button{ flex-grow:1; justify-content:center; } .editor-preview-dropdown .editor-preview-dropdown__toggle.has-icon.has-text{ padding-left:6px; padding-right:4px; } .editor-preview-dropdown__button-external{ display:flex; justify-content:space-between; width:100%; } .editor-resizable-editor.is-resizable{ margin:0 auto; overflow:visible; } .editor-resizable-editor__resize-handle{ appearance:none; background:none; border:0; border-radius:9999px; bottom:0; cursor:ew-resize; height:100px; margin:auto 0; outline:none; padding:0; position:absolute; top:0; width:12px; } .editor-resizable-editor__resize-handle:after{ background-color:#75757566; border-radius:9999px; bottom:16px; content:""; left:4px; position:absolute; right:0; top:16px; width:4px; } .editor-resizable-editor__resize-handle.is-left{ left:-18px; } .editor-resizable-editor__resize-handle.is-right{ right:-18px; } .editor-resizable-editor__resize-handle:active,.editor-resizable-editor__resize-handle:focus,.editor-resizable-editor__resize-handle:hover{ opacity:1; } .editor-resizable-editor__resize-handle:active:after,.editor-resizable-editor__resize-handle:focus:after,.editor-resizable-editor__resize-handle:hover:after{ background-color:var(--wp-admin-theme-color); } .editor-layout__toggle-entities-saved-states-panel,.editor-layout__toggle-publish-panel,.editor-layout__toggle-sidebar-panel{ background-color:#fff; border:1px dotted #ddd; bottom:auto; box-sizing:border-box; display:flex; height:auto !important; justify-content:center; left:auto; padding:24px; position:fixed !important; right:0; top:-9999em; width:280px; z-index:100000; } .interface-interface-skeleton__actions:focus .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus .editor-layout__toggle-publish-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-entities-saved-states-panel,.interface-interface-skeleton__actions:focus-within .editor-layout__toggle-publish-panel{ bottom:0; top:auto; } .editor-start-page-options__modal .editor-start-page-options__modal__actions{ background-color:#fff; border-top:1px solid #ddd; bottom:0; height:92px; margin-left:-32px; margin-right:-32px; padding-left:32px; padding-right:32px; position:absolute; width:100%; z-index:1; } .editor-start-page-options__modal .block-editor-block-patterns-list{ padding-bottom:92px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:782px){ .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-start-page-options__modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; margin-bottom:24px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__container{ min-height:100px; } .editor-start-page-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-preview__content{ width:100%; } .editor-start-template-options__modal .editor-start-template-options__modal__actions{ background-color:#fff; border-top:1px solid #ddd; bottom:0; height:92px; margin-left:-32px; margin-right:-32px; padding-left:32px; padding-right:32px; position:absolute; width:100%; z-index:1; } .editor-start-template-options__modal .block-editor-block-patterns-list{ padding-bottom:92px; } .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:2; column-gap:24px; } @media (min-width:782px){ .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:3; } } @media (min-width:1280px){ .editor-start-template-options__modal-content .block-editor-block-patterns-list{ column-count:4; } } .editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ break-inside:avoid-column; } .editor-start-template-options__modal-content .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item .block-editor-block-patterns-list__item-title{ display:none; } .components-panel__header.editor-sidebar__panel-tabs{ padding-left:0; padding-right:8px; } .components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{ padding:0; } @media (min-width:782px){ .components-panel__header.editor-sidebar__panel-tabs .components-button.has-icon{ display:flex; } } .editor-post-summary .components-v-stack:empty{ display:none; } .editor-site-discussion-dropdown__content .components-popover__content{ min-width:320px; padding:16px; } .table-of-contents__popover.components-popover .components-popover__content{ min-width:380px; } .components-popover.table-of-contents__popover{ z-index:99998; } .table-of-contents__popover .components-popover__content{ padding:16px; } @media (min-width:600px){ .table-of-contents__popover .components-popover__content{ max-height:calc(100vh - 120px); overflow-y:auto; } } .table-of-contents__popover hr{ margin:10px -16px 0; } .table-of-contents__wrapper:focus:before{ bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; display:block; left:0; pointer-events:none; position:absolute; right:0; top:0; } .table-of-contents__counts{ display:flex; flex-wrap:wrap; margin:-8px 0 0; } .table-of-contents__count{ color:#1e1e1e; display:flex; flex-basis:33%; flex-direction:column; font-size:13px; margin-bottom:0; margin-top:8px; padding-right:8px; } .table-of-contents__count:nth-child(4n){ padding-right:0; } .table-of-contents__number,.table-of-contents__popover .word-count{ color:#1e1e1e; font-size:21px; font-weight:400; line-height:30px; } .table-of-contents__title{ display:block; font-size:15px; font-weight:600; margin-top:20px; } .editor-text-editor{ background-color:#fff; flex-grow:1; position:relative; width:100%; } .editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){ border:1px solid #949494; border-radius:0; font-family:Menlo,Consolas,monaco,monospace; font-size:2.5em; font-weight:400; line-height:1.4; max-width:none; padding:16px; } @media (min-width:600px){ .editor-text-editor .editor-post-title.is-raw-text textarea,.editor-text-editor .editor-post-title:not(.is-raw-text){ padding:24px; } } .editor-text-editor .editor-post-title.is-raw-text textarea:focus,.editor-text-editor .editor-post-title:not(.is-raw-text):focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .editor-text-editor__body{ margin-left:auto; margin-right:auto; max-width:1080px; padding:0 12px 12px; width:100%; } @media (min-width:960px){ .editor-text-editor__body{ padding:0 24px 24px; } } .editor-text-editor__toolbar{ background:#fffc; display:flex; left:0; padding:4px 12px; position:sticky; right:0; top:0; z-index:1; } @media (min-width:600px){ .editor-text-editor__toolbar{ padding:12px; } } @media (min-width:960px){ .editor-text-editor__toolbar{ padding:12px 24px; } } .editor-text-editor__toolbar h2{ color:#1e1e1e; font-size:13px; line-height:40px; margin:0 auto 0 0; } .editor-visual-editor{ align-items:center; background-color:#ddd; display:flex; position:relative; } .editor-visual-editor iframe[name=editor-canvas]{ background-color:initial; } .editor-visual-editor.is-resizable{ max-height:100%; } .editor-visual-editor.has-padding{ padding:24px 24px 0; } .editor-visual-editor.is-iframed{ overflow:hidden; } .editor-visual-editor .components-button{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; padding:6px 12px; } .editor-visual-editor .components-button.has-icon,.editor-visual-editor .components-button.is-tertiary{ padding:6px; } .editor-fields-content-preview{ border-radius:4px; display:flex; flex-direction:column; height:100%; } .dataviews-view-table .editor-fields-content-preview{ flex-grow:0; width:96px; } .editor-fields-content-preview .block-editor-block-preview__container,.editor-fields-content-preview .editor-fields-content-preview__empty{ margin-bottom:auto; margin-top:auto; } .editor-fields-content-preview__empty{ text-align:center; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.list-reusable-blocks-import-dropdown__content .components-popover__content{padding:10px}[class].list-reusable-blocks-import-dropdown__button{height:30px}.list-reusable-blocks-import-form__label{display:block;margin-bottom:10px}.list-reusable-blocks-import-form__button{float:left;margin-top:10px}.list-reusable-blocks-import-form .components-notice__content{margin:0}.list-reusable-blocks-import-form .components-notice.is-dismissible{margin:5px 0;padding-left:0}.list-reusable-blocks__container{align-items:center;display:inline-flex;position:relative;top:-3px}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.list-reusable-blocks-import-dropdown__content .components-popover__content{padding:10px}[class].list-reusable-blocks-import-dropdown__button{height:30px}.list-reusable-blocks-import-form__label{display:block;margin-bottom:10px}.list-reusable-blocks-import-form__button{float:right;margin-top:10px}.list-reusable-blocks-import-form .components-notice__content{margin:0}.list-reusable-blocks-import-form .components-notice.is-dismissible{margin:5px 0;padding-right:0}.list-reusable-blocks__container{align-items:center;display:inline-flex;position:relative;top:-3px}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .list-reusable-blocks-import-dropdown__content .components-popover__content{ padding:10px; } [class].list-reusable-blocks-import-dropdown__button{ height:30px; } .list-reusable-blocks-import-form__label{ display:block; margin-bottom:10px; } .list-reusable-blocks-import-form__button{ float:left; margin-top:10px; } .list-reusable-blocks-import-form .components-notice__content{ margin:0; } .list-reusable-blocks-import-form .components-notice.is-dismissible{ margin:5px 0; padding-left:0; } .list-reusable-blocks__container{ align-items:center; display:inline-flex; position:relative; top:-3px; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .list-reusable-blocks-import-dropdown__content .components-popover__content{ padding:10px; } [class].list-reusable-blocks-import-dropdown__button{ height:30px; } .list-reusable-blocks-import-form__label{ display:block; margin-bottom:10px; } .list-reusable-blocks-import-form__button{ float:right; margin-top:10px; } .list-reusable-blocks-import-form .components-notice__content{ margin:0; } .list-reusable-blocks-import-form .components-notice.is-dismissible{ margin:5px 0; padding-right:0; } .list-reusable-blocks__container{ align-items:center; display:inline-flex; position:relative; top:-3px; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }@charset "UTF-8";:root{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}@media not (prefers-reduced-motion){.components-animate__appear{animation:components-animate__appear-animation .1s cubic-bezier(0,0,.2,1) 0s;animation-fill-mode:forwards}}.components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{transform-origin:top right}.components-animate__appear.is-from-top.is-from-right{transform-origin:top left}.components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{transform-origin:bottom right}.components-animate__appear.is-from-bottom.is-from-right{transform-origin:bottom left}@keyframes components-animate__appear-animation{0%{transform:translateY(-2em) scaleY(0) scaleX(0)}to{transform:translateY(0) scaleY(1) scaleX(1)}}@media not (prefers-reduced-motion){.components-animate__slide-in{animation:components-animate__slide-in-animation .1s cubic-bezier(0,0,.2,1);animation-fill-mode:forwards}.components-animate__slide-in.is-from-left{transform:translateX(-100%)}.components-animate__slide-in.is-from-right{transform:translateX(100%)}}@keyframes components-animate__slide-in-animation{to{transform:translateX(0)}}@media not (prefers-reduced-motion){.components-animate__loading{animation:components-animate__loading 1.6s ease-in-out infinite}}@keyframes components-animate__loading{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.components-autocomplete__popover .components-popover__content{min-width:200px;padding:8px}.components-autocomplete__result.components-button{display:flex;height:auto;min-height:36px;text-align:right;width:100%}.components-autocomplete__result.components-button:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.components-badge{align-items:center;background-color:color-mix(in srgb,#fff 90%,var(--base-color));border-radius:2px;box-sizing:border-box;color:color-mix(in srgb,#000 50%,var(--base-color));display:inline-flex;font-size:12px;font-weight:400;gap:2px;line-height:20px;max-width:100%;min-height:24px;padding:0 8px}.components-badge *,.components-badge :after,.components-badge :before{box-sizing:inherit}.components-badge:where(.is-default){background-color:#f0f0f0;color:#2f2f2f}.components-badge.has-icon{padding-inline-start:4px}.components-badge.is-info{--base-color:#3858e9}.components-badge.is-warning{--base-color:#f0b849}.components-badge.is-error{--base-color:#cc1818}.components-badge.is-success{--base-color:#4ab866}.components-badge__icon{flex-shrink:0}.components-badge__content{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.components-button-group{display:inline-block}.components-button-group .components-button{border-radius:0;box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e;display:inline-flex}.components-button-group .components-button+.components-button{margin-right:-1px}.components-button-group .components-button:first-child{border-radius:0 2px 2px 0}.components-button-group .components-button:last-child{border-radius:2px 0 0 2px}.components-button-group .components-button.is-primary,.components-button-group .components-button:focus{position:relative;z-index:1}.components-button-group .components-button.is-primary{box-shadow:inset 0 0 0 1px #1e1e1e}.components-button{align-items:center;-webkit-appearance:none;background:none;border:0;border-radius:2px;box-sizing:border-box;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;height:36px;margin:0;padding:6px 12px;text-decoration:none}@media not (prefers-reduced-motion){.components-button{transition:box-shadow .1s linear}}.components-button.is-next-40px-default-size{height:40px}.components-button:hover:not(:disabled,[aria-disabled=true]),.components-button[aria-expanded=true]{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:3px solid #0000}.components-button.is-primary{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:var(--wp-components-color-accent-inverted,#fff);outline:1px solid #0000;text-decoration:none;text-shadow:none;white-space:nowrap}.components-button.is-primary:hover:not(:disabled){background:var(--wp-components-color-accent-darker-10,var(--wp-admin-theme-color-darker-10,#2145e6));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-primary:active:not(:disabled){background:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));border-color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-primary:focus:not(:disabled){box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#fff6;outline:none}.components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{background-image:linear-gradient(45deg,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 33%,var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6)) 33%,var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6)) 70%,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 70%);background-size:100px 100%;border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-secondary,.components-button.is-tertiary{outline:1px solid #0000}.components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){box-shadow:none}.components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{background:#0000;color:#949494;transform:none}.components-button.is-secondary{background:#0000;box-shadow:inset 0 0 0 1px var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),0 0 0 currentColor;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:1px solid #0000;white-space:nowrap}.components-button.is-secondary:hover:not(:disabled,[aria-disabled=true],.is-pressed){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 4%,#0000);box-shadow:inset 0 0 0 1px var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6))}.components-button.is-secondary:disabled:not(:focus),.components-button.is-secondary[aria-disabled=true]:hover:not(:focus),.components-button.is-secondary[aria-disabled=true]:not(:focus){box-shadow:inset 0 0 0 1px #ddd}.components-button.is-secondary:focus:not(:disabled){box-shadow:0 0 0 currentColor inset,0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-tertiary{background:#0000;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));white-space:nowrap}.components-button.is-tertiary:hover:not(:disabled,[aria-disabled=true],.is-pressed){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 4%,#0000);color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6))}.components-button.is-tertiary:active:not(:disabled,[aria-disabled=true]){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 8%,#0000)}p+.components-button.is-tertiary{margin-right:-6px}.components-button.is-tertiary:disabled:not(:focus),.components-button.is-tertiary[aria-disabled=true]:hover:not(:focus),.components-button.is-tertiary[aria-disabled=true]:not(:focus){box-shadow:none;outline:none}.components-button.is-destructive{--wp-components-color-accent:#cc1818;--wp-components-color-accent-darker-10:#9e1313;--wp-components-color-accent-darker-20:#710d0d}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link){color:#cc1818}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):hover:not(:disabled,[aria-disabled=true]){color:#710d0d}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #cc1818}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):active:not(:disabled,[aria-disabled=true]){background:#ccc}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):disabled,.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link)[aria-disabled=true]{color:#949494}.components-button.is-destructive.is-secondary:hover:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:hover:not(:disabled,[aria-disabled=true]){background:#cc18180a}.components-button.is-destructive.is-secondary:active:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:active:not(:disabled,[aria-disabled=true]){background:#cc181814}.components-button.is-link{background:none;border:0;border-radius:0;box-shadow:none;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));height:auto;margin:0;outline:none;padding:0;text-align:right;text-decoration:underline}@media not (prefers-reduced-motion){.components-button.is-link{transition-duration:.05s;transition-property:border,background,color;transition-timing-function:ease-in-out}}.components-button.is-link:focus{border-radius:2px}.components-button.is-link:disabled,.components-button.is-link[aria-disabled=true]{color:#949494}.components-button:not(:disabled,[aria-disabled=true]):active{color:var(--wp-components-color-foreground,#1e1e1e)}.components-button:disabled,.components-button[aria-disabled=true]{color:#949494;cursor:default}.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{background-image:linear-gradient(45deg,#fafafa 33%,#e0e0e0 0,#e0e0e0 70%,#fafafa 0);background-size:100px 100%}@media not (prefers-reduced-motion){.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{animation:components-button__busy-animation 2.5s linear infinite}}.components-button.is-compact{height:32px}.components-button.is-compact.has-icon:not(.has-text){min-width:32px;padding:0;width:32px}.components-button.is-small{font-size:11px;height:24px;line-height:22px;padding:0 8px}.components-button.is-small.has-icon:not(.has-text){min-width:24px;padding:0;width:24px}.components-button.has-icon{justify-content:center;min-width:36px;padding:6px}.components-button.has-icon.is-next-40px-default-size{min-width:40px}.components-button.has-icon .dashicon{align-items:center;box-sizing:initial;display:inline-flex;justify-content:center;padding:2px}.components-button.has-icon.has-text{gap:4px;justify-content:start;padding-left:12px;padding-right:8px}.components-button.is-pressed,.components-button.is-pressed:hover{color:var(--wp-components-color-foreground-inverted,#fff)}.components-button.is-pressed:hover:not(:disabled,[aria-disabled=true]),.components-button.is-pressed:not(:disabled,[aria-disabled=true]){background:var(--wp-components-color-foreground,#1e1e1e)}.components-button.is-pressed:disabled,.components-button.is-pressed[aria-disabled=true]{color:#949494}.components-button.is-pressed:disabled:not(.is-primary):not(.is-secondary):not(.is-tertiary),.components-button.is-pressed[aria-disabled=true]:not(.is-primary):not(.is-secondary):not(.is-tertiary){background:#949494;color:var(--wp-components-color-foreground-inverted,#fff)}.components-button.is-pressed:focus:not(:disabled){box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000}.components-button svg{fill:currentColor;outline:none}@media (forced-colors:active){.components-button svg{fill:CanvasText}}.components-button .components-visually-hidden{height:auto}@keyframes components-button__busy-animation{0%{background-position:right 200px top 0}}.components-checkbox-control{--checkbox-input-size:24px;--checkbox-input-margin:8px}@media (min-width:600px){.components-checkbox-control{--checkbox-input-size:16px}}.components-checkbox-control__label{cursor:pointer;line-height:var(--checkbox-input-size)}.components-checkbox-control__input[type=checkbox]{appearance:none;background:#fff;border:1px solid #1e1e1e;border-radius:2px;box-shadow:0 0 0 #0000;clear:none;color:#1e1e1e;cursor:pointer;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:var(--checkbox-input-size);line-height:normal;line-height:0;margin:0 0 0 4px;outline:0;padding:6px 8px;padding:0!important;text-align:center;transition:none;vertical-align:top;width:var(--checkbox-input-size)}@media not (prefers-reduced-motion){.components-checkbox-control__input[type=checkbox]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{font-size:13px;line-height:normal}}.components-checkbox-control__input[type=checkbox]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]::-moz-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked{background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{color:#fff;margin:-3px -5px}@media (min-width:782px){.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-4px -5px 0 0}}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]{background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{content:"\f460";display:inline-block;float:right;font:normal 30px/1 dashicons;vertical-align:middle;width:16px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (min-width:782px){.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{float:none;font-size:21px}}.components-checkbox-control__input[type=checkbox]:disabled,.components-checkbox-control__input[type=checkbox][aria-disabled=true]{background:#f0f0f0;border-color:#ddd;cursor:default;opacity:1}@media not (prefers-reduced-motion){.components-checkbox-control__input[type=checkbox]{transition:border-color .1s ease-in-out}}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.components-checkbox-control__input[type=checkbox]:checked,.components-checkbox-control__input[type=checkbox]:indeterminate{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-checkbox-control__input[type=checkbox]:checked::-ms-check,.components-checkbox-control__input[type=checkbox]:indeterminate::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before{content:none}.components-checkbox-control__input-container{aspect-ratio:1;display:inline-block;flex-shrink:0;line-height:1;margin-left:var(--checkbox-input-margin);position:relative;vertical-align:middle;width:var(--checkbox-input-size)}svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{--checkmark-size:var(--checkbox-input-size);fill:#fff;cursor:pointer;height:var(--checkmark-size);pointer-events:none;position:absolute;right:50%;top:50%;transform:translate(50%,-50%);-webkit-user-select:none;user-select:none;width:var(--checkmark-size)}@media (min-width:600px){svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{--checkmark-size:calc(var(--checkbox-input-size) + 4px)}}.components-checkbox-control__help{display:inline-block;margin-inline-start:calc(var(--checkbox-input-size) + var(--checkbox-input-margin))}.components-circular-option-picker{display:inline-block;min-width:188px;width:100%}.components-circular-option-picker .components-circular-option-picker__custom-clear-wrapper{display:flex;justify-content:flex-end;margin-top:12px}.components-circular-option-picker .components-circular-option-picker__swatches{display:flex;flex-wrap:wrap;gap:12px;position:relative;z-index:1}.components-circular-option-picker>:not(.components-circular-option-picker__swatches){position:relative;z-index:0}.components-circular-option-picker__option-wrapper{display:inline-block;height:28px;transform:scale(1);vertical-align:top;width:28px}@media not (prefers-reduced-motion){.components-circular-option-picker__option-wrapper{transition:transform .1s ease;will-change:transform}}.components-circular-option-picker__option-wrapper:hover{transform:scale(1.2)}.components-circular-option-picker__option-wrapper>div{height:100%;width:100%}.components-circular-option-picker__option-wrapper:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none'%3E%3Cpath fill='%23555D65' d='M6 8V6H4v2zm2 0V6h2v2zm2 8H8v-2h2zm2 0v-2h2v2zm0 2v-2h-2v2H8v2h2v-2zm2 0v2h-2v-2zm2 0h-2v-2h2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M18 18h2v-2h-2v-2h2v-2h-2v-2h2V8h-2v2h-2V8h-2v2h2v2h-2v2h2v2h2zm-2-4v-2h2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' d='M18 18v2h-2v-2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M8 10V8H6v2H4v2h2v2H4v2h2v2H4v2h2v2H4v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2v2h-2V4h-2v2h-2V4h-2v2h-2V4h-2v2h2v2h-2v2zm0 2v-2H6v2zm2 0v-2h2v2zm0 2v-2H8v2H6v2h2v2H6v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h-2v2h-2V6h-2v2h-2v2h2v2h-2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M4 0H2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2H8V0H6v2H4zm0 4V2H2v2zm2 0V2h2v2zm0 2V4H4v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2H8v2z' clip-rule='evenodd'/%3E%3C/svg%3E");border-radius:50%;bottom:1px;content:"";left:1px;position:absolute;right:1px;top:1px;z-index:-1}.components-circular-option-picker__option{aspect-ratio:1;background:#0000;border:none;border-radius:50%;box-shadow:inset 0 0 0 14px;cursor:pointer;display:inline-block;height:100%!important;vertical-align:top}@media not (prefers-reduced-motion){.components-circular-option-picker__option{transition:box-shadow .1s ease}}.components-circular-option-picker__option:hover{box-shadow:inset 0 0 0 14px!important}.components-circular-option-picker__option[aria-pressed=true],.components-circular-option-picker__option[aria-selected=true]{box-shadow:inset 0 0 0 4px;overflow:visible;position:relative;z-index:1}.components-circular-option-picker__option[aria-pressed=true]+svg,.components-circular-option-picker__option[aria-selected=true]+svg{border-radius:50%;pointer-events:none;position:absolute;right:2px;top:2px;z-index:2}.components-circular-option-picker__option:after{border:1px solid #0000;border-radius:50%;bottom:-1px;box-shadow:inset 0 0 0 1px #0003;box-sizing:inherit;content:"";left:-1px;position:absolute;right:-1px;top:-1px}.components-circular-option-picker__option:focus:after{border:2px solid #757575;border-radius:50%;box-shadow:inset 0 0 0 2px #fff;content:"";height:calc(100% + 4px);position:absolute;right:50%;top:50%;transform:translate(50%,-50%);width:calc(100% + 4px)}.components-circular-option-picker__option.components-button:focus{background-color:initial;box-shadow:inset 0 0 0 14px;outline:none}.components-circular-option-picker__button-action .components-circular-option-picker__option{background:#fff;color:#fff}.components-circular-option-picker__dropdown-link-action{margin-left:16px}.components-circular-option-picker__dropdown-link-action .components-button{line-height:22px}.components-palette-edit__popover-gradient-picker{padding:8px;width:260px}.components-dropdown-menu__menu .components-palette-edit__menu-button{width:100%}.component-color-indicator{background:#fff linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);border-radius:50%;box-shadow:inset 0 0 0 1px #0003;display:inline-block;height:20px;padding:0;width:20px}.components-combobox-control{width:100%}input.components-combobox-control__input[type=text]{border:none;box-shadow:none;font-family:inherit;font-size:16px;line-height:inherit;margin:0;min-height:auto;padding:2px;width:100%}@media (min-width:600px){input.components-combobox-control__input[type=text]{font-size:13px}}input.components-combobox-control__input[type=text]:focus{box-shadow:none;outline:none}.components-combobox-control__suggestions-container{align-items:flex-start;border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;display:flex;flex-wrap:wrap;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:0;width:100%}@media not (prefers-reduced-motion){.components-combobox-control__suggestions-container{transition:box-shadow .1s linear}}@media (min-width:600px){.components-combobox-control__suggestions-container{font-size:13px;line-height:normal}}.components-combobox-control__suggestions-container:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-combobox-control__suggestions-container::-webkit-input-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container::-moz-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container:-ms-input-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container:focus-within{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-combobox-control__suggestions-container .components-spinner{margin:0}.components-color-palette__custom-color-wrapper{position:relative;z-index:0}.components-color-palette__custom-color-button{background:none;border:none;border-radius:4px 4px 0 0;box-shadow:inset 0 0 0 1px #0003;box-sizing:border-box;cursor:pointer;height:64px;outline:1px solid #0000;position:relative;width:100%}.components-color-palette__custom-color-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline-width:2px}.components-color-palette__custom-color-button:after{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,24px 24px;background-size:48px 48px;border-radius:3px 3px 0 0;content:"";inset:1px;position:absolute;z-index:-1}.components-color-palette__custom-color-text-wrapper{border-radius:0 0 4px 4px;box-shadow:inset 0 -1px 0 0 #0003,inset -1px 0 0 0 #0003,inset 1px 0 0 0 #0003;font-size:13px;padding:12px 16px;position:relative}.components-color-palette__custom-color-name{color:var(--wp-components-color-foreground,#1e1e1e);margin:0 1px}.components-color-palette__custom-color-value{color:#757575}.components-color-palette__custom-color-value--is-hex{text-transform:uppercase}.components-color-palette__custom-color-value:empty:after{content:"";visibility:hidden}.components-custom-gradient-picker__gradient-bar{border-radius:2px;height:48px;position:relative;width:100%;z-index:1}.components-custom-gradient-picker__gradient-bar.has-gradient{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,12px 12px;background-size:24px 24px}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__gradient-bar-background{inset:0;position:absolute}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__markers-container{margin-left:auto;margin-right:auto;position:relative;width:calc(100% - 48px)}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-dropdown{display:flex;height:16px;position:absolute;top:16px;width:16px}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown{background:#fff;border-radius:50%;color:#1e1e1e;height:inherit;min-width:16px!important;padding:2px;position:relative;width:inherit}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown svg{height:100%;width:100%}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button{border-radius:50%;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 2px 0 #00000040;height:inherit;outline:2px solid #0000;padding:0;width:inherit}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button.is-active,.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button:focus{box-shadow:inset 0 0 0 calc(var(--wp-admin-border-width-focus)*2) #fff,0 0 2px 0 #00000040;outline:1.5px solid #0000}.components-custom-gradient-picker__remove-control-point-wrapper{padding-bottom:8px}.components-custom-gradient-picker__inserter{direction:ltr}.components-custom-gradient-picker__liner-gradient-indicator{display:inline-block;flex:0 auto;height:20px;width:20px}.components-custom-gradient-picker__ui-line{position:relative;z-index:0}.block-editor-dimension-control .components-base-control__field{align-items:center;display:flex}.block-editor-dimension-control .components-base-control__label{align-items:center;display:flex;margin-bottom:0;margin-left:1em}.block-editor-dimension-control .components-base-control__label .dashicon{margin-left:.5em}.block-editor-dimension-control.is-manual .components-base-control__label{width:10em}body.is-dragging-components-draggable{cursor:move;cursor:grabbing!important}.components-draggable__invisible-drag-image{height:50px;position:fixed;right:-1000px;width:50px}.components-draggable__clone{background:#0000;padding:0;pointer-events:none;position:fixed;z-index:1000000000}.components-drop-zone{border-radius:2px;bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;visibility:hidden;z-index:40}.components-drop-zone.is-active{opacity:1;visibility:visible}.components-drop-zone .components-drop-zone__content{align-items:center;background-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));bottom:0;color:#fff;display:flex;height:100%;justify-content:center;left:0;opacity:0;pointer-events:none;position:absolute;right:0;text-align:center;top:0;width:100%;z-index:50}.components-drop-zone .components-drop-zone__content-inner{opacity:0;transform:scale(.9)}.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{opacity:1}@media not (prefers-reduced-motion){.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{transition:opacity .2s ease-in-out}}.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{opacity:1;transform:scale(1)}@media not (prefers-reduced-motion){.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{transition:opacity .1s ease-in-out .1s,transform .1s ease-in-out .1s}}.components-drop-zone__content-icon,.components-drop-zone__content-text{display:block}.components-drop-zone__content-icon{line-height:0;margin:0 auto 8px;fill:currentColor;pointer-events:none}.components-drop-zone__content-text{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-dropdown{display:inline-block}.components-dropdown__content .components-popover__content{padding:8px}.components-dropdown__content .components-popover__content:has(.components-menu-group){padding:0}.components-dropdown__content .components-popover__content:has(.components-menu-group) .components-dropdown-menu__menu>.components-menu-item__button,.components-dropdown__content .components-popover__content:has(.components-menu-group)>.components-menu-item__button{margin:8px;width:auto}.components-dropdown__content [role=menuitem]{white-space:nowrap}.components-dropdown__content .components-menu-group{padding:8px}.components-dropdown__content .components-menu-group+.components-menu-group{border-top:1px solid #ccc;padding:8px}.components-dropdown__content.is-alternate .components-menu-group+.components-menu-group{border-color:#1e1e1e}.components-dropdown-menu__toggle{vertical-align:top}.components-dropdown-menu__menu{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:1.4;width:100%}.components-dropdown-menu__menu .components-dropdown-menu__menu-item,.components-dropdown-menu__menu .components-menu-item{cursor:pointer;outline:none;padding:6px;white-space:nowrap;width:100%}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator,.components-dropdown-menu__menu .components-menu-item.has-separator{margin-top:6px;overflow:visible;position:relative}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator:before,.components-dropdown-menu__menu .components-menu-item.has-separator:before{background-color:#ddd;box-sizing:initial;content:"";display:block;height:1px;left:0;position:absolute;right:0;top:-3px}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active svg,.components-dropdown-menu__menu .components-menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-menu-item.is-active svg{background:#1e1e1e;border-radius:1px;box-shadow:0 0 0 1px #1e1e1e;color:#fff}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-icon-only,.components-dropdown-menu__menu .components-menu-item.is-icon-only{width:auto}.components-dropdown-menu__menu .components-menu-item__button,.components-dropdown-menu__menu .components-menu-item__button.components-button{height:auto;min-height:40px;padding-left:8px;padding-right:8px;text-align:right}.components-duotone-picker__color-indicator:before{background:#0000}.components-duotone-picker__color-indicator>.components-button,.components-duotone-picker__color-indicator>.components-button.is-pressed:hover:not(:disabled){background:linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);color:#0000}.components-duotone-picker__color-indicator>.components-button:not([aria-disabled=true]):active{color:#0000}.components-color-list-picker,.components-color-list-picker__swatch-button{width:100%}.components-color-list-picker__color-picker{margin:8px 0}.components-color-list-picker__swatch-color{margin:2px}.components-external-link{text-decoration:none}.components-external-link__contents{text-decoration:underline}.components-external-link__icon{font-weight:400;margin-right:.5ch}.components-form-toggle{display:inline-block;height:16px;position:relative}.components-form-toggle .components-form-toggle__track{background-color:#fff;border:1px solid #949494;border-radius:8px;box-sizing:border-box;content:"";display:inline-block;height:16px;overflow:hidden;position:relative;vertical-align:top;width:32px}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__track{transition:background-color .2s ease,border-color .2s ease}}.components-form-toggle .components-form-toggle__track:after{border-top:16px solid #0000;box-sizing:border-box;content:"";inset:0;opacity:0;position:absolute}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__track:after{transition:opacity .2s ease}}.components-form-toggle .components-form-toggle__thumb{background-color:#1e1e1e;border:6px solid #0000;border-radius:50%;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;box-sizing:border-box;display:block;height:12px;position:absolute;right:2px;top:2px;width:12px}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__thumb{transition:transform .2s ease,background-color .2s ease-out}}.components-form-toggle.is-checked .components-form-toggle__track{background-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-form-toggle.is-checked .components-form-toggle__track:after{opacity:1}.components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:2px}.components-form-toggle.is-checked .components-form-toggle__thumb{background-color:#fff;border-width:0;transform:translateX(-16px)}.components-disabled .components-form-toggle,.components-form-toggle.is-disabled{opacity:.3}.components-form-toggle input.components-form-toggle__input[type=checkbox]{border:none;height:100%;margin:0;opacity:0;padding:0;position:absolute;right:0;top:0;width:100%;z-index:1}.components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{background:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:before{content:""}.components-form-toggle input.components-form-toggle__input[type=checkbox]:not(:disabled,[aria-disabled=true]){cursor:pointer}.components-form-token-field__input-container{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;cursor:text;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:0;width:100%}@media not (prefers-reduced-motion){.components-form-token-field__input-container{transition:box-shadow .1s linear}}@media (min-width:600px){.components-form-token-field__input-container{font-size:13px;line-height:normal}}.components-form-token-field__input-container:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-form-token-field__input-container::-webkit-input-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container::-moz-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container:-ms-input-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container.is-disabled{background:#ddd;border-color:#ddd}.components-form-token-field__input-container.is-active{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-form-token-field__input-container input[type=text].components-form-token-field__input{background:inherit;border:0;box-shadow:none;color:#1e1e1e;display:inline-block;flex:1;font-family:inherit;font-size:16px;margin-right:4px;max-width:100%;min-height:24px;min-width:50px;padding:0;width:100%}@media (min-width:600px){.components-form-token-field__input-container input[type=text].components-form-token-field__input{font-size:13px}}.components-form-token-field.is-active .components-form-token-field__input-container input[type=text].components-form-token-field__input,.components-form-token-field__input-container input[type=text].components-form-token-field__input:focus{box-shadow:none;outline:none}.components-form-token-field__input-container .components-form-token-field__token+input[type=text].components-form-token-field__input{width:auto}.components-form-token-field__token{color:#1e1e1e;display:flex;font-size:13px;max-width:100%}.components-form-token-field__token.is-success .components-form-token-field__remove-token,.components-form-token-field__token.is-success .components-form-token-field__token-text{background:#4ab866}.components-form-token-field__token.is-error .components-form-token-field__remove-token,.components-form-token-field__token.is-error .components-form-token-field__token-text{background:#cc1818}.components-form-token-field__token.is-validating .components-form-token-field__remove-token,.components-form-token-field__token.is-validating .components-form-token-field__token-text{color:#757575}.components-form-token-field__token.is-borderless{padding:0 0 0 24px;position:relative}.components-form-token-field__token.is-borderless .components-form-token-field__token-text{background:#0000}.components-form-token-field__token.is-borderless:not(.is-disabled) .components-form-token-field__token-text{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-form-token-field__token.is-borderless .components-form-token-field__remove-token{background:#0000;color:#757575;left:0;position:absolute;top:1px}.components-form-token-field__token.is-borderless.is-success .components-form-token-field__token-text{color:#4ab866}.components-form-token-field__token.is-borderless.is-error .components-form-token-field__token-text{color:#cc1818;padding:0 6px 0 4px}.components-form-token-field__token.is-borderless.is-validating .components-form-token-field__token-text{color:#1e1e1e}.components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{background:#ddd;display:inline-block;height:auto;min-width:unset}@media not (prefers-reduced-motion){.components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{transition:all .2s cubic-bezier(.4,1,.4,1)}}.components-form-token-field__token-text{border-radius:0 1px 1px 0;line-height:24px;overflow:hidden;padding:0 8px 0 0;text-overflow:ellipsis;white-space:nowrap}.components-form-token-field__remove-token.components-button{border-radius:1px 0 0 1px;color:#1e1e1e;line-height:10px;overflow:initial}.components-form-token-field__remove-token.components-button:hover:not(:disabled){color:#1e1e1e}.components-form-token-field__suggestions-list{box-shadow:inset 0 1px 0 0 #949494;flex:1 0 100%;list-style:none;margin:0;max-height:128px;min-width:100%;overflow-y:auto;padding:0}@media not (prefers-reduced-motion){.components-form-token-field__suggestions-list{transition:all .15s ease-in-out}}.components-form-token-field__suggestion{box-sizing:border-box;color:#1e1e1e;display:block;font-size:13px;margin:0;min-height:32px;padding:8px 12px}.components-form-token-field__suggestion.is-selected{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#fff}.components-form-token-field__suggestion[aria-disabled=true]{color:#949494;pointer-events:none}.components-form-token-field__suggestion[aria-disabled=true].is-selected{background-color:rgba(var(--wp-components-color-accent--rgb,var(--wp-admin-theme-color--rgb)),.04)}.components-form-token-field__suggestion:not(.is-empty){cursor:pointer}@media (min-width:600px){.components-guide{width:600px}}.components-guide .components-modal__content{margin-top:0;padding:0}.components-guide .components-modal__content:before{content:none}.components-guide .components-modal__header{border-bottom:none;height:60px;padding:0;position:sticky}.components-guide .components-modal__header .components-button{align-self:flex-start;margin:8px 0 0 8px;position:static}.components-guide .components-modal__header .components-button:hover svg{fill:#fff}.components-guide .components-guide__container{display:flex;flex-direction:column;justify-content:space-between;margin-top:-60px;min-height:100%}.components-guide .components-guide__page{display:flex;flex-direction:column;justify-content:center;position:relative}@media (min-width:600px){.components-guide .components-guide__page{min-height:300px}}.components-guide .components-guide__footer{align-content:center;display:flex;height:36px;justify-content:center;margin:0 0 24px;padding:0 32px;position:relative;width:100%}.components-guide .components-guide__page-control{margin:0;text-align:center}.components-guide .components-guide__page-control li{display:inline-block;margin:0}.components-guide .components-guide__page-control .components-button{color:#e0e0e0;margin:-6px 0}.components-guide .components-guide__page-control li[aria-current=step] .components-button{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-modal__frame.components-guide{border:none;max-height:575px;min-width:312px}@media (max-width:600px){.components-modal__frame.components-guide{margin:auto;max-width:calc(100vw - 32px)}}.components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{position:absolute}.components-button.components-guide__back-button{right:32px}.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{left:32px}[role=region]{position:relative}.is-focusing-regions [role=region]:focus:after,[role=region].interface-interface-skeleton__content:focus-visible:after{bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:1000000}.is-focusing-regions .editor-post-publish-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-entities-saved-states-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-publish-panel,.is-focusing-regions .interface-interface-skeleton__sidebar .editor-layout__toggle-sidebar-panel,.is-focusing-regions [role=region]:focus:after,.is-focusing-regions.is-distraction-free .interface-interface-skeleton__header .edit-post-header,[role=region].interface-interface-skeleton__content:focus-visible:after{outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2)}.components-menu-group+.components-menu-group{border-top:1px solid #1e1e1e;padding-top:8px}.components-menu-group+.components-menu-group.has-hidden-separator{border-top:none;margin-top:0;padding-top:0}.components-menu-group:has(>div:empty){display:none}.components-menu-group__label{color:#757575;font-size:11px;font-weight:500;margin-bottom:12px;margin-top:4px;padding:0 8px;text-transform:uppercase;white-space:nowrap}.components-menu-item__button,.components-menu-item__button.components-button{width:100%}.components-menu-item__button.components-button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button.components-button[role=menuitemradio] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemradio] .components-menu-item__item:only-child{box-sizing:initial;padding-left:48px}.components-menu-item__button .components-menu-items__item-icon,.components-menu-item__button.components-button .components-menu-items__item-icon{display:inline-block;flex:0 0 auto}.components-menu-item__button .components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-items__item-icon.has-icon-right{margin-left:-2px;margin-right:24px}.components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right{margin-right:8px}.components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{margin-left:8px;margin-right:-2px}.components-menu-item__button.components-button.is-primary,.components-menu-item__button.is-primary{justify-content:center}.components-menu-item__button.components-button.is-primary .components-menu-item__item,.components-menu-item__button.is-primary .components-menu-item__item{margin-left:0}.components-menu-item__button.components-button:disabled.is-tertiary,.components-menu-item__button.components-button[aria-disabled=true].is-tertiary,.components-menu-item__button:disabled.is-tertiary,.components-menu-item__button[aria-disabled=true].is-tertiary{background:none;color:var(--wp-components-color-accent-darker-10,var(--wp-admin-theme-color-darker-10,#2145e6));opacity:.3}.components-menu-item__info-wrapper{display:flex;flex-direction:column;margin-left:auto}.components-menu-item__info{color:#757575;font-size:12px;margin-top:4px;white-space:normal}.components-menu-item__item{align-items:center;display:inline-flex;margin-left:auto;min-width:160px;white-space:nowrap}.components-menu-item__shortcut{align-self:center;color:currentColor;display:none;margin-left:0;margin-right:auto;padding-right:24px}@media (min-width:480px){.components-menu-item__shortcut{display:inline}}.components-menu-items-choice,.components-menu-items-choice.components-button{height:auto;min-height:40px}.components-menu-items-choice svg,.components-menu-items-choice.components-button svg{margin-left:12px}.components-menu-items-choice.components-button.has-icon,.components-menu-items-choice.has-icon{padding-right:12px}.components-modal__screen-overlay{background-color:#00000059;bottom:0;display:flex;left:0;position:fixed;right:0;top:0;z-index:100000}@keyframes __wp-base-styles-fade-in{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.components-modal__screen-overlay{animation:__wp-base-styles-fade-in .08s linear 0s;animation-fill-mode:forwards}}@keyframes __wp-base-styles-fade-out{0%{opacity:1}to{opacity:0}}@media not (prefers-reduced-motion){.components-modal__screen-overlay.is-animating-out{animation:__wp-base-styles-fade-out .08s linear 80ms;animation-fill-mode:forwards}}.components-modal__frame{animation-fill-mode:forwards;animation-name:components-modal__appear-animation;animation-timing-function:cubic-bezier(.29,0,0,1);background:#fff;border-radius:8px 8px 0 0;box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;box-sizing:border-box;display:flex;margin:40px 0 0;overflow:hidden;width:100%}.components-modal__frame *,.components-modal__frame :after,.components-modal__frame :before{box-sizing:inherit}@media not (prefers-reduced-motion){.components-modal__frame{animation-duration:var(--modal-frame-animation-duration)}}.components-modal__screen-overlay.is-animating-out .components-modal__frame{animation-name:components-modal__disappear-animation;animation-timing-function:cubic-bezier(1,0,.2,1)}@media (min-width:600px){.components-modal__frame{border-radius:8px;margin:auto;max-height:calc(100% - 120px);max-width:calc(100% - 32px);min-width:350px;width:auto}}@media (min-width:600px) and (min-width:600px){.components-modal__frame.is-full-screen{height:calc(100% - 32px);max-height:none;width:calc(100% - 32px)}}@media (min-width:600px) and (min-width:782px){.components-modal__frame.is-full-screen{height:calc(100% - 80px);max-width:none;width:calc(100% - 80px)}}@media (min-width:600px){.components-modal__frame.has-size-large,.components-modal__frame.has-size-medium,.components-modal__frame.has-size-small{width:100%}.components-modal__frame.has-size-small{max-width:384px}.components-modal__frame.has-size-medium{max-width:512px}.components-modal__frame.has-size-large{max-width:840px}}@media (min-width:960px){.components-modal__frame{max-height:70%}}@keyframes components-modal__appear-animation{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes components-modal__disappear-animation{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}.components-modal__header{align-items:center;border-bottom:1px solid #0000;box-sizing:border-box;display:flex;flex-direction:row;height:72px;justify-content:space-between;padding:24px 32px 8px;position:absolute;right:0;top:0;width:100%;z-index:10}.components-modal__header .components-modal__header-heading{font-size:1.2rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__content.has-scrolled-content:not(.hide-header) .components-modal__header{border-bottom-color:#ddd}.components-modal__header+p{margin-top:0}.components-modal__header-heading-container{align-items:center;display:flex;flex-direction:row;flex-grow:1;justify-content:right}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-height:36px;max-width:36px;padding:8px}.components-modal__content{flex:1;margin-top:72px;overflow:auto;padding:4px 32px 32px}.components-modal__content.hide-header{margin-top:0;padding-top:32px}.components-modal__content.is-scrollable:focus-visible{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:-2px}.components-notice{align-items:center;background-color:#fff;border-right:4px solid var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#1e1e1e;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:8px 12px}.components-notice.is-dismissible{position:relative}.components-notice.is-success{background-color:#eff9f1;border-right-color:#4ab866}.components-notice.is-warning{background-color:#fef8ee;border-right-color:#f0b849}.components-notice.is-error{background-color:#f4a2a2;border-right-color:#cc1818}.components-notice__content{flex-grow:1;margin:4px 0 4px 25px}.components-notice__actions{display:flex;flex-wrap:wrap}.components-notice__action.components-button{margin-left:8px}.components-notice__action.components-button,.components-notice__action.components-button.is-link{margin-right:12px}.components-notice__action.components-button.is-secondary{vertical-align:initial}.components-notice__dismiss{align-self:flex-start;color:#757575;flex-shrink:0}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{background-color:initial;color:#1e1e1e}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{box-shadow:none}.components-notice-list{box-sizing:border-box;max-width:100vw}.components-notice-list .components-notice__content{line-height:2;margin-bottom:12px;margin-top:12px}.components-notice-list .components-notice__action.components-button{display:block;margin-right:0;margin-top:8px}.components-panel{background:#fff;border:1px solid #e0e0e0}.components-panel>.components-panel__body:first-child,.components-panel>.components-panel__header:first-child{margin-top:-1px}.components-panel>.components-panel__body:last-child,.components-panel>.components-panel__header:last-child{border-bottom-width:0}.components-panel+.components-panel{margin-top:-1px}.components-panel__body{border-bottom:1px solid #e0e0e0;border-top:1px solid #e0e0e0}.components-panel__body h3{margin:0 0 .5em}.components-panel__body.is-opened{padding:16px}.components-panel__header{align-items:center;border-bottom:1px solid #ddd;box-sizing:initial;display:flex;flex-shrink:0;height:47px;justify-content:space-between;padding:0 16px}.components-panel__header h2{color:inherit;font-size:inherit;margin:0}.components-panel__body+.components-panel__body,.components-panel__body+.components-panel__header,.components-panel__header+.components-panel__body,.components-panel__header+.components-panel__header{margin-top:-1px}.components-panel__body>.components-panel__body-title{display:block;font-size:inherit;margin-bottom:0;margin-top:0;padding:0}@media not (prefers-reduced-motion){.components-panel__body>.components-panel__body-title{transition:background .1s ease-in-out}}.components-panel__body.is-opened>.components-panel__body-title{margin:-16px -16px 5px}.components-panel__body>.components-panel__body-title:hover{background:#f0f0f0;border:none}.components-panel__body-toggle.components-button{border:none;box-shadow:none;color:#1e1e1e;font-weight:500;height:auto;outline:none;padding:16px 16px 16px 48px;position:relative;text-align:right;width:100%}@media not (prefers-reduced-motion){.components-panel__body-toggle.components-button{transition:background .1s ease-in-out}}.components-panel__body-toggle.components-button:focus{border-radius:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-panel__body-toggle.components-button .components-panel__arrow{color:#1e1e1e;left:16px;position:absolute;top:50%;transform:translateY(-50%);fill:currentColor}@media not (prefers-reduced-motion){.components-panel__body-toggle.components-button .components-panel__arrow{transition:color .1s ease-in-out}}body.rtl .components-panel__body-toggle.components-button .dashicons-arrow-right{-ms-filter:fliph;filter:FlipH;margin-top:-10px;transform:scaleX(-1)}.components-panel__icon{color:#757575;margin:-2px 6px -2px 0}.components-panel__body-toggle-icon{margin-left:-5px}.components-panel__color-title{float:right;height:19px}.components-panel__row{align-items:center;display:flex;justify-content:space-between;margin-top:8px;min-height:36px}.components-panel__row select{min-width:0}.components-panel__row label{flex-shrink:0;margin-left:12px;max-width:75%}.components-panel__row:empty,.components-panel__row:first-of-type{margin-top:0}.components-panel .circle-picker{padding-bottom:20px}.components-placeholder.components-placeholder{align-items:flex-start;box-sizing:border-box;color:#1e1e1e;display:flex;flex-direction:column;font-size:13px;gap:16px;margin:0;padding:24px;position:relative;text-align:right;width:100%;-moz-font-smoothing:subpixel-antialiased;-webkit-font-smoothing:subpixel-antialiased;background-color:#fff;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;outline:1px solid #0000}.components-placeholder__error,.components-placeholder__fieldset,.components-placeholder__instructions,.components-placeholder__label{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:400;letter-spacing:normal;line-height:normal;text-transform:none}.components-placeholder__label{align-items:center;display:flex;font-weight:600}.components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{margin-left:4px;fill:currentColor}@media (forced-colors:active){.components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{fill:CanvasText}}.components-placeholder__label:empty{display:none}.components-placeholder__fieldset,.components-placeholder__fieldset form{display:flex;flex-direction:row;flex-wrap:wrap;gap:16px;justify-content:flex-start;width:100%}.components-placeholder__fieldset form p,.components-placeholder__fieldset p{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-placeholder__fieldset.is-column-layout,.components-placeholder__fieldset.is-column-layout form{flex-direction:column}.components-placeholder__input[type=url]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;flex:1 1 auto;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:6px 8px}@media not (prefers-reduced-motion){.components-placeholder__input[type=url]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-placeholder__input[type=url]{font-size:13px;line-height:normal}}.components-placeholder__input[type=url]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-placeholder__input[type=url]::-webkit-input-placeholder{color:#1e1e1e9e}.components-placeholder__input[type=url]::-moz-placeholder{color:#1e1e1e9e}.components-placeholder__input[type=url]:-ms-input-placeholder{color:#1e1e1e9e}.components-placeholder__error{gap:8px;width:100%}.components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link{margin-left:10px;margin-right:10px}.components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link:last-child{margin-left:0}.components-placeholder.is-medium .components-placeholder__instructions,.components-placeholder.is-small .components-placeholder__instructions{display:none}.components-placeholder.is-medium .components-placeholder__fieldset,.components-placeholder.is-medium .components-placeholder__fieldset form,.components-placeholder.is-small .components-placeholder__fieldset,.components-placeholder.is-small .components-placeholder__fieldset form{flex-direction:column}.components-placeholder.is-medium .components-button,.components-placeholder.is-medium .components-placeholder__fieldset>*,.components-placeholder.is-small .components-button,.components-placeholder.is-small .components-placeholder__fieldset>*{justify-content:center;width:100%}.components-placeholder.is-small{padding:16px}.components-placeholder.has-illustration{-webkit-backdrop-filter:blur(100px);backdrop-filter:blur(100px);backface-visibility:hidden;background-color:initial;border-radius:0;box-shadow:none;color:inherit;display:flex;overflow:hidden}.is-dark-theme .components-placeholder.has-illustration{background-color:#0000001a}.components-placeholder.has-illustration .components-placeholder__fieldset{margin-left:0;margin-right:0}.components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{opacity:0;pointer-events:none}@media not (prefers-reduced-motion){.components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{transition:opacity .1s linear}}.is-selected>.components-placeholder.has-illustration .components-button,.is-selected>.components-placeholder.has-illustration .components-placeholder__instructions,.is-selected>.components-placeholder.has-illustration .components-placeholder__label{opacity:1;pointer-events:auto}.components-placeholder.has-illustration:before{background:currentColor;bottom:0;content:"";left:0;opacity:.1;pointer-events:none;position:absolute;right:0;top:0}.is-selected .components-placeholder.has-illustration{overflow:auto}.components-placeholder__preview{display:flex;justify-content:center}.components-placeholder__illustration{box-sizing:initial;height:100%;position:absolute;right:50%;top:50%;transform:translate(50%,-50%);width:100%;stroke:currentColor;opacity:.25}.components-popover{box-sizing:border-box;will-change:transform;z-index:1000000}.components-popover *,.components-popover :after,.components-popover :before{box-sizing:inherit}.components-popover.is-expanded{bottom:0;left:0;position:fixed;right:0;top:0;z-index:1000000!important}.components-popover__content{background:#fff;border-radius:4px;box-shadow:0 0 0 1px #ccc,0 2px 3px #0000000d,0 4px 5px #0000000a,0 12px 12px #00000008,0 16px 16px #00000005;box-sizing:border-box;width:min-content}.is-alternate .components-popover__content{border-radius:2px;box-shadow:0 0 0 1px #1e1e1e}.is-unstyled .components-popover__content{background:none;border-radius:0;box-shadow:none}.components-popover.is-expanded .components-popover__content{box-shadow:0 -1px 0 0 #ccc;height:calc(100% - 48px);overflow-y:visible;position:static;width:auto}.components-popover.is-expanded.is-alternate .components-popover__content{box-shadow:0 -1px 0 #1e1e1e}.components-popover__header{align-items:center;background:#fff;display:flex;height:48px;justify-content:space-between;padding:0 16px 0 8px}.components-popover__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.components-popover__close.components-button{z-index:5}.components-popover__arrow{display:flex;height:14px;pointer-events:none;position:absolute;width:14px}.components-popover__arrow:before{background-color:#fff;content:"";height:2px;left:1px;position:absolute;right:1px;top:-1px}.components-popover__arrow.is-top{bottom:-14px!important;transform:rotate(0)}.components-popover__arrow.is-right{left:-14px!important;transform:rotate(90deg)}.components-popover__arrow.is-bottom{top:-14px!important;transform:rotate(180deg)}.components-popover__arrow.is-left{right:-14px!important;transform:rotate(-90deg)}.components-popover__triangle{display:block;flex:1}.components-popover__triangle-bg{fill:#fff}.components-popover__triangle-border{fill:#0000;stroke-width:1px;stroke:#ccc}.is-alternate .components-popover__triangle-border{stroke:#1e1e1e}.components-radio-control{border:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;margin:0;padding:0}.components-radio-control__group-wrapper.has-help{margin-block-end:12px}.components-radio-control__option{align-items:center;column-gap:8px;display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto minmax(0,max-content)}.components-radio-control__input[type=radio]{appearance:none;border:1px solid #1e1e1e;border-radius:2px;border-radius:50%;box-shadow:0 0 0 #0000;cursor:pointer;display:inline-flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;grid-column:1;grid-row:1;height:24px;line-height:normal;margin:0;max-width:24px;min-width:24px;padding:0;position:relative;transition:none;width:24px}@media not (prefers-reduced-motion){.components-radio-control__input[type=radio]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-radio-control__input[type=radio]{font-size:13px;line-height:normal}}.components-radio-control__input[type=radio]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]::-webkit-input-placeholder{color:#1e1e1e9e}.components-radio-control__input[type=radio]::-moz-placeholder{color:#1e1e1e9e}.components-radio-control__input[type=radio]:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.components-radio-control__input[type=radio]{height:16px;max-width:16px;min-width:16px;width:16px}}.components-radio-control__input[type=radio]:checked:before{background-color:#fff;border:4px solid #fff;box-sizing:inherit;height:12px;margin:0;position:absolute;right:50%;top:50%;transform:translate(50%,-50%);width:12px}@media (min-width:600px){.components-radio-control__input[type=radio]:checked:before{height:8px;width:8px}}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]:checked{background:var(--wp-admin-theme-color);border:none}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.components-radio-control__input[type=radio]:checked{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-radio-control__input[type=radio]:checked:before{border-radius:50%;content:""}.components-radio-control__label{cursor:pointer;grid-column:2;grid-row:1;line-height:24px}@media (min-width:600px){.components-radio-control__label{line-height:16px}}.components-radio-control__option-description{grid-column:2;grid-row:2;padding-block-start:4px}.components-radio-control__option-description.components-radio-control__option-description{margin-top:0}.components-resizable-box__handle{display:none;height:23px;width:23px;z-index:2}.components-resizable-box__container.has-show-handle .components-resizable-box__handle{display:block}.components-resizable-box__handle>div{height:100%;outline:none;position:relative;width:100%;z-index:2}.components-resizable-box__container>img{width:inherit}.components-resizable-box__handle:after{background:#fff;border-radius:50%;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;content:"";cursor:inherit;display:block;height:15px;left:calc(50% - 8px);outline:2px solid #0000;position:absolute;top:calc(50% - 8px);width:15px}.components-resizable-box__side-handle:before{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-radius:9999px;content:"";cursor:inherit;display:block;height:3px;left:calc(50% - 1px);opacity:0;position:absolute;top:calc(50% - 1px);width:3px}@media not (prefers-reduced-motion){.components-resizable-box__side-handle:before{transition:transform .1s ease-in;will-change:transform}}.components-resizable-box__corner-handle,.components-resizable-box__side-handle{z-index:2}.components-resizable-box__side-handle.components-resizable-box__handle-bottom,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:before,.components-resizable-box__side-handle.components-resizable-box__handle-top,.components-resizable-box__side-handle.components-resizable-box__handle-top:before{border-left:0;border-right:0;right:0;width:100%}.components-resizable-box__side-handle.components-resizable-box__handle-left,.components-resizable-box__side-handle.components-resizable-box__handle-left:before,.components-resizable-box__side-handle.components-resizable-box__handle-right,.components-resizable-box__side-handle.components-resizable-box__handle-right:before{border-bottom:0;border-top:0;height:100%;top:0}@media not (prefers-reduced-motion){.components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{animation:components-resizable-box__top-bottom-animation .1s ease-out 0s;animation-fill-mode:forwards}.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before{animation:components-resizable-box__left-right-animation .1s ease-out 0s;animation-fill-mode:forwards}}@media not all and (min-resolution:0.001dpcm){@supports (-webkit-appearance:none){.components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{animation:none}}}@keyframes components-resizable-box__top-bottom-animation{0%{opacity:0;transform:scaleX(0)}to{opacity:1;transform:scaleX(1)}}@keyframes components-resizable-box__left-right-animation{0%{opacity:0;transform:scaleY(0)}to{opacity:1;transform:scaleY(1)}}.components-resizable-box__handle-right{right:-11.5px}.components-resizable-box__handle-left{left:-11.5px}.components-resizable-box__handle-top{top:-11.5px}.components-resizable-box__handle-bottom{bottom:-11.5px}.components-responsive-wrapper{align-items:center;display:flex;justify-content:center;max-width:100%;position:relative}.components-responsive-wrapper__content{display:block;max-width:100%;width:100%}.components-sandbox{overflow:hidden}iframe.components-sandbox{width:100%}body.lockscroll,html.lockscroll{overflow:hidden}.components-select-control__input{outline:0;-webkit-tap-highlight-color:rgba(0,0,0,0)!important}@media (max-width:782px){.components-base-control .components-base-control__field .components-select-control__input{font-size:16px}}.components-snackbar{-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background:#000000d9;border-radius:4px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;box-sizing:border-box;color:#fff;cursor:pointer;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;max-width:600px;padding:12px 20px;pointer-events:auto;width:100%}@media (min-width:600px){.components-snackbar{width:fit-content}}.components-snackbar:focus{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-snackbar.components-snackbar-explicit-dismiss{cursor:default}.components-snackbar .components-snackbar__content-with-icon{padding-right:24px;position:relative}.components-snackbar .components-snackbar__icon{position:absolute;right:-8px;top:-2.9px}.components-snackbar .components-snackbar__dismiss-button{cursor:pointer;margin-right:24px}.components-snackbar__action.components-button{color:#fff;flex-shrink:0;margin-right:32px}.components-snackbar__action.components-button:focus{box-shadow:none;outline:1px dotted #fff}.components-snackbar__action.components-button:hover{color:currentColor;text-decoration:none}.components-snackbar__content{align-items:baseline;display:flex;justify-content:space-between;line-height:1.4}.components-snackbar-list{box-sizing:border-box;pointer-events:none;position:absolute;width:100%;z-index:100000}.components-snackbar-list__notice-container{padding-top:8px;position:relative}.components-tab-panel__tabs{align-items:stretch;display:flex;flex-direction:row}.components-tab-panel__tabs[aria-orientation=vertical]{flex-direction:column}.components-tab-panel__tabs-item{background:#0000;border:none;border-radius:0;box-shadow:none;cursor:pointer;font-weight:500;height:48px!important;margin-right:0;padding:3px 16px;position:relative}.components-tab-panel__tabs-item:focus:not(:disabled){box-shadow:none;outline:none;position:relative}.components-tab-panel__tabs-item:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-radius:0;bottom:0;content:"";height:calc(var(--wp-admin-border-width-focus)*0);left:0;pointer-events:none;position:absolute;right:0}@media not (prefers-reduced-motion){.components-tab-panel__tabs-item:after{transition:all .1s linear}}.components-tab-panel__tabs-item.is-active:after{height:calc(var(--wp-admin-border-width-focus)*1);outline:2px solid #0000;outline-offset:-1px}.components-tab-panel__tabs-item:before{border-radius:2px;bottom:12px;box-shadow:0 0 0 0 #0000;content:"";left:12px;pointer-events:none;position:absolute;right:12px;top:12px}@media not (prefers-reduced-motion){.components-tab-panel__tabs-item:before{transition:all .1s linear}}.components-tab-panel__tabs-item:focus-visible:before{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000}.components-tab-panel__tab-content:focus{box-shadow:none;outline:none}.components-tab-panel__tab-content:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:0}.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin:0;padding:6px 8px;width:100%}@media not (prefers-reduced-motion){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{font-size:13px;line-height:normal}}.components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{color:#1e1e1e9e}.components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{color:#1e1e1e9e}.components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{color:#1e1e1e9e}.components-text-control__input.is-next-40px-default-size,.components-text-control__input[type=color].is-next-40px-default-size,.components-text-control__input[type=date].is-next-40px-default-size,.components-text-control__input[type=datetime-local].is-next-40px-default-size,.components-text-control__input[type=datetime].is-next-40px-default-size,.components-text-control__input[type=email].is-next-40px-default-size,.components-text-control__input[type=month].is-next-40px-default-size,.components-text-control__input[type=number].is-next-40px-default-size,.components-text-control__input[type=password].is-next-40px-default-size,.components-text-control__input[type=tel].is-next-40px-default-size,.components-text-control__input[type=text].is-next-40px-default-size,.components-text-control__input[type=time].is-next-40px-default-size,.components-text-control__input[type=url].is-next-40px-default-size,.components-text-control__input[type=week].is-next-40px-default-size{height:40px;padding-left:12px;padding-right:12px}.components-text-control__input[type=email],.components-text-control__input[type=url]{direction:ltr}.components-tip{color:#757575;display:flex}.components-tip svg{align-self:center;fill:#f0b849;flex-shrink:0;margin-left:16px}.components-tip p{margin:0}.components-toggle-control__label{line-height:16px}.components-toggle-control__label:not(.is-disabled){cursor:pointer}.components-toggle-control__help{display:inline-block;margin-inline-start:40px}.components-accessible-toolbar{border:1px solid #1e1e1e;border-radius:2px;display:inline-flex;flex-shrink:0}.components-accessible-toolbar>.components-toolbar-group:last-child{border-left:none}.components-accessible-toolbar.is-unstyled{border:none}.components-accessible-toolbar.is-unstyled>.components-toolbar-group{border-left:none}.components-accessible-toolbar[aria-orientation=vertical],.components-toolbar[aria-orientation=vertical]{align-items:center;display:flex;flex-direction:column}.components-accessible-toolbar .components-button,.components-toolbar .components-button{height:48px;padding-left:16px;padding-right:16px;position:relative;z-index:1}.components-accessible-toolbar .components-button:focus:not(:disabled),.components-toolbar .components-button:focus:not(:disabled){box-shadow:none;outline:none}.components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.components-accessible-toolbar .components-button svg,.components-toolbar .components-button svg{margin-left:auto;margin-right:auto;position:relative}.components-accessible-toolbar .components-button.is-pressed,.components-accessible-toolbar .components-button.is-pressed:hover,.components-toolbar .components-button.is-pressed,.components-toolbar .components-button.is-pressed:hover{background:#0000}.components-accessible-toolbar .components-button.is-pressed:before,.components-toolbar .components-button.is-pressed:before{background:#1e1e1e}.components-accessible-toolbar .components-button:focus:before,.components-toolbar .components-button:focus:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.components-accessible-toolbar .components-button.has-icon.has-icon,.components-toolbar .components-button.has-icon.has-icon{min-width:48px;padding-left:8px;padding-right:8px}@keyframes components-button__appear-animation{0%{transform:scaleY(0)}to{transform:scaleY(1)}}.components-toolbar__control.components-button{position:relative}.components-toolbar__control.components-button[data-subscript] svg{padding:5px 0 5px 10px}.components-toolbar__control.components-button[data-subscript]:after{bottom:10px;content:attr(data-subscript);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;left:8px;line-height:12px;position:absolute}.components-toolbar__control.components-button:not(:disabled).is-pressed[data-subscript]:after{color:#fff}.components-toolbar-group{background-color:#fff;border-left:1px solid #1e1e1e;display:inline-flex;flex-shrink:0;flex-wrap:wrap;line-height:0;min-height:48px;padding-left:6px;padding-right:6px}.components-toolbar-group .components-toolbar-group.components-toolbar-group{border-width:0;margin:0}.components-toolbar-group .components-button.components-button,.components-toolbar-group .components-button.has-icon.has-icon{justify-content:center;min-width:36px;padding-left:6px;padding-right:6px}.components-toolbar-group .components-button.components-button svg,.components-toolbar-group .components-button.has-icon.has-icon svg{min-width:24px}.components-toolbar-group .components-button.components-button:before,.components-toolbar-group .components-button.has-icon.has-icon:before{left:2px;right:2px}.components-toolbar{background-color:#fff;border:1px solid #1e1e1e;display:inline-flex;flex-shrink:0;flex-wrap:wrap;margin:0;min-height:48px}.components-toolbar .components-toolbar.components-toolbar{border-width:0;margin:0}div.components-toolbar>div{display:flex;margin:0}div.components-toolbar>div+div.has-left-divider{margin-right:6px;overflow:visible;position:relative}div.components-toolbar>div+div.has-left-divider:before{background-color:#ddd;box-sizing:initial;content:"";display:inline-block;height:20px;position:absolute;right:-3px;top:8px;width:1px}.components-tooltip{background:#000;border-radius:2px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;color:#f0f0f0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:12px;line-height:1.4;padding:4px 8px;text-align:center;z-index:1000002}.components-tooltip__shortcut{margin-right:8px}@charset "UTF-8";:root{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}@media not (prefers-reduced-motion){.components-animate__appear{animation:components-animate__appear-animation .1s cubic-bezier(0,0,.2,1) 0s;animation-fill-mode:forwards}}.components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{transform-origin:top left}.components-animate__appear.is-from-top.is-from-right{transform-origin:top right}.components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{transform-origin:bottom left}.components-animate__appear.is-from-bottom.is-from-right{transform-origin:bottom right}@keyframes components-animate__appear-animation{0%{transform:translateY(-2em) scaleY(0) scaleX(0)}to{transform:translateY(0) scaleY(1) scaleX(1)}}@media not (prefers-reduced-motion){.components-animate__slide-in{animation:components-animate__slide-in-animation .1s cubic-bezier(0,0,.2,1);animation-fill-mode:forwards}.components-animate__slide-in.is-from-left{transform:translateX(100%)}.components-animate__slide-in.is-from-right{transform:translateX(-100%)}}@keyframes components-animate__slide-in-animation{to{transform:translateX(0)}}@media not (prefers-reduced-motion){.components-animate__loading{animation:components-animate__loading 1.6s ease-in-out infinite}}@keyframes components-animate__loading{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.components-autocomplete__popover .components-popover__content{min-width:200px;padding:8px}.components-autocomplete__result.components-button{display:flex;height:auto;min-height:36px;text-align:left;width:100%}.components-autocomplete__result.components-button:focus:not(:disabled){box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.components-badge{align-items:center;background-color:color-mix(in srgb,#fff 90%,var(--base-color));border-radius:2px;box-sizing:border-box;color:color-mix(in srgb,#000 50%,var(--base-color));display:inline-flex;font-size:12px;font-weight:400;gap:2px;line-height:20px;max-width:100%;min-height:24px;padding:0 8px}.components-badge *,.components-badge :after,.components-badge :before{box-sizing:inherit}.components-badge:where(.is-default){background-color:#f0f0f0;color:#2f2f2f}.components-badge.has-icon{padding-inline-start:4px}.components-badge.is-info{--base-color:#3858e9}.components-badge.is-warning{--base-color:#f0b849}.components-badge.is-error{--base-color:#cc1818}.components-badge.is-success{--base-color:#4ab866}.components-badge__icon{flex-shrink:0}.components-badge__content{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.components-button-group{display:inline-block}.components-button-group .components-button{border-radius:0;box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e;display:inline-flex}.components-button-group .components-button+.components-button{margin-left:-1px}.components-button-group .components-button:first-child{border-radius:2px 0 0 2px}.components-button-group .components-button:last-child{border-radius:0 2px 2px 0}.components-button-group .components-button.is-primary,.components-button-group .components-button:focus{position:relative;z-index:1}.components-button-group .components-button.is-primary{box-shadow:inset 0 0 0 1px #1e1e1e}.components-button{align-items:center;-webkit-appearance:none;background:none;border:0;border-radius:2px;box-sizing:border-box;color:var(--wp-components-color-foreground,#1e1e1e);cursor:pointer;display:inline-flex;font-family:inherit;font-size:13px;height:36px;margin:0;padding:6px 12px;text-decoration:none}@media not (prefers-reduced-motion){.components-button{transition:box-shadow .1s linear}}.components-button.is-next-40px-default-size{height:40px}.components-button:hover:not(:disabled,[aria-disabled=true]),.components-button[aria-expanded=true]{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button:focus:not(:disabled){box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:3px solid #0000}.components-button.is-primary{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:var(--wp-components-color-accent-inverted,#fff);outline:1px solid #0000;text-decoration:none;text-shadow:none;white-space:nowrap}.components-button.is-primary:hover:not(:disabled){background:var(--wp-components-color-accent-darker-10,var(--wp-admin-theme-color-darker-10,#2145e6));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-primary:active:not(:disabled){background:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));border-color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-primary:focus:not(:disabled){box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#fff6;outline:none}.components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{background-image:linear-gradient(-45deg,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 33%,var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6)) 33%,var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6)) 70%,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 70%);background-size:100px 100%;border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:var(--wp-components-color-accent-inverted,#fff)}.components-button.is-secondary,.components-button.is-tertiary{outline:1px solid #0000}.components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){box-shadow:none}.components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{background:#0000;color:#949494;transform:none}.components-button.is-secondary{background:#0000;box-shadow:inset 0 0 0 1px var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),0 0 0 currentColor;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:1px solid #0000;white-space:nowrap}.components-button.is-secondary:hover:not(:disabled,[aria-disabled=true],.is-pressed){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 4%,#0000);box-shadow:inset 0 0 0 1px var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6));color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6))}.components-button.is-secondary:disabled:not(:focus),.components-button.is-secondary[aria-disabled=true]:hover:not(:focus),.components-button.is-secondary[aria-disabled=true]:not(:focus){box-shadow:inset 0 0 0 1px #ddd}.components-button.is-secondary:focus:not(:disabled){box-shadow:0 0 0 currentColor inset,0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-button.is-tertiary{background:#0000;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));white-space:nowrap}.components-button.is-tertiary:hover:not(:disabled,[aria-disabled=true],.is-pressed){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 4%,#0000);color:var(--wp-components-color-accent-darker-20,var(--wp-admin-theme-color-darker-20,#183ad6))}.components-button.is-tertiary:active:not(:disabled,[aria-disabled=true]){background:color-mix(in srgb,var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)) 8%,#0000)}p+.components-button.is-tertiary{margin-left:-6px}.components-button.is-tertiary:disabled:not(:focus),.components-button.is-tertiary[aria-disabled=true]:hover:not(:focus),.components-button.is-tertiary[aria-disabled=true]:not(:focus){box-shadow:none;outline:none}.components-button.is-destructive{--wp-components-color-accent:#cc1818;--wp-components-color-accent-darker-10:#9e1313;--wp-components-color-accent-darker-20:#710d0d}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link){color:#cc1818}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):hover:not(:disabled,[aria-disabled=true]){color:#710d0d}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #cc1818}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):active:not(:disabled,[aria-disabled=true]){background:#ccc}.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):disabled,.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link)[aria-disabled=true]{color:#949494}.components-button.is-destructive.is-secondary:hover:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:hover:not(:disabled,[aria-disabled=true]){background:#cc18180a}.components-button.is-destructive.is-secondary:active:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:active:not(:disabled,[aria-disabled=true]){background:#cc181814}.components-button.is-link{background:none;border:0;border-radius:0;box-shadow:none;color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));height:auto;margin:0;outline:none;padding:0;text-align:left;text-decoration:underline}@media not (prefers-reduced-motion){.components-button.is-link{transition-duration:.05s;transition-property:border,background,color;transition-timing-function:ease-in-out}}.components-button.is-link:focus{border-radius:2px}.components-button.is-link:disabled,.components-button.is-link[aria-disabled=true]{color:#949494}.components-button:not(:disabled,[aria-disabled=true]):active{color:var(--wp-components-color-foreground,#1e1e1e)}.components-button:disabled,.components-button[aria-disabled=true]{color:#949494;cursor:default}.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{background-image:linear-gradient(-45deg,#fafafa 33%,#e0e0e0 0,#e0e0e0 70%,#fafafa 0);background-size:100px 100%}@media not (prefers-reduced-motion){.components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{animation:components-button__busy-animation 2.5s linear infinite}}.components-button.is-compact{height:32px}.components-button.is-compact.has-icon:not(.has-text){min-width:32px;padding:0;width:32px}.components-button.is-small{font-size:11px;height:24px;line-height:22px;padding:0 8px}.components-button.is-small.has-icon:not(.has-text){min-width:24px;padding:0;width:24px}.components-button.has-icon{justify-content:center;min-width:36px;padding:6px}.components-button.has-icon.is-next-40px-default-size{min-width:40px}.components-button.has-icon .dashicon{align-items:center;box-sizing:initial;display:inline-flex;justify-content:center;padding:2px}.components-button.has-icon.has-text{gap:4px;justify-content:start;padding-left:8px;padding-right:12px}.components-button.is-pressed,.components-button.is-pressed:hover{color:var(--wp-components-color-foreground-inverted,#fff)}.components-button.is-pressed:hover:not(:disabled,[aria-disabled=true]),.components-button.is-pressed:not(:disabled,[aria-disabled=true]){background:var(--wp-components-color-foreground,#1e1e1e)}.components-button.is-pressed:disabled,.components-button.is-pressed[aria-disabled=true]{color:#949494}.components-button.is-pressed:disabled:not(.is-primary):not(.is-secondary):not(.is-tertiary),.components-button.is-pressed[aria-disabled=true]:not(.is-primary):not(.is-secondary):not(.is-tertiary){background:#949494;color:var(--wp-components-color-foreground-inverted,#fff)}.components-button.is-pressed:focus:not(:disabled){box-shadow:inset 0 0 0 1px var(--wp-components-color-background,#fff),0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000}.components-button svg{fill:currentColor;outline:none}@media (forced-colors:active){.components-button svg{fill:CanvasText}}.components-button .components-visually-hidden{height:auto}@keyframes components-button__busy-animation{0%{background-position:200px 0}}.components-checkbox-control{--checkbox-input-size:24px;--checkbox-input-margin:8px}@media (min-width:600px){.components-checkbox-control{--checkbox-input-size:16px}}.components-checkbox-control__label{cursor:pointer;line-height:var(--checkbox-input-size)}.components-checkbox-control__input[type=checkbox]{appearance:none;background:#fff;border:1px solid #1e1e1e;border-radius:2px;box-shadow:0 0 0 #0000;clear:none;color:#1e1e1e;cursor:pointer;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:var(--checkbox-input-size);line-height:normal;line-height:0;margin:0 4px 0 0;outline:0;padding:6px 8px;padding:0!important;text-align:center;transition:none;vertical-align:top;width:var(--checkbox-input-size)}@media not (prefers-reduced-motion){.components-checkbox-control__input[type=checkbox]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-checkbox-control__input[type=checkbox]{font-size:13px;line-height:normal}}.components-checkbox-control__input[type=checkbox]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]::-moz-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{color:#1e1e1e9e}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked{background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox]:checked::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{color:#fff;margin:-3px -5px}@media (min-width:782px){.components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{margin:-4px 0 0 -5px}}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]{background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color)}.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{content:"\f460";display:inline-block;float:left;font:normal 30px/1 dashicons;vertical-align:middle;width:16px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (min-width:782px){.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{float:none;font-size:21px}}.components-checkbox-control__input[type=checkbox]:disabled,.components-checkbox-control__input[type=checkbox][aria-disabled=true]{background:#f0f0f0;border-color:#ddd;cursor:default;opacity:1}@media not (prefers-reduced-motion){.components-checkbox-control__input[type=checkbox]{transition:border-color .1s ease-in-out}}.components-checkbox-control__input[type=checkbox]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.components-checkbox-control__input[type=checkbox]:checked,.components-checkbox-control__input[type=checkbox]:indeterminate{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-checkbox-control__input[type=checkbox]:checked::-ms-check,.components-checkbox-control__input[type=checkbox]:indeterminate::-ms-check{opacity:0}.components-checkbox-control__input[type=checkbox]:checked:before{content:none}.components-checkbox-control__input-container{aspect-ratio:1;display:inline-block;flex-shrink:0;line-height:1;margin-right:var(--checkbox-input-margin);position:relative;vertical-align:middle;width:var(--checkbox-input-size)}svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{--checkmark-size:var(--checkbox-input-size);fill:#fff;cursor:pointer;height:var(--checkmark-size);left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);-webkit-user-select:none;user-select:none;width:var(--checkmark-size)}@media (min-width:600px){svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{--checkmark-size:calc(var(--checkbox-input-size) + 4px)}}.components-checkbox-control__help{display:inline-block;margin-inline-start:calc(var(--checkbox-input-size) + var(--checkbox-input-margin))}.components-circular-option-picker{display:inline-block;min-width:188px;width:100%}.components-circular-option-picker .components-circular-option-picker__custom-clear-wrapper{display:flex;justify-content:flex-end;margin-top:12px}.components-circular-option-picker .components-circular-option-picker__swatches{display:flex;flex-wrap:wrap;gap:12px;position:relative;z-index:1}.components-circular-option-picker>:not(.components-circular-option-picker__swatches){position:relative;z-index:0}.components-circular-option-picker__option-wrapper{display:inline-block;height:28px;transform:scale(1);vertical-align:top;width:28px}@media not (prefers-reduced-motion){.components-circular-option-picker__option-wrapper{transition:transform .1s ease;will-change:transform}}.components-circular-option-picker__option-wrapper:hover{transform:scale(1.2)}.components-circular-option-picker__option-wrapper>div{height:100%;width:100%}.components-circular-option-picker__option-wrapper:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none'%3E%3Cpath fill='%23555D65' d='M6 8V6H4v2zm2 0V6h2v2zm2 8H8v-2h2zm2 0v-2h2v2zm0 2v-2h-2v2H8v2h2v-2zm2 0v2h-2v-2zm2 0h-2v-2h2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M18 18h2v-2h-2v-2h2v-2h-2v-2h2V8h-2v2h-2V8h-2v2h2v2h-2v2h2v2h2zm-2-4v-2h2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' d='M18 18v2h-2v-2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M8 10V8H6v2H4v2h2v2H4v2h2v2H4v2h2v2H4v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2v2h-2V4h-2v2h-2V4h-2v2h-2V4h-2v2h2v2h-2v2zm0 2v-2H6v2zm2 0v-2h2v2zm0 2v-2H8v2H6v2h2v2H6v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h-2v2h-2V6h-2v2h-2v2h2v2h-2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M4 0H2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2H8V0H6v2H4zm0 4V2H2v2zm2 0V2h2v2zm0 2V4H4v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2H8v2z' clip-rule='evenodd'/%3E%3C/svg%3E");border-radius:50%;bottom:1px;content:"";left:1px;position:absolute;right:1px;top:1px;z-index:-1}.components-circular-option-picker__option{aspect-ratio:1;background:#0000;border:none;border-radius:50%;box-shadow:inset 0 0 0 14px;cursor:pointer;display:inline-block;height:100%!important;vertical-align:top}@media not (prefers-reduced-motion){.components-circular-option-picker__option{transition:box-shadow .1s ease}}.components-circular-option-picker__option:hover{box-shadow:inset 0 0 0 14px!important}.components-circular-option-picker__option[aria-pressed=true],.components-circular-option-picker__option[aria-selected=true]{box-shadow:inset 0 0 0 4px;overflow:visible;position:relative;z-index:1}.components-circular-option-picker__option[aria-pressed=true]+svg,.components-circular-option-picker__option[aria-selected=true]+svg{border-radius:50%;left:2px;pointer-events:none;position:absolute;top:2px;z-index:2}.components-circular-option-picker__option:after{border:1px solid #0000;border-radius:50%;bottom:-1px;box-shadow:inset 0 0 0 1px #0003;box-sizing:inherit;content:"";left:-1px;position:absolute;right:-1px;top:-1px}.components-circular-option-picker__option:focus:after{border:2px solid #757575;border-radius:50%;box-shadow:inset 0 0 0 2px #fff;content:"";height:calc(100% + 4px);left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% + 4px)}.components-circular-option-picker__option.components-button:focus{background-color:initial;box-shadow:inset 0 0 0 14px;outline:none}.components-circular-option-picker__button-action .components-circular-option-picker__option{background:#fff;color:#fff}.components-circular-option-picker__dropdown-link-action{margin-right:16px}.components-circular-option-picker__dropdown-link-action .components-button{line-height:22px}.components-palette-edit__popover-gradient-picker{padding:8px;width:260px}.components-dropdown-menu__menu .components-palette-edit__menu-button{width:100%}.component-color-indicator{background:#fff linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);border-radius:50%;box-shadow:inset 0 0 0 1px #0003;display:inline-block;height:20px;padding:0;width:20px}.components-combobox-control{width:100%}input.components-combobox-control__input[type=text]{border:none;box-shadow:none;font-family:inherit;font-size:16px;line-height:inherit;margin:0;min-height:auto;padding:2px;width:100%}@media (min-width:600px){input.components-combobox-control__input[type=text]{font-size:13px}}input.components-combobox-control__input[type=text]:focus{box-shadow:none;outline:none}.components-combobox-control__suggestions-container{align-items:flex-start;border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;display:flex;flex-wrap:wrap;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:0;width:100%}@media not (prefers-reduced-motion){.components-combobox-control__suggestions-container{transition:box-shadow .1s linear}}@media (min-width:600px){.components-combobox-control__suggestions-container{font-size:13px;line-height:normal}}.components-combobox-control__suggestions-container:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-combobox-control__suggestions-container::-webkit-input-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container::-moz-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container:-ms-input-placeholder{color:#1e1e1e9e}.components-combobox-control__suggestions-container:focus-within{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-combobox-control__suggestions-container .components-spinner{margin:0}.components-color-palette__custom-color-wrapper{position:relative;z-index:0}.components-color-palette__custom-color-button{background:none;border:none;border-radius:4px 4px 0 0;box-shadow:inset 0 0 0 1px #0003;box-sizing:border-box;cursor:pointer;height:64px;outline:1px solid #0000;position:relative;width:100%}.components-color-palette__custom-color-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline-width:2px}.components-color-palette__custom-color-button:after{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,24px 24px;background-size:48px 48px;border-radius:3px 3px 0 0;content:"";inset:1px;position:absolute;z-index:-1}.components-color-palette__custom-color-text-wrapper{border-radius:0 0 4px 4px;box-shadow:inset 0 -1px 0 0 #0003,inset 1px 0 0 0 #0003,inset -1px 0 0 0 #0003;font-size:13px;padding:12px 16px;position:relative}.components-color-palette__custom-color-name{color:var(--wp-components-color-foreground,#1e1e1e);margin:0 1px}.components-color-palette__custom-color-value{color:#757575}.components-color-palette__custom-color-value--is-hex{text-transform:uppercase}.components-color-palette__custom-color-value:empty:after{content:"";visibility:hidden}.components-custom-gradient-picker__gradient-bar{border-radius:2px;height:48px;position:relative;width:100%;z-index:1}.components-custom-gradient-picker__gradient-bar.has-gradient{background-image:repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0),repeating-linear-gradient(45deg,#e0e0e0 25%,#0000 0,#0000 75%,#e0e0e0 0,#e0e0e0);background-position:0 0,12px 12px;background-size:24px 24px}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__gradient-bar-background{inset:0;position:absolute}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__markers-container{margin-left:auto;margin-right:auto;position:relative;width:calc(100% - 48px)}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-dropdown{display:flex;height:16px;position:absolute;top:16px;width:16px}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown{background:#fff;border-radius:50%;color:#1e1e1e;height:inherit;min-width:16px!important;padding:2px;position:relative;width:inherit}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown svg{height:100%;width:100%}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button{border-radius:50%;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 2px 0 #00000040;height:inherit;outline:2px solid #0000;padding:0;width:inherit}.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button.is-active,.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button:focus{box-shadow:inset 0 0 0 calc(var(--wp-admin-border-width-focus)*2) #fff,0 0 2px 0 #00000040;outline:1.5px solid #0000}.components-custom-gradient-picker__remove-control-point-wrapper{padding-bottom:8px}.components-custom-gradient-picker__inserter{direction:ltr}.components-custom-gradient-picker__liner-gradient-indicator{display:inline-block;flex:0 auto;height:20px;width:20px}.components-custom-gradient-picker__ui-line{position:relative;z-index:0}.block-editor-dimension-control .components-base-control__field{align-items:center;display:flex}.block-editor-dimension-control .components-base-control__label{align-items:center;display:flex;margin-bottom:0;margin-right:1em}.block-editor-dimension-control .components-base-control__label .dashicon{margin-right:.5em}.block-editor-dimension-control.is-manual .components-base-control__label{width:10em}body.is-dragging-components-draggable{cursor:move;cursor:grabbing!important}.components-draggable__invisible-drag-image{height:50px;left:-1000px;position:fixed;width:50px}.components-draggable__clone{background:#0000;padding:0;pointer-events:none;position:fixed;z-index:1000000000}.components-drop-zone{border-radius:2px;bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;visibility:hidden;z-index:40}.components-drop-zone.is-active{opacity:1;visibility:visible}.components-drop-zone .components-drop-zone__content{align-items:center;background-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));bottom:0;color:#fff;display:flex;height:100%;justify-content:center;left:0;opacity:0;pointer-events:none;position:absolute;right:0;text-align:center;top:0;width:100%;z-index:50}.components-drop-zone .components-drop-zone__content-inner{opacity:0;transform:scale(.9)}.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{opacity:1}@media not (prefers-reduced-motion){.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{transition:opacity .2s ease-in-out}}.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{opacity:1;transform:scale(1)}@media not (prefers-reduced-motion){.components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{transition:opacity .1s ease-in-out .1s,transform .1s ease-in-out .1s}}.components-drop-zone__content-icon,.components-drop-zone__content-text{display:block}.components-drop-zone__content-icon{line-height:0;margin:0 auto 8px;fill:currentColor;pointer-events:none}.components-drop-zone__content-text{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-dropdown{display:inline-block}.components-dropdown__content .components-popover__content{padding:8px}.components-dropdown__content .components-popover__content:has(.components-menu-group){padding:0}.components-dropdown__content .components-popover__content:has(.components-menu-group) .components-dropdown-menu__menu>.components-menu-item__button,.components-dropdown__content .components-popover__content:has(.components-menu-group)>.components-menu-item__button{margin:8px;width:auto}.components-dropdown__content [role=menuitem]{white-space:nowrap}.components-dropdown__content .components-menu-group{padding:8px}.components-dropdown__content .components-menu-group+.components-menu-group{border-top:1px solid #ccc;padding:8px}.components-dropdown__content.is-alternate .components-menu-group+.components-menu-group{border-color:#1e1e1e}.components-dropdown-menu__toggle{vertical-align:top}.components-dropdown-menu__menu{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:1.4;width:100%}.components-dropdown-menu__menu .components-dropdown-menu__menu-item,.components-dropdown-menu__menu .components-menu-item{cursor:pointer;outline:none;padding:6px;white-space:nowrap;width:100%}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator,.components-dropdown-menu__menu .components-menu-item.has-separator{margin-top:6px;overflow:visible;position:relative}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator:before,.components-dropdown-menu__menu .components-menu-item.has-separator:before{background-color:#ddd;box-sizing:initial;content:"";display:block;height:1px;left:0;position:absolute;right:0;top:-3px}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active svg,.components-dropdown-menu__menu .components-menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-menu-item.is-active svg{background:#1e1e1e;border-radius:1px;box-shadow:0 0 0 1px #1e1e1e;color:#fff}.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-icon-only,.components-dropdown-menu__menu .components-menu-item.is-icon-only{width:auto}.components-dropdown-menu__menu .components-menu-item__button,.components-dropdown-menu__menu .components-menu-item__button.components-button{height:auto;min-height:40px;padding-left:8px;padding-right:8px;text-align:left}.components-duotone-picker__color-indicator:before{background:#0000}.components-duotone-picker__color-indicator>.components-button,.components-duotone-picker__color-indicator>.components-button.is-pressed:hover:not(:disabled){background:linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0);color:#0000}.components-duotone-picker__color-indicator>.components-button:not([aria-disabled=true]):active{color:#0000}.components-color-list-picker,.components-color-list-picker__swatch-button{width:100%}.components-color-list-picker__color-picker{margin:8px 0}.components-color-list-picker__swatch-color{margin:2px}.components-external-link{text-decoration:none}.components-external-link__contents{text-decoration:underline}.components-external-link__icon{font-weight:400;margin-left:.5ch}.components-form-toggle{display:inline-block;height:16px;position:relative}.components-form-toggle .components-form-toggle__track{background-color:#fff;border:1px solid #949494;border-radius:8px;box-sizing:border-box;content:"";display:inline-block;height:16px;overflow:hidden;position:relative;vertical-align:top;width:32px}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__track{transition:background-color .2s ease,border-color .2s ease}}.components-form-toggle .components-form-toggle__track:after{border-top:16px solid #0000;box-sizing:border-box;content:"";inset:0;opacity:0;position:absolute}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__track:after{transition:opacity .2s ease}}.components-form-toggle .components-form-toggle__thumb{background-color:#1e1e1e;border:6px solid #0000;border-radius:50%;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;box-sizing:border-box;display:block;height:12px;left:2px;position:absolute;top:2px;width:12px}@media not (prefers-reduced-motion){.components-form-toggle .components-form-toggle__thumb{transition:transform .2s ease,background-color .2s ease-out}}.components-form-toggle.is-checked .components-form-toggle__track{background-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-form-toggle.is-checked .components-form-toggle__track:after{opacity:1}.components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:2px}.components-form-toggle.is-checked .components-form-toggle__thumb{background-color:#fff;border-width:0;transform:translateX(16px)}.components-disabled .components-form-toggle,.components-form-toggle.is-disabled{opacity:.3}.components-form-toggle input.components-form-toggle__input[type=checkbox]{border:none;height:100%;left:0;margin:0;opacity:0;padding:0;position:absolute;top:0;width:100%;z-index:1}.components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{background:none}.components-form-toggle input.components-form-toggle__input[type=checkbox]:before{content:""}.components-form-toggle input.components-form-toggle__input[type=checkbox]:not(:disabled,[aria-disabled=true]){cursor:pointer}.components-form-token-field__input-container{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;cursor:text;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:0;width:100%}@media not (prefers-reduced-motion){.components-form-token-field__input-container{transition:box-shadow .1s linear}}@media (min-width:600px){.components-form-token-field__input-container{font-size:13px;line-height:normal}}.components-form-token-field__input-container:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-form-token-field__input-container::-webkit-input-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container::-moz-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container:-ms-input-placeholder{color:#1e1e1e9e}.components-form-token-field__input-container.is-disabled{background:#ddd;border-color:#ddd}.components-form-token-field__input-container.is-active{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-form-token-field__input-container input[type=text].components-form-token-field__input{background:inherit;border:0;box-shadow:none;color:#1e1e1e;display:inline-block;flex:1;font-family:inherit;font-size:16px;margin-left:4px;max-width:100%;min-height:24px;min-width:50px;padding:0;width:100%}@media (min-width:600px){.components-form-token-field__input-container input[type=text].components-form-token-field__input{font-size:13px}}.components-form-token-field.is-active .components-form-token-field__input-container input[type=text].components-form-token-field__input,.components-form-token-field__input-container input[type=text].components-form-token-field__input:focus{box-shadow:none;outline:none}.components-form-token-field__input-container .components-form-token-field__token+input[type=text].components-form-token-field__input{width:auto}.components-form-token-field__token{color:#1e1e1e;display:flex;font-size:13px;max-width:100%}.components-form-token-field__token.is-success .components-form-token-field__remove-token,.components-form-token-field__token.is-success .components-form-token-field__token-text{background:#4ab866}.components-form-token-field__token.is-error .components-form-token-field__remove-token,.components-form-token-field__token.is-error .components-form-token-field__token-text{background:#cc1818}.components-form-token-field__token.is-validating .components-form-token-field__remove-token,.components-form-token-field__token.is-validating .components-form-token-field__token-text{color:#757575}.components-form-token-field__token.is-borderless{padding:0 24px 0 0;position:relative}.components-form-token-field__token.is-borderless .components-form-token-field__token-text{background:#0000}.components-form-token-field__token.is-borderless:not(.is-disabled) .components-form-token-field__token-text{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-form-token-field__token.is-borderless .components-form-token-field__remove-token{background:#0000;color:#757575;position:absolute;right:0;top:1px}.components-form-token-field__token.is-borderless.is-success .components-form-token-field__token-text{color:#4ab866}.components-form-token-field__token.is-borderless.is-error .components-form-token-field__token-text{color:#cc1818;padding:0 4px 0 6px}.components-form-token-field__token.is-borderless.is-validating .components-form-token-field__token-text{color:#1e1e1e}.components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{background:#ddd;display:inline-block;height:auto;min-width:unset}@media not (prefers-reduced-motion){.components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{transition:all .2s cubic-bezier(.4,1,.4,1)}}.components-form-token-field__token-text{border-radius:1px 0 0 1px;line-height:24px;overflow:hidden;padding:0 0 0 8px;text-overflow:ellipsis;white-space:nowrap}.components-form-token-field__remove-token.components-button{border-radius:0 1px 1px 0;color:#1e1e1e;line-height:10px;overflow:initial}.components-form-token-field__remove-token.components-button:hover:not(:disabled){color:#1e1e1e}.components-form-token-field__suggestions-list{box-shadow:inset 0 1px 0 0 #949494;flex:1 0 100%;list-style:none;margin:0;max-height:128px;min-width:100%;overflow-y:auto;padding:0}@media not (prefers-reduced-motion){.components-form-token-field__suggestions-list{transition:all .15s ease-in-out}}.components-form-token-field__suggestion{box-sizing:border-box;color:#1e1e1e;display:block;font-size:13px;margin:0;min-height:32px;padding:8px 12px}.components-form-token-field__suggestion.is-selected{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#fff}.components-form-token-field__suggestion[aria-disabled=true]{color:#949494;pointer-events:none}.components-form-token-field__suggestion[aria-disabled=true].is-selected{background-color:rgba(var(--wp-components-color-accent--rgb,var(--wp-admin-theme-color--rgb)),.04)}.components-form-token-field__suggestion:not(.is-empty){cursor:pointer}@media (min-width:600px){.components-guide{width:600px}}.components-guide .components-modal__content{margin-top:0;padding:0}.components-guide .components-modal__content:before{content:none}.components-guide .components-modal__header{border-bottom:none;height:60px;padding:0;position:sticky}.components-guide .components-modal__header .components-button{align-self:flex-start;margin:8px 8px 0 0;position:static}.components-guide .components-modal__header .components-button:hover svg{fill:#fff}.components-guide .components-guide__container{display:flex;flex-direction:column;justify-content:space-between;margin-top:-60px;min-height:100%}.components-guide .components-guide__page{display:flex;flex-direction:column;justify-content:center;position:relative}@media (min-width:600px){.components-guide .components-guide__page{min-height:300px}}.components-guide .components-guide__footer{align-content:center;display:flex;height:36px;justify-content:center;margin:0 0 24px;padding:0 32px;position:relative;width:100%}.components-guide .components-guide__page-control{margin:0;text-align:center}.components-guide .components-guide__page-control li{display:inline-block;margin:0}.components-guide .components-guide__page-control .components-button{color:#e0e0e0;margin:-6px 0}.components-guide .components-guide__page-control li[aria-current=step] .components-button{color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-modal__frame.components-guide{border:none;max-height:575px;min-width:312px}@media (max-width:600px){.components-modal__frame.components-guide{margin:auto;max-width:calc(100vw - 32px)}}.components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{position:absolute}.components-button.components-guide__back-button{left:32px}.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{right:32px}[role=region]{position:relative}.is-focusing-regions [role=region]:focus:after,[role=region].interface-interface-skeleton__content:focus-visible:after{bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:1000000}.is-focusing-regions .editor-post-publish-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-entities-saved-states-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-publish-panel,.is-focusing-regions .interface-interface-skeleton__sidebar .editor-layout__toggle-sidebar-panel,.is-focusing-regions [role=region]:focus:after,.is-focusing-regions.is-distraction-free .interface-interface-skeleton__header .edit-post-header,[role=region].interface-interface-skeleton__content:focus-visible:after{outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2)}.components-menu-group+.components-menu-group{border-top:1px solid #1e1e1e;padding-top:8px}.components-menu-group+.components-menu-group.has-hidden-separator{border-top:none;margin-top:0;padding-top:0}.components-menu-group:has(>div:empty){display:none}.components-menu-group__label{color:#757575;font-size:11px;font-weight:500;margin-bottom:12px;margin-top:4px;padding:0 8px;text-transform:uppercase;white-space:nowrap}.components-menu-item__button,.components-menu-item__button.components-button{width:100%}.components-menu-item__button.components-button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button.components-button[role=menuitemradio] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemradio] .components-menu-item__item:only-child{box-sizing:initial;padding-right:48px}.components-menu-item__button .components-menu-items__item-icon,.components-menu-item__button.components-button .components-menu-items__item-icon{display:inline-block;flex:0 0 auto}.components-menu-item__button .components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-items__item-icon.has-icon-right{margin-left:24px;margin-right:-2px}.components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right{margin-left:8px}.components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{margin-left:-2px;margin-right:8px}.components-menu-item__button.components-button.is-primary,.components-menu-item__button.is-primary{justify-content:center}.components-menu-item__button.components-button.is-primary .components-menu-item__item,.components-menu-item__button.is-primary .components-menu-item__item{margin-right:0}.components-menu-item__button.components-button:disabled.is-tertiary,.components-menu-item__button.components-button[aria-disabled=true].is-tertiary,.components-menu-item__button:disabled.is-tertiary,.components-menu-item__button[aria-disabled=true].is-tertiary{background:none;color:var(--wp-components-color-accent-darker-10,var(--wp-admin-theme-color-darker-10,#2145e6));opacity:.3}.components-menu-item__info-wrapper{display:flex;flex-direction:column;margin-right:auto}.components-menu-item__info{color:#757575;font-size:12px;margin-top:4px;white-space:normal}.components-menu-item__item{align-items:center;display:inline-flex;margin-right:auto;min-width:160px;white-space:nowrap}.components-menu-item__shortcut{align-self:center;color:currentColor;display:none;margin-left:auto;margin-right:0;padding-left:24px}@media (min-width:480px){.components-menu-item__shortcut{display:inline}}.components-menu-items-choice,.components-menu-items-choice.components-button{height:auto;min-height:40px}.components-menu-items-choice svg,.components-menu-items-choice.components-button svg{margin-right:12px}.components-menu-items-choice.components-button.has-icon,.components-menu-items-choice.has-icon{padding-left:12px}.components-modal__screen-overlay{background-color:#00000059;bottom:0;display:flex;left:0;position:fixed;right:0;top:0;z-index:100000}@keyframes __wp-base-styles-fade-in{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.components-modal__screen-overlay{animation:__wp-base-styles-fade-in .08s linear 0s;animation-fill-mode:forwards}}@keyframes __wp-base-styles-fade-out{0%{opacity:1}to{opacity:0}}@media not (prefers-reduced-motion){.components-modal__screen-overlay.is-animating-out{animation:__wp-base-styles-fade-out .08s linear 80ms;animation-fill-mode:forwards}}.components-modal__frame{animation-fill-mode:forwards;animation-name:components-modal__appear-animation;animation-timing-function:cubic-bezier(.29,0,0,1);background:#fff;border-radius:8px 8px 0 0;box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005;box-sizing:border-box;display:flex;margin:40px 0 0;overflow:hidden;width:100%}.components-modal__frame *,.components-modal__frame :after,.components-modal__frame :before{box-sizing:inherit}@media not (prefers-reduced-motion){.components-modal__frame{animation-duration:var(--modal-frame-animation-duration)}}.components-modal__screen-overlay.is-animating-out .components-modal__frame{animation-name:components-modal__disappear-animation;animation-timing-function:cubic-bezier(1,0,.2,1)}@media (min-width:600px){.components-modal__frame{border-radius:8px;margin:auto;max-height:calc(100% - 120px);max-width:calc(100% - 32px);min-width:350px;width:auto}}@media (min-width:600px) and (min-width:600px){.components-modal__frame.is-full-screen{height:calc(100% - 32px);max-height:none;width:calc(100% - 32px)}}@media (min-width:600px) and (min-width:782px){.components-modal__frame.is-full-screen{height:calc(100% - 80px);max-width:none;width:calc(100% - 80px)}}@media (min-width:600px){.components-modal__frame.has-size-large,.components-modal__frame.has-size-medium,.components-modal__frame.has-size-small{width:100%}.components-modal__frame.has-size-small{max-width:384px}.components-modal__frame.has-size-medium{max-width:512px}.components-modal__frame.has-size-large{max-width:840px}}@media (min-width:960px){.components-modal__frame{max-height:70%}}@keyframes components-modal__appear-animation{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes components-modal__disappear-animation{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.9)}}.components-modal__header{align-items:center;border-bottom:1px solid #0000;box-sizing:border-box;display:flex;flex-direction:row;height:72px;justify-content:space-between;left:0;padding:24px 32px 8px;position:absolute;top:0;width:100%;z-index:10}.components-modal__header .components-modal__header-heading{font-size:1.2rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__content.has-scrolled-content:not(.hide-header) .components-modal__header{border-bottom-color:#ddd}.components-modal__header+p{margin-top:0}.components-modal__header-heading-container{align-items:center;display:flex;flex-direction:row;flex-grow:1;justify-content:left}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-height:36px;max-width:36px;padding:8px}.components-modal__content{flex:1;margin-top:72px;overflow:auto;padding:4px 32px 32px}.components-modal__content.hide-header{margin-top:0;padding-top:32px}.components-modal__content.is-scrollable:focus-visible{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:-2px}.components-notice{align-items:center;background-color:#fff;border-left:4px solid var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));color:#1e1e1e;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;padding:8px 12px}.components-notice.is-dismissible{position:relative}.components-notice.is-success{background-color:#eff9f1;border-left-color:#4ab866}.components-notice.is-warning{background-color:#fef8ee;border-left-color:#f0b849}.components-notice.is-error{background-color:#f4a2a2;border-left-color:#cc1818}.components-notice__content{flex-grow:1;margin:4px 25px 4px 0}.components-notice__actions{display:flex;flex-wrap:wrap}.components-notice__action.components-button{margin-right:8px}.components-notice__action.components-button,.components-notice__action.components-button.is-link{margin-left:12px}.components-notice__action.components-button.is-secondary{vertical-align:initial}.components-notice__dismiss{align-self:flex-start;color:#757575;flex-shrink:0}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{background-color:initial;color:#1e1e1e}.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{box-shadow:none}.components-notice-list{box-sizing:border-box;max-width:100vw}.components-notice-list .components-notice__content{line-height:2;margin-bottom:12px;margin-top:12px}.components-notice-list .components-notice__action.components-button{display:block;margin-left:0;margin-top:8px}.components-panel{background:#fff;border:1px solid #e0e0e0}.components-panel>.components-panel__body:first-child,.components-panel>.components-panel__header:first-child{margin-top:-1px}.components-panel>.components-panel__body:last-child,.components-panel>.components-panel__header:last-child{border-bottom-width:0}.components-panel+.components-panel{margin-top:-1px}.components-panel__body{border-bottom:1px solid #e0e0e0;border-top:1px solid #e0e0e0}.components-panel__body h3{margin:0 0 .5em}.components-panel__body.is-opened{padding:16px}.components-panel__header{align-items:center;border-bottom:1px solid #ddd;box-sizing:initial;display:flex;flex-shrink:0;height:47px;justify-content:space-between;padding:0 16px}.components-panel__header h2{color:inherit;font-size:inherit;margin:0}.components-panel__body+.components-panel__body,.components-panel__body+.components-panel__header,.components-panel__header+.components-panel__body,.components-panel__header+.components-panel__header{margin-top:-1px}.components-panel__body>.components-panel__body-title{display:block;font-size:inherit;margin-bottom:0;margin-top:0;padding:0}@media not (prefers-reduced-motion){.components-panel__body>.components-panel__body-title{transition:background .1s ease-in-out}}.components-panel__body.is-opened>.components-panel__body-title{margin:-16px -16px 5px}.components-panel__body>.components-panel__body-title:hover{background:#f0f0f0;border:none}.components-panel__body-toggle.components-button{border:none;box-shadow:none;color:#1e1e1e;font-weight:500;height:auto;outline:none;padding:16px 48px 16px 16px;position:relative;text-align:left;width:100%}@media not (prefers-reduced-motion){.components-panel__body-toggle.components-button{transition:background .1s ease-in-out}}.components-panel__body-toggle.components-button:focus{border-radius:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-panel__body-toggle.components-button .components-panel__arrow{color:#1e1e1e;position:absolute;right:16px;top:50%;transform:translateY(-50%);fill:currentColor}@media not (prefers-reduced-motion){.components-panel__body-toggle.components-button .components-panel__arrow{transition:color .1s ease-in-out}}body.rtl .components-panel__body-toggle.components-button .dashicons-arrow-right{-ms-filter:fliph;filter:FlipH;margin-top:-10px;transform:scaleX(-1)}.components-panel__icon{color:#757575;margin:-2px 0 -2px 6px}.components-panel__body-toggle-icon{margin-right:-5px}.components-panel__color-title{float:left;height:19px}.components-panel__row{align-items:center;display:flex;justify-content:space-between;margin-top:8px;min-height:36px}.components-panel__row select{min-width:0}.components-panel__row label{flex-shrink:0;margin-right:12px;max-width:75%}.components-panel__row:empty,.components-panel__row:first-of-type{margin-top:0}.components-panel .circle-picker{padding-bottom:20px}.components-placeholder.components-placeholder{align-items:flex-start;box-sizing:border-box;color:#1e1e1e;display:flex;flex-direction:column;font-size:13px;gap:16px;margin:0;padding:24px;position:relative;text-align:left;width:100%;-moz-font-smoothing:subpixel-antialiased;-webkit-font-smoothing:subpixel-antialiased;background-color:#fff;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;outline:1px solid #0000}.components-placeholder__error,.components-placeholder__fieldset,.components-placeholder__instructions,.components-placeholder__label{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:400;letter-spacing:normal;line-height:normal;text-transform:none}.components-placeholder__label{align-items:center;display:flex;font-weight:600}.components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{margin-right:4px;fill:currentColor}@media (forced-colors:active){.components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{fill:CanvasText}}.components-placeholder__label:empty{display:none}.components-placeholder__fieldset,.components-placeholder__fieldset form{display:flex;flex-direction:row;flex-wrap:wrap;gap:16px;justify-content:flex-start;width:100%}.components-placeholder__fieldset form p,.components-placeholder__fieldset p{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.components-placeholder__fieldset.is-column-layout,.components-placeholder__fieldset.is-column-layout form{flex-direction:column}.components-placeholder__input[type=url]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;flex:1 1 auto;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;line-height:normal;padding:6px 8px}@media not (prefers-reduced-motion){.components-placeholder__input[type=url]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-placeholder__input[type=url]{font-size:13px;line-height:normal}}.components-placeholder__input[type=url]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-placeholder__input[type=url]::-webkit-input-placeholder{color:#1e1e1e9e}.components-placeholder__input[type=url]::-moz-placeholder{color:#1e1e1e9e}.components-placeholder__input[type=url]:-ms-input-placeholder{color:#1e1e1e9e}.components-placeholder__error{gap:8px;width:100%}.components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link{margin-left:10px;margin-right:10px}.components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link:last-child{margin-right:0}.components-placeholder.is-medium .components-placeholder__instructions,.components-placeholder.is-small .components-placeholder__instructions{display:none}.components-placeholder.is-medium .components-placeholder__fieldset,.components-placeholder.is-medium .components-placeholder__fieldset form,.components-placeholder.is-small .components-placeholder__fieldset,.components-placeholder.is-small .components-placeholder__fieldset form{flex-direction:column}.components-placeholder.is-medium .components-button,.components-placeholder.is-medium .components-placeholder__fieldset>*,.components-placeholder.is-small .components-button,.components-placeholder.is-small .components-placeholder__fieldset>*{justify-content:center;width:100%}.components-placeholder.is-small{padding:16px}.components-placeholder.has-illustration{-webkit-backdrop-filter:blur(100px);backdrop-filter:blur(100px);backface-visibility:hidden;background-color:initial;border-radius:0;box-shadow:none;color:inherit;display:flex;overflow:hidden}.is-dark-theme .components-placeholder.has-illustration{background-color:#0000001a}.components-placeholder.has-illustration .components-placeholder__fieldset{margin-left:0;margin-right:0}.components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{opacity:0;pointer-events:none}@media not (prefers-reduced-motion){.components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{transition:opacity .1s linear}}.is-selected>.components-placeholder.has-illustration .components-button,.is-selected>.components-placeholder.has-illustration .components-placeholder__instructions,.is-selected>.components-placeholder.has-illustration .components-placeholder__label{opacity:1;pointer-events:auto}.components-placeholder.has-illustration:before{background:currentColor;bottom:0;content:"";left:0;opacity:.1;pointer-events:none;position:absolute;right:0;top:0}.is-selected .components-placeholder.has-illustration{overflow:auto}.components-placeholder__preview{display:flex;justify-content:center}.components-placeholder__illustration{box-sizing:initial;height:100%;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%;stroke:currentColor;opacity:.25}.components-popover{box-sizing:border-box;will-change:transform;z-index:1000000}.components-popover *,.components-popover :after,.components-popover :before{box-sizing:inherit}.components-popover.is-expanded{bottom:0;left:0;position:fixed;right:0;top:0;z-index:1000000!important}.components-popover__content{background:#fff;border-radius:4px;box-shadow:0 0 0 1px #ccc,0 2px 3px #0000000d,0 4px 5px #0000000a,0 12px 12px #00000008,0 16px 16px #00000005;box-sizing:border-box;width:min-content}.is-alternate .components-popover__content{border-radius:2px;box-shadow:0 0 0 1px #1e1e1e}.is-unstyled .components-popover__content{background:none;border-radius:0;box-shadow:none}.components-popover.is-expanded .components-popover__content{box-shadow:0 -1px 0 0 #ccc;height:calc(100% - 48px);overflow-y:visible;position:static;width:auto}.components-popover.is-expanded.is-alternate .components-popover__content{box-shadow:0 -1px 0 #1e1e1e}.components-popover__header{align-items:center;background:#fff;display:flex;height:48px;justify-content:space-between;padding:0 8px 0 16px}.components-popover__header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:100%}.components-popover__close.components-button{z-index:5}.components-popover__arrow{display:flex;height:14px;pointer-events:none;position:absolute;width:14px}.components-popover__arrow:before{background-color:#fff;content:"";height:2px;left:1px;position:absolute;right:1px;top:-1px}.components-popover__arrow.is-top{bottom:-14px!important;transform:rotate(0)}.components-popover__arrow.is-right{left:-14px!important;transform:rotate(90deg)}.components-popover__arrow.is-bottom{top:-14px!important;transform:rotate(180deg)}.components-popover__arrow.is-left{right:-14px!important;transform:rotate(-90deg)}.components-popover__triangle{display:block;flex:1}.components-popover__triangle-bg{fill:#fff}.components-popover__triangle-border{fill:#0000;stroke-width:1px;stroke:#ccc}.is-alternate .components-popover__triangle-border{stroke:#1e1e1e}.components-radio-control{border:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;margin:0;padding:0}.components-radio-control__group-wrapper.has-help{margin-block-end:12px}.components-radio-control__option{align-items:center;column-gap:8px;display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto minmax(0,max-content)}.components-radio-control__input[type=radio]{appearance:none;border:1px solid #1e1e1e;border-radius:2px;border-radius:50%;box-shadow:0 0 0 #0000;cursor:pointer;display:inline-flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;grid-column:1;grid-row:1;height:24px;line-height:normal;margin:0;max-width:24px;min-width:24px;padding:0;position:relative;transition:none;width:24px}@media not (prefers-reduced-motion){.components-radio-control__input[type=radio]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-radio-control__input[type=radio]{font-size:13px;line-height:normal}}.components-radio-control__input[type=radio]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]::-webkit-input-placeholder{color:#1e1e1e9e}.components-radio-control__input[type=radio]::-moz-placeholder{color:#1e1e1e9e}.components-radio-control__input[type=radio]:-ms-input-placeholder{color:#1e1e1e9e}@media (min-width:600px){.components-radio-control__input[type=radio]{height:16px;max-width:16px;min-width:16px;width:16px}}.components-radio-control__input[type=radio]:checked:before{background-color:#fff;border:4px solid #fff;box-sizing:inherit;height:12px;left:50%;margin:0;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}@media (min-width:600px){.components-radio-control__input[type=radio]:checked:before{height:8px;width:8px}}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--wp-admin-theme-color)}.components-radio-control__input[type=radio]:checked{background:var(--wp-admin-theme-color);border:none}.components-radio-control__input[type=radio]:focus{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.components-radio-control__input[type=radio]:checked{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-color:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-radio-control__input[type=radio]:checked:before{border-radius:50%;content:""}.components-radio-control__label{cursor:pointer;grid-column:2;grid-row:1;line-height:24px}@media (min-width:600px){.components-radio-control__label{line-height:16px}}.components-radio-control__option-description{grid-column:2;grid-row:2;padding-block-start:4px}.components-radio-control__option-description.components-radio-control__option-description{margin-top:0}.components-resizable-box__handle{display:none;height:23px;width:23px;z-index:2}.components-resizable-box__container.has-show-handle .components-resizable-box__handle{display:block}.components-resizable-box__handle>div{height:100%;outline:none;position:relative;width:100%;z-index:2}.components-resizable-box__container>img{width:inherit}.components-resizable-box__handle:after{background:#fff;border-radius:50%;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9)),0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;content:"";cursor:inherit;display:block;height:15px;outline:2px solid #0000;position:absolute;right:calc(50% - 8px);top:calc(50% - 8px);width:15px}.components-resizable-box__side-handle:before{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-radius:9999px;content:"";cursor:inherit;display:block;height:3px;opacity:0;position:absolute;right:calc(50% - 1px);top:calc(50% - 1px);width:3px}@media not (prefers-reduced-motion){.components-resizable-box__side-handle:before{transition:transform .1s ease-in;will-change:transform}}.components-resizable-box__corner-handle,.components-resizable-box__side-handle{z-index:2}.components-resizable-box__side-handle.components-resizable-box__handle-bottom,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:before,.components-resizable-box__side-handle.components-resizable-box__handle-top,.components-resizable-box__side-handle.components-resizable-box__handle-top:before{border-left:0;border-right:0;left:0;width:100%}.components-resizable-box__side-handle.components-resizable-box__handle-left,.components-resizable-box__side-handle.components-resizable-box__handle-left:before,.components-resizable-box__side-handle.components-resizable-box__handle-right,.components-resizable-box__side-handle.components-resizable-box__handle-right:before{border-bottom:0;border-top:0;height:100%;top:0}@media not (prefers-reduced-motion){.components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{animation:components-resizable-box__top-bottom-animation .1s ease-out 0s;animation-fill-mode:forwards}.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before{animation:components-resizable-box__left-right-animation .1s ease-out 0s;animation-fill-mode:forwards}}@media not all and (min-resolution:0.001dpcm){@supports (-webkit-appearance:none){.components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{animation:none}}}@keyframes components-resizable-box__top-bottom-animation{0%{opacity:0;transform:scaleX(0)}to{opacity:1;transform:scaleX(1)}}@keyframes components-resizable-box__left-right-animation{0%{opacity:0;transform:scaleY(0)}to{opacity:1;transform:scaleY(1)}} /*!rtl:begin:ignore*/.components-resizable-box__handle-right{right:-11.5px}.components-resizable-box__handle-left{left:-11.5px}.components-resizable-box__handle-top{top:-11.5px}.components-resizable-box__handle-bottom{bottom:-11.5px} /*!rtl:end:ignore*/.components-responsive-wrapper{align-items:center;display:flex;justify-content:center;max-width:100%;position:relative}.components-responsive-wrapper__content{display:block;max-width:100%;width:100%}.components-sandbox{overflow:hidden}iframe.components-sandbox{width:100%}body.lockscroll,html.lockscroll{overflow:hidden}.components-select-control__input{outline:0;-webkit-tap-highlight-color:rgba(0,0,0,0)!important}@media (max-width:782px){.components-base-control .components-base-control__field .components-select-control__input{font-size:16px}}.components-snackbar{-webkit-backdrop-filter:blur(16px) saturate(180%);backdrop-filter:blur(16px) saturate(180%);background:#000000d9;border-radius:4px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;box-sizing:border-box;color:#fff;cursor:pointer;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;max-width:600px;padding:12px 20px;pointer-events:auto;width:100%}@media (min-width:600px){.components-snackbar{width:fit-content}}.components-snackbar:focus{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9))}.components-snackbar.components-snackbar-explicit-dismiss{cursor:default}.components-snackbar .components-snackbar__content-with-icon{padding-left:24px;position:relative}.components-snackbar .components-snackbar__icon{left:-8px;position:absolute;top:-2.9px}.components-snackbar .components-snackbar__dismiss-button{cursor:pointer;margin-left:24px}.components-snackbar__action.components-button{color:#fff;flex-shrink:0;margin-left:32px}.components-snackbar__action.components-button:focus{box-shadow:none;outline:1px dotted #fff}.components-snackbar__action.components-button:hover{color:currentColor;text-decoration:none}.components-snackbar__content{align-items:baseline;display:flex;justify-content:space-between;line-height:1.4}.components-snackbar-list{box-sizing:border-box;pointer-events:none;position:absolute;width:100%;z-index:100000}.components-snackbar-list__notice-container{padding-top:8px;position:relative}.components-tab-panel__tabs{align-items:stretch;display:flex;flex-direction:row}.components-tab-panel__tabs[aria-orientation=vertical]{flex-direction:column}.components-tab-panel__tabs-item{background:#0000;border:none;border-radius:0;box-shadow:none;cursor:pointer;font-weight:500;height:48px!important;margin-left:0;padding:3px 16px;position:relative}.components-tab-panel__tabs-item:focus:not(:disabled){box-shadow:none;outline:none;position:relative}.components-tab-panel__tabs-item:after{background:var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));border-radius:0;bottom:0;content:"";height:calc(var(--wp-admin-border-width-focus)*0);left:0;pointer-events:none;position:absolute;right:0}@media not (prefers-reduced-motion){.components-tab-panel__tabs-item:after{transition:all .1s linear}}.components-tab-panel__tabs-item.is-active:after{height:calc(var(--wp-admin-border-width-focus)*1);outline:2px solid #0000;outline-offset:-1px}.components-tab-panel__tabs-item:before{border-radius:2px;bottom:12px;box-shadow:0 0 0 0 #0000;content:"";left:12px;pointer-events:none;position:absolute;right:12px;top:12px}@media not (prefers-reduced-motion){.components-tab-panel__tabs-item:before{transition:all .1s linear}}.components-tab-panel__tabs-item:focus-visible:before{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000}.components-tab-panel__tab-content:focus{box-shadow:none;outline:none}.components-tab-panel__tab-content:focus-visible{box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent,var(--wp-admin-theme-color,#3858e9));outline:2px solid #0000;outline-offset:0}.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{border:1px solid #949494;border-radius:2px;box-shadow:0 0 0 #0000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:16px;height:32px;line-height:normal;margin:0;padding:6px 8px;width:100%}@media not (prefers-reduced-motion){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{transition:box-shadow .1s linear}}@media (min-width:600px){.components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{font-size:13px;line-height:normal}}.components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 .5px var(--wp-admin-theme-color);outline:2px solid #0000}.components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{color:#1e1e1e9e}.components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{color:#1e1e1e9e}.components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{color:#1e1e1e9e}.components-text-control__input.is-next-40px-default-size,.components-text-control__input[type=color].is-next-40px-default-size,.components-text-control__input[type=date].is-next-40px-default-size,.components-text-control__input[type=datetime-local].is-next-40px-default-size,.components-text-control__input[type=datetime].is-next-40px-default-size,.components-text-control__input[type=email].is-next-40px-default-size,.components-text-control__input[type=month].is-next-40px-default-size,.components-text-control__input[type=number].is-next-40px-default-size,.components-text-control__input[type=password].is-next-40px-default-size,.components-text-control__input[type=tel].is-next-40px-default-size,.components-text-control__input[type=text].is-next-40px-default-size,.components-text-control__input[type=time].is-next-40px-default-size,.components-text-control__input[type=url].is-next-40px-default-size,.components-text-control__input[type=week].is-next-40px-default-size{height:40px;padding-left:12px;padding-right:12px}.components-text-control__input[type=email],.components-text-control__input[type=url]{direction:ltr}.components-tip{color:#757575;display:flex}.components-tip svg{align-self:center;fill:#f0b849;flex-shrink:0;margin-right:16px}.components-tip p{margin:0}.components-toggle-control__label{line-height:16px}.components-toggle-control__label:not(.is-disabled){cursor:pointer}.components-toggle-control__help{display:inline-block;margin-inline-start:40px}.components-accessible-toolbar{border:1px solid #1e1e1e;border-radius:2px;display:inline-flex;flex-shrink:0}.components-accessible-toolbar>.components-toolbar-group:last-child{border-right:none}.components-accessible-toolbar.is-unstyled{border:none}.components-accessible-toolbar.is-unstyled>.components-toolbar-group{border-right:none}.components-accessible-toolbar[aria-orientation=vertical],.components-toolbar[aria-orientation=vertical]{align-items:center;display:flex;flex-direction:column}.components-accessible-toolbar .components-button,.components-toolbar .components-button{height:48px;padding-left:16px;padding-right:16px;position:relative;z-index:1}.components-accessible-toolbar .components-button:focus:not(:disabled),.components-toolbar .components-button:focus:not(:disabled){box-shadow:none;outline:none}.components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.components-accessible-toolbar .components-button svg,.components-toolbar .components-button svg{margin-left:auto;margin-right:auto;position:relative}.components-accessible-toolbar .components-button.is-pressed,.components-accessible-toolbar .components-button.is-pressed:hover,.components-toolbar .components-button.is-pressed,.components-toolbar .components-button.is-pressed:hover{background:#0000}.components-accessible-toolbar .components-button.is-pressed:before,.components-toolbar .components-button.is-pressed:before{background:#1e1e1e}.components-accessible-toolbar .components-button:focus:before,.components-toolbar .components-button:focus:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.components-accessible-toolbar .components-button.has-icon.has-icon,.components-toolbar .components-button.has-icon.has-icon{min-width:48px;padding-left:8px;padding-right:8px}@keyframes components-button__appear-animation{0%{transform:scaleY(0)}to{transform:scaleY(1)}}.components-toolbar__control.components-button{position:relative}.components-toolbar__control.components-button[data-subscript] svg{padding:5px 10px 5px 0}.components-toolbar__control.components-button[data-subscript]:after{bottom:10px;content:attr(data-subscript);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:600;line-height:12px;position:absolute;right:8px}.components-toolbar__control.components-button:not(:disabled).is-pressed[data-subscript]:after{color:#fff}.components-toolbar-group{background-color:#fff;border-right:1px solid #1e1e1e;display:inline-flex;flex-shrink:0;flex-wrap:wrap;line-height:0;min-height:48px;padding-left:6px;padding-right:6px}.components-toolbar-group .components-toolbar-group.components-toolbar-group{border-width:0;margin:0}.components-toolbar-group .components-button.components-button,.components-toolbar-group .components-button.has-icon.has-icon{justify-content:center;min-width:36px;padding-left:6px;padding-right:6px}.components-toolbar-group .components-button.components-button svg,.components-toolbar-group .components-button.has-icon.has-icon svg{min-width:24px}.components-toolbar-group .components-button.components-button:before,.components-toolbar-group .components-button.has-icon.has-icon:before{left:2px;right:2px}.components-toolbar{background-color:#fff;border:1px solid #1e1e1e;display:inline-flex;flex-shrink:0;flex-wrap:wrap;margin:0;min-height:48px}.components-toolbar .components-toolbar.components-toolbar{border-width:0;margin:0}div.components-toolbar>div{display:flex;margin:0}div.components-toolbar>div+div.has-left-divider{margin-left:6px;overflow:visible;position:relative}div.components-toolbar>div+div.has-left-divider:before{background-color:#ddd;box-sizing:initial;content:"";display:inline-block;height:20px;left:-3px;position:absolute;top:8px;width:1px}.components-tooltip{background:#000;border-radius:2px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;color:#f0f0f0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:12px;line-height:1.4;padding:4px 8px;text-align:center;z-index:1000002}.components-tooltip__shortcut{margin-left:8px}@charset "UTF-8"; :root{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } @media not (prefers-reduced-motion){ .components-animate__appear{ animation:components-animate__appear-animation .1s cubic-bezier(0, 0, .2, 1) 0s; animation-fill-mode:forwards; } } .components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{ transform-origin:top right; } .components-animate__appear.is-from-top.is-from-right{ transform-origin:top left; } .components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{ transform-origin:bottom right; } .components-animate__appear.is-from-bottom.is-from-right{ transform-origin:bottom left; } @keyframes components-animate__appear-animation{ 0%{ transform:translateY(-2em) scaleY(0) scaleX(0); } to{ transform:translateY(0) scaleY(1) scaleX(1); } } @media not (prefers-reduced-motion){ .components-animate__slide-in{ animation:components-animate__slide-in-animation .1s cubic-bezier(0, 0, .2, 1); animation-fill-mode:forwards; } .components-animate__slide-in.is-from-left{ transform:translateX(-100%); } .components-animate__slide-in.is-from-right{ transform:translateX(100%); } } @keyframes components-animate__slide-in-animation{ to{ transform:translateX(0); } } @media not (prefers-reduced-motion){ .components-animate__loading{ animation:components-animate__loading 1.6s ease-in-out infinite; } } @keyframes components-animate__loading{ 0%{ opacity:.5; } 50%{ opacity:1; } to{ opacity:.5; } } .components-autocomplete__popover .components-popover__content{ min-width:200px; padding:8px; } .components-autocomplete__result.components-button{ display:flex; height:auto; min-height:36px; text-align:right; width:100%; } .components-autocomplete__result.components-button:focus:not(:disabled){ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .components-badge{ align-items:center; background-color:color-mix(in srgb, #fff 90%, var(--base-color)); border-radius:2px; box-sizing:border-box; color:color-mix(in srgb, #000 50%, var(--base-color)); display:inline-flex; font-size:12px; font-weight:400; gap:2px; line-height:20px; max-width:100%; min-height:24px; padding:0 8px; } .components-badge *,.components-badge :after,.components-badge :before{ box-sizing:inherit; } .components-badge:where(.is-default){ background-color:#f0f0f0; color:#2f2f2f; } .components-badge.has-icon{ padding-inline-start:4px; } .components-badge.is-info{ --base-color:#3858e9; } .components-badge.is-warning{ --base-color:#f0b849; } .components-badge.is-error{ --base-color:#cc1818; } .components-badge.is-success{ --base-color:#4ab866; } .components-badge__icon{ flex-shrink:0; } .components-badge__content{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .components-button-group{ display:inline-block; } .components-button-group .components-button{ border-radius:0; box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; display:inline-flex; } .components-button-group .components-button+.components-button{ margin-right:-1px; } .components-button-group .components-button:first-child{ border-radius:0 2px 2px 0; } .components-button-group .components-button:last-child{ border-radius:2px 0 0 2px; } .components-button-group .components-button.is-primary,.components-button-group .components-button:focus{ position:relative; z-index:1; } .components-button-group .components-button.is-primary{ box-shadow:inset 0 0 0 1px #1e1e1e; } .components-button{ align-items:center; -webkit-appearance:none; background:none; border:0; border-radius:2px; box-sizing:border-box; color:var(--wp-components-color-foreground, #1e1e1e); cursor:pointer; display:inline-flex; font-family:inherit; font-size:13px; height:36px; margin:0; padding:6px 12px; text-decoration:none; } @media not (prefers-reduced-motion){ .components-button{ transition:box-shadow .1s linear; } } .components-button.is-next-40px-default-size{ height:40px; } .components-button:hover:not(:disabled,[aria-disabled=true]),.components-button[aria-expanded=true]{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:3px solid #0000; } .components-button.is-primary{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:var(--wp-components-color-accent-inverted, #fff); outline:1px solid #0000; text-decoration:none; text-shadow:none; white-space:nowrap; } .components-button.is-primary:hover:not(:disabled){ background:var(--wp-components-color-accent-darker-10, var(--wp-admin-theme-color-darker-10, #2145e6)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-primary:active:not(:disabled){ background:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); border-color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-primary:focus:not(:disabled){ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#fff6; outline:none; } .components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{ background-image:linear-gradient(45deg, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 33%, var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)) 33%, var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)) 70%, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 70%); background-size:100px 100%; border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-secondary,.components-button.is-tertiary{ outline:1px solid #0000; } .components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){ box-shadow:none; } .components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{ background:#0000; color:#949494; transform:none; } .components-button.is-secondary{ background:#0000; box-shadow:inset 0 0 0 1px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)), 0 0 0 currentColor; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:1px solid #0000; white-space:nowrap; } .components-button.is-secondary:hover:not(:disabled,[aria-disabled=true],.is-pressed){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 4%, #0000); box-shadow:inset 0 0 0 1px var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); } .components-button.is-secondary:disabled:not(:focus),.components-button.is-secondary[aria-disabled=true]:hover:not(:focus),.components-button.is-secondary[aria-disabled=true]:not(:focus){ box-shadow:inset 0 0 0 1px #ddd; } .components-button.is-secondary:focus:not(:disabled){ box-shadow:0 0 0 currentColor inset, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-tertiary{ background:#0000; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); white-space:nowrap; } .components-button.is-tertiary:hover:not(:disabled,[aria-disabled=true],.is-pressed){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 4%, #0000); color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); } .components-button.is-tertiary:active:not(:disabled,[aria-disabled=true]){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 8%, #0000); } p+.components-button.is-tertiary{ margin-right:-6px; } .components-button.is-tertiary:disabled:not(:focus),.components-button.is-tertiary[aria-disabled=true]:hover:not(:focus),.components-button.is-tertiary[aria-disabled=true]:not(:focus){ box-shadow:none; outline:none; } .components-button.is-destructive{ --wp-components-color-accent:#cc1818; --wp-components-color-accent-darker-10:#9e1313; --wp-components-color-accent-darker-20:#710d0d; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link){ color:#cc1818; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):hover:not(:disabled,[aria-disabled=true]){ color:#710d0d; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #cc1818; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):active:not(:disabled,[aria-disabled=true]){ background:#ccc; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):disabled,.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link)[aria-disabled=true]{ color:#949494; } .components-button.is-destructive.is-secondary:hover:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:hover:not(:disabled,[aria-disabled=true]){ background:#cc18180a; } .components-button.is-destructive.is-secondary:active:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:active:not(:disabled,[aria-disabled=true]){ background:#cc181814; } .components-button.is-link{ background:none; border:0; border-radius:0; box-shadow:none; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); height:auto; margin:0; outline:none; padding:0; text-align:right; text-decoration:underline; } @media not (prefers-reduced-motion){ .components-button.is-link{ transition-duration:.05s; transition-property:border, background, color; transition-timing-function:ease-in-out; } } .components-button.is-link:focus{ border-radius:2px; } .components-button.is-link:disabled,.components-button.is-link[aria-disabled=true]{ color:#949494; } .components-button:not(:disabled,[aria-disabled=true]):active{ color:var(--wp-components-color-foreground, #1e1e1e); } .components-button:disabled,.components-button[aria-disabled=true]{ color:#949494; cursor:default; } .components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{ background-image:linear-gradient(45deg, #fafafa 33%, #e0e0e0 0, #e0e0e0 70%, #fafafa 0); background-size:100px 100%; } @media not (prefers-reduced-motion){ .components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{ animation:components-button__busy-animation 2.5s linear infinite; } } .components-button.is-compact{ height:32px; } .components-button.is-compact.has-icon:not(.has-text){ min-width:32px; padding:0; width:32px; } .components-button.is-small{ font-size:11px; height:24px; line-height:22px; padding:0 8px; } .components-button.is-small.has-icon:not(.has-text){ min-width:24px; padding:0; width:24px; } .components-button.has-icon{ justify-content:center; min-width:36px; padding:6px; } .components-button.has-icon.is-next-40px-default-size{ min-width:40px; } .components-button.has-icon .dashicon{ align-items:center; box-sizing:initial; display:inline-flex; justify-content:center; padding:2px; } .components-button.has-icon.has-text{ gap:4px; justify-content:start; padding-left:12px; padding-right:8px; } .components-button.is-pressed,.components-button.is-pressed:hover{ color:var(--wp-components-color-foreground-inverted, #fff); } .components-button.is-pressed:hover:not(:disabled,[aria-disabled=true]),.components-button.is-pressed:not(:disabled,[aria-disabled=true]){ background:var(--wp-components-color-foreground, #1e1e1e); } .components-button.is-pressed:disabled,.components-button.is-pressed[aria-disabled=true]{ color:#949494; } .components-button.is-pressed:disabled:not(.is-primary):not(.is-secondary):not(.is-tertiary),.components-button.is-pressed[aria-disabled=true]:not(.is-primary):not(.is-secondary):not(.is-tertiary){ background:#949494; color:var(--wp-components-color-foreground-inverted, #fff); } .components-button.is-pressed:focus:not(:disabled){ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; } .components-button svg{ fill:currentColor; outline:none; } @media (forced-colors:active){ .components-button svg{ fill:CanvasText; } } .components-button .components-visually-hidden{ height:auto; } @keyframes components-button__busy-animation{ 0%{ background-position:right 200px top 0; } } .components-checkbox-control{ --checkbox-input-size:24px; --checkbox-input-margin:8px; } @media (min-width:600px){ .components-checkbox-control{ --checkbox-input-size:16px; } } .components-checkbox-control__label{ cursor:pointer; line-height:var(--checkbox-input-size); } .components-checkbox-control__input[type=checkbox]{ appearance:none; background:#fff; border:1px solid #1e1e1e; border-radius:2px; box-shadow:0 0 0 #0000; clear:none; color:#1e1e1e; cursor:pointer; display:inline-block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:var(--checkbox-input-size); line-height:normal; line-height:0; margin:0 0 0 4px; outline:0; padding:6px 8px; padding:0 !important; text-align:center; transition:none; vertical-align:top; width:var(--checkbox-input-size); } @media not (prefers-reduced-motion){ .components-checkbox-control__input[type=checkbox]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-checkbox-control__input[type=checkbox]{ font-size:13px; line-height:normal; } } .components-checkbox-control__input[type=checkbox]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]::-moz-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]:checked{ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]:checked::-ms-check{ opacity:0; } .components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ color:#fff; margin:-3px -5px; } @media (min-width:782px){ .components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ margin:-4px -5px 0 0; } } .components-checkbox-control__input[type=checkbox][aria-checked=mixed]{ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ content:"\f460"; display:inline-block; float:right; font:normal 30px/1 dashicons; vertical-align:middle; width:16px; speak:none; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; } @media (min-width:782px){ .components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ float:none; font-size:21px; } } .components-checkbox-control__input[type=checkbox]:disabled,.components-checkbox-control__input[type=checkbox][aria-disabled=true]{ background:#f0f0f0; border-color:#ddd; cursor:default; opacity:1; } @media not (prefers-reduced-motion){ .components-checkbox-control__input[type=checkbox]{ transition:border-color .1s ease-in-out; } } .components-checkbox-control__input[type=checkbox]:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .components-checkbox-control__input[type=checkbox]:checked,.components-checkbox-control__input[type=checkbox]:indeterminate{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-checkbox-control__input[type=checkbox]:checked::-ms-check,.components-checkbox-control__input[type=checkbox]:indeterminate::-ms-check{ opacity:0; } .components-checkbox-control__input[type=checkbox]:checked:before{ content:none; } .components-checkbox-control__input-container{ aspect-ratio:1; display:inline-block; flex-shrink:0; line-height:1; margin-left:var(--checkbox-input-margin); position:relative; vertical-align:middle; width:var(--checkbox-input-size); } svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{ --checkmark-size:var(--checkbox-input-size); fill:#fff; cursor:pointer; height:var(--checkmark-size); pointer-events:none; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); -webkit-user-select:none; user-select:none; width:var(--checkmark-size); } @media (min-width:600px){ svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{ --checkmark-size:calc(var(--checkbox-input-size) + 4px); } } .components-checkbox-control__help{ display:inline-block; margin-inline-start:calc(var(--checkbox-input-size) + var(--checkbox-input-margin)); } .components-circular-option-picker{ display:inline-block; min-width:188px; width:100%; } .components-circular-option-picker .components-circular-option-picker__custom-clear-wrapper{ display:flex; justify-content:flex-end; margin-top:12px; } .components-circular-option-picker .components-circular-option-picker__swatches{ display:flex; flex-wrap:wrap; gap:12px; position:relative; z-index:1; } .components-circular-option-picker>:not(.components-circular-option-picker__swatches){ position:relative; z-index:0; } .components-circular-option-picker__option-wrapper{ display:inline-block; height:28px; transform:scale(1); vertical-align:top; width:28px; } @media not (prefers-reduced-motion){ .components-circular-option-picker__option-wrapper{ transition:transform .1s ease; will-change:transform; } } .components-circular-option-picker__option-wrapper:hover{ transform:scale(1.2); } .components-circular-option-picker__option-wrapper>div{ height:100%; width:100%; } .components-circular-option-picker__option-wrapper:before{ background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none'%3E%3Cpath fill='%23555D65' d='M6 8V6H4v2zm2 0V6h2v2zm2 8H8v-2h2zm2 0v-2h2v2zm0 2v-2h-2v2H8v2h2v-2zm2 0v2h-2v-2zm2 0h-2v-2h2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M18 18h2v-2h-2v-2h2v-2h-2v-2h2V8h-2v2h-2V8h-2v2h2v2h-2v2h2v2h2zm-2-4v-2h2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' d='M18 18v2h-2v-2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M8 10V8H6v2H4v2h2v2H4v2h2v2H4v2h2v2H4v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2v2h-2V4h-2v2h-2V4h-2v2h-2V4h-2v2h2v2h-2v2zm0 2v-2H6v2zm2 0v-2h2v2zm0 2v-2H8v2H6v2h2v2H6v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h-2v2h-2V6h-2v2h-2v2h2v2h-2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M4 0H2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2H8V0H6v2H4zm0 4V2H2v2zm2 0V2h2v2zm0 2V4H4v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2H8v2z' clip-rule='evenodd'/%3E%3C/svg%3E"); border-radius:50%; bottom:1px; content:""; left:1px; position:absolute; right:1px; top:1px; z-index:-1; } .components-circular-option-picker__option{ aspect-ratio:1; background:#0000; border:none; border-radius:50%; box-shadow:inset 0 0 0 14px; cursor:pointer; display:inline-block; height:100% !important; vertical-align:top; } @media not (prefers-reduced-motion){ .components-circular-option-picker__option{ transition:box-shadow .1s ease; } } .components-circular-option-picker__option:hover{ box-shadow:inset 0 0 0 14px !important; } .components-circular-option-picker__option[aria-pressed=true],.components-circular-option-picker__option[aria-selected=true]{ box-shadow:inset 0 0 0 4px; overflow:visible; position:relative; z-index:1; } .components-circular-option-picker__option[aria-pressed=true]+svg,.components-circular-option-picker__option[aria-selected=true]+svg{ border-radius:50%; pointer-events:none; position:absolute; right:2px; top:2px; z-index:2; } .components-circular-option-picker__option:after{ border:1px solid #0000; border-radius:50%; bottom:-1px; box-shadow:inset 0 0 0 1px #0003; box-sizing:inherit; content:""; left:-1px; position:absolute; right:-1px; top:-1px; } .components-circular-option-picker__option:focus:after{ border:2px solid #757575; border-radius:50%; box-shadow:inset 0 0 0 2px #fff; content:""; height:calc(100% + 4px); position:absolute; right:50%; top:50%; transform:translate(50%, -50%); width:calc(100% + 4px); } .components-circular-option-picker__option.components-button:focus{ background-color:initial; box-shadow:inset 0 0 0 14px; outline:none; } .components-circular-option-picker__button-action .components-circular-option-picker__option{ background:#fff; color:#fff; } .components-circular-option-picker__dropdown-link-action{ margin-left:16px; } .components-circular-option-picker__dropdown-link-action .components-button{ line-height:22px; } .components-palette-edit__popover-gradient-picker{ padding:8px; width:260px; } .components-dropdown-menu__menu .components-palette-edit__menu-button{ width:100%; } .component-color-indicator{ background:#fff linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); border-radius:50%; box-shadow:inset 0 0 0 1px #0003; display:inline-block; height:20px; padding:0; width:20px; } .components-combobox-control{ width:100%; } input.components-combobox-control__input[type=text]{ border:none; box-shadow:none; font-family:inherit; font-size:16px; line-height:inherit; margin:0; min-height:auto; padding:2px; width:100%; } @media (min-width:600px){ input.components-combobox-control__input[type=text]{ font-size:13px; } } input.components-combobox-control__input[type=text]:focus{ box-shadow:none; outline:none; } .components-combobox-control__suggestions-container{ align-items:flex-start; border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; display:flex; flex-wrap:wrap; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:0; width:100%; } @media not (prefers-reduced-motion){ .components-combobox-control__suggestions-container{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-combobox-control__suggestions-container{ font-size:13px; line-height:normal; } } .components-combobox-control__suggestions-container:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-combobox-control__suggestions-container::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container::-moz-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container:-ms-input-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container:focus-within{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-combobox-control__suggestions-container .components-spinner{ margin:0; } .components-color-palette__custom-color-wrapper{ position:relative; z-index:0; } .components-color-palette__custom-color-button{ background:none; border:none; border-radius:4px 4px 0 0; box-shadow:inset 0 0 0 1px #0003; box-sizing:border-box; cursor:pointer; height:64px; outline:1px solid #0000; position:relative; width:100%; } .components-color-palette__custom-color-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline-width:2px; } .components-color-palette__custom-color-button:after{ background-image:repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0), repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0); background-position:0 0, 24px 24px; background-size:48px 48px; border-radius:3px 3px 0 0; content:""; inset:1px; position:absolute; z-index:-1; } .components-color-palette__custom-color-text-wrapper{ border-radius:0 0 4px 4px; box-shadow:inset 0 -1px 0 0 #0003,inset -1px 0 0 0 #0003,inset 1px 0 0 0 #0003; font-size:13px; padding:12px 16px; position:relative; } .components-color-palette__custom-color-name{ color:var(--wp-components-color-foreground, #1e1e1e); margin:0 1px; } .components-color-palette__custom-color-value{ color:#757575; } .components-color-palette__custom-color-value--is-hex{ text-transform:uppercase; } .components-color-palette__custom-color-value:empty:after{ content:""; visibility:hidden; } .components-custom-gradient-picker__gradient-bar{ border-radius:2px; height:48px; position:relative; width:100%; z-index:1; } .components-custom-gradient-picker__gradient-bar.has-gradient{ background-image:repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0), repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0); background-position:0 0, 12px 12px; background-size:24px 24px; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__gradient-bar-background{ inset:0; position:absolute; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__markers-container{ margin-left:auto; margin-right:auto; position:relative; width:calc(100% - 48px); } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-dropdown{ display:flex; height:16px; position:absolute; top:16px; width:16px; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown{ background:#fff; border-radius:50%; color:#1e1e1e; height:inherit; min-width:16px !important; padding:2px; position:relative; width:inherit; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown svg{ height:100%; width:100%; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button{ border-radius:50%; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 2px 0 #00000040; height:inherit; outline:2px solid #0000; padding:0; width:inherit; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button.is-active,.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button:focus{ box-shadow:inset 0 0 0 calc(var(--wp-admin-border-width-focus)*2) #fff, 0 0 2px 0 #00000040; outline:1.5px solid #0000; } .components-custom-gradient-picker__remove-control-point-wrapper{ padding-bottom:8px; } .components-custom-gradient-picker__inserter{ direction:ltr; } .components-custom-gradient-picker__liner-gradient-indicator{ display:inline-block; flex:0 auto; height:20px; width:20px; } .components-custom-gradient-picker__ui-line{ position:relative; z-index:0; } .block-editor-dimension-control .components-base-control__field{ align-items:center; display:flex; } .block-editor-dimension-control .components-base-control__label{ align-items:center; display:flex; margin-bottom:0; margin-left:1em; } .block-editor-dimension-control .components-base-control__label .dashicon{ margin-left:.5em; } .block-editor-dimension-control.is-manual .components-base-control__label{ width:10em; } body.is-dragging-components-draggable{ cursor:move; cursor:grabbing !important; } .components-draggable__invisible-drag-image{ height:50px; position:fixed; right:-1000px; width:50px; } .components-draggable__clone{ background:#0000; padding:0; pointer-events:none; position:fixed; z-index:1000000000; } .components-drop-zone{ border-radius:2px; bottom:0; left:0; opacity:0; position:absolute; right:0; top:0; visibility:hidden; z-index:40; } .components-drop-zone.is-active{ opacity:1; visibility:visible; } .components-drop-zone .components-drop-zone__content{ align-items:center; background-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); bottom:0; color:#fff; display:flex; height:100%; justify-content:center; left:0; opacity:0; pointer-events:none; position:absolute; right:0; text-align:center; top:0; width:100%; z-index:50; } .components-drop-zone .components-drop-zone__content-inner{ opacity:0; transform:scale(.9); } .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{ opacity:1; } @media not (prefers-reduced-motion){ .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{ transition:opacity .2s ease-in-out; } } .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{ opacity:1; transform:scale(1); } @media not (prefers-reduced-motion){ .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{ transition:opacity .1s ease-in-out .1s,transform .1s ease-in-out .1s; } } .components-drop-zone__content-icon,.components-drop-zone__content-text{ display:block; } .components-drop-zone__content-icon{ line-height:0; margin:0 auto 8px; fill:currentColor; pointer-events:none; } .components-drop-zone__content-text{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .components-dropdown{ display:inline-block; } .components-dropdown__content .components-popover__content{ padding:8px; } .components-dropdown__content .components-popover__content:has(.components-menu-group){ padding:0; } .components-dropdown__content .components-popover__content:has(.components-menu-group) .components-dropdown-menu__menu>.components-menu-item__button,.components-dropdown__content .components-popover__content:has(.components-menu-group)>.components-menu-item__button{ margin:8px; width:auto; } .components-dropdown__content [role=menuitem]{ white-space:nowrap; } .components-dropdown__content .components-menu-group{ padding:8px; } .components-dropdown__content .components-menu-group+.components-menu-group{ border-top:1px solid #ccc; padding:8px; } .components-dropdown__content.is-alternate .components-menu-group+.components-menu-group{ border-color:#1e1e1e; } .components-dropdown-menu__toggle{ vertical-align:top; } .components-dropdown-menu__menu{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:1.4; width:100%; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item,.components-dropdown-menu__menu .components-menu-item{ cursor:pointer; outline:none; padding:6px; white-space:nowrap; width:100%; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator,.components-dropdown-menu__menu .components-menu-item.has-separator{ margin-top:6px; overflow:visible; position:relative; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator:before,.components-dropdown-menu__menu .components-menu-item.has-separator:before{ background-color:#ddd; box-sizing:initial; content:""; display:block; height:1px; left:0; position:absolute; right:0; top:-3px; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active svg,.components-dropdown-menu__menu .components-menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-menu-item.is-active svg{ background:#1e1e1e; border-radius:1px; box-shadow:0 0 0 1px #1e1e1e; color:#fff; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-icon-only,.components-dropdown-menu__menu .components-menu-item.is-icon-only{ width:auto; } .components-dropdown-menu__menu .components-menu-item__button,.components-dropdown-menu__menu .components-menu-item__button.components-button{ height:auto; min-height:40px; padding-left:8px; padding-right:8px; text-align:right; } .components-duotone-picker__color-indicator:before{ background:#0000; } .components-duotone-picker__color-indicator>.components-button,.components-duotone-picker__color-indicator>.components-button.is-pressed:hover:not(:disabled){ background:linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); color:#0000; } .components-duotone-picker__color-indicator>.components-button:not([aria-disabled=true]):active{ color:#0000; } .components-color-list-picker,.components-color-list-picker__swatch-button{ width:100%; } .components-color-list-picker__color-picker{ margin:8px 0; } .components-color-list-picker__swatch-color{ margin:2px; } .components-external-link{ text-decoration:none; } .components-external-link__contents{ text-decoration:underline; } .components-external-link__icon{ font-weight:400; margin-right:.5ch; } .components-form-toggle,.components-form-toggle .components-form-toggle__track{ display:inline-block; height:16px; position:relative; } .components-form-toggle .components-form-toggle__track{ background-color:#fff; border:1px solid #949494; border-radius:8px; box-sizing:border-box; content:""; overflow:hidden; vertical-align:top; width:32px; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__track{ transition:background-color .2s ease,border-color .2s ease; } } .components-form-toggle .components-form-toggle__track:after{ border-top:16px solid #0000; box-sizing:border-box; content:""; inset:0; opacity:0; position:absolute; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__track:after{ transition:opacity .2s ease; } } .components-form-toggle .components-form-toggle__thumb{ background-color:#1e1e1e; border:6px solid #0000; border-radius:50%; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; box-sizing:border-box; display:block; height:12px; position:absolute; right:2px; top:2px; width:12px; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__thumb{ transition:transform .2s ease,background-color .2s ease-out; } } .components-form-toggle.is-checked .components-form-toggle__track{ background-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-form-toggle.is-checked .components-form-toggle__track:after{ opacity:1; } .components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:2px; } .components-form-toggle.is-checked .components-form-toggle__thumb{ background-color:#fff; border-width:0; transform:translateX(-16px); } .components-disabled .components-form-toggle,.components-form-toggle.is-disabled{ opacity:.3; } .components-form-toggle input.components-form-toggle__input[type=checkbox]{ border:none; height:100%; margin:0; opacity:0; padding:0; position:absolute; right:0; top:0; width:100%; z-index:1; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{ background:none; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:before{ content:""; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:not(:disabled,[aria-disabled=true]){ cursor:pointer; } .components-form-token-field__input-container{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; cursor:text; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:0; width:100%; } @media not (prefers-reduced-motion){ .components-form-token-field__input-container{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-form-token-field__input-container{ font-size:13px; line-height:normal; } } .components-form-token-field__input-container:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-form-token-field__input-container::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container::-moz-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container:-ms-input-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container.is-disabled{ background:#ddd; border-color:#ddd; } .components-form-token-field__input-container.is-active{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-form-token-field__input-container input[type=text].components-form-token-field__input{ background:inherit; border:0; box-shadow:none; color:#1e1e1e; display:inline-block; flex:1; font-family:inherit; font-size:16px; margin-right:4px; max-width:100%; min-height:24px; min-width:50px; padding:0; width:100%; } @media (min-width:600px){ .components-form-token-field__input-container input[type=text].components-form-token-field__input{ font-size:13px; } } .components-form-token-field.is-active .components-form-token-field__input-container input[type=text].components-form-token-field__input,.components-form-token-field__input-container input[type=text].components-form-token-field__input:focus{ box-shadow:none; outline:none; } .components-form-token-field__input-container .components-form-token-field__token+input[type=text].components-form-token-field__input{ width:auto; } .components-form-token-field__token{ color:#1e1e1e; display:flex; font-size:13px; max-width:100%; } .components-form-token-field__token.is-success .components-form-token-field__remove-token,.components-form-token-field__token.is-success .components-form-token-field__token-text{ background:#4ab866; } .components-form-token-field__token.is-error .components-form-token-field__remove-token,.components-form-token-field__token.is-error .components-form-token-field__token-text{ background:#cc1818; } .components-form-token-field__token.is-validating .components-form-token-field__remove-token,.components-form-token-field__token.is-validating .components-form-token-field__token-text{ color:#757575; } .components-form-token-field__token.is-borderless{ padding:0 0 0 24px; position:relative; } .components-form-token-field__token.is-borderless .components-form-token-field__token-text{ background:#0000; } .components-form-token-field__token.is-borderless:not(.is-disabled) .components-form-token-field__token-text{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-form-token-field__token.is-borderless .components-form-token-field__remove-token{ background:#0000; color:#757575; left:0; position:absolute; top:1px; } .components-form-token-field__token.is-borderless.is-success .components-form-token-field__token-text{ color:#4ab866; } .components-form-token-field__token.is-borderless.is-error .components-form-token-field__token-text{ color:#cc1818; padding:0 6px 0 4px; } .components-form-token-field__token.is-borderless.is-validating .components-form-token-field__token-text{ color:#1e1e1e; } .components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{ background:#ddd; display:inline-block; height:auto; min-width:unset; } @media not (prefers-reduced-motion){ .components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{ transition:all .2s cubic-bezier(.4, 1, .4, 1); } } .components-form-token-field__token-text{ border-radius:0 1px 1px 0; line-height:24px; overflow:hidden; padding:0 8px 0 0; text-overflow:ellipsis; white-space:nowrap; } .components-form-token-field__remove-token.components-button{ border-radius:1px 0 0 1px; color:#1e1e1e; line-height:10px; overflow:initial; } .components-form-token-field__remove-token.components-button:hover:not(:disabled){ color:#1e1e1e; } .components-form-token-field__suggestions-list{ box-shadow:inset 0 1px 0 0 #949494; flex:1 0 100%; list-style:none; margin:0; max-height:128px; min-width:100%; overflow-y:auto; padding:0; } @media not (prefers-reduced-motion){ .components-form-token-field__suggestions-list{ transition:all .15s ease-in-out; } } .components-form-token-field__suggestion{ box-sizing:border-box; color:#1e1e1e; display:block; font-size:13px; margin:0; min-height:32px; padding:8px 12px; } .components-form-token-field__suggestion.is-selected{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#fff; } .components-form-token-field__suggestion[aria-disabled=true]{ color:#949494; pointer-events:none; } .components-form-token-field__suggestion[aria-disabled=true].is-selected{ background-color:rgba(var(--wp-components-color-accent--rgb, var(--wp-admin-theme-color--rgb)), .04); } .components-form-token-field__suggestion:not(.is-empty){ cursor:pointer; } @media (min-width:600px){ .components-guide{ width:600px; } } .components-guide .components-modal__content{ margin-top:0; padding:0; } .components-guide .components-modal__content:before{ content:none; } .components-guide .components-modal__header{ border-bottom:none; height:60px; padding:0; position:sticky; } .components-guide .components-modal__header .components-button{ align-self:flex-start; margin:8px 0 0 8px; position:static; } .components-guide .components-modal__header .components-button:hover svg{ fill:#fff; } .components-guide .components-guide__container{ display:flex; flex-direction:column; justify-content:space-between; margin-top:-60px; min-height:100%; } .components-guide .components-guide__page{ display:flex; flex-direction:column; justify-content:center; position:relative; } @media (min-width:600px){ .components-guide .components-guide__page{ min-height:300px; } } .components-guide .components-guide__footer{ align-content:center; display:flex; height:36px; justify-content:center; margin:0 0 24px; padding:0 32px; position:relative; width:100%; } .components-guide .components-guide__page-control{ margin:0; text-align:center; } .components-guide .components-guide__page-control li{ display:inline-block; margin:0; } .components-guide .components-guide__page-control .components-button{ color:#e0e0e0; margin:-6px 0; } .components-guide .components-guide__page-control li[aria-current=step] .components-button{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-modal__frame.components-guide{ border:none; max-height:575px; min-width:312px; } @media (max-width:600px){ .components-modal__frame.components-guide{ margin:auto; max-width:calc(100vw - 32px); } } .components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{ position:absolute; } .components-button.components-guide__back-button{ right:32px; } .components-button.components-guide__finish-button,.components-button.components-guide__forward-button{ left:32px; } [role=region]{ position:relative; } .is-focusing-regions [role=region]:focus:after,[role=region].interface-interface-skeleton__content:focus-visible:after{ bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; z-index:1000000; } .is-focusing-regions .editor-post-publish-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-entities-saved-states-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-publish-panel,.is-focusing-regions .interface-interface-skeleton__sidebar .editor-layout__toggle-sidebar-panel,.is-focusing-regions [role=region]:focus:after,.is-focusing-regions.is-distraction-free .interface-interface-skeleton__header .edit-post-header,[role=region].interface-interface-skeleton__content:focus-visible:after{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2); } .components-menu-group+.components-menu-group{ border-top:1px solid #1e1e1e; padding-top:8px; } .components-menu-group+.components-menu-group.has-hidden-separator{ border-top:none; margin-top:0; padding-top:0; } .components-menu-group:has(>div:empty){ display:none; } .components-menu-group__label{ color:#757575; font-size:11px; font-weight:500; margin-bottom:12px; margin-top:4px; padding:0 8px; text-transform:uppercase; white-space:nowrap; } .components-menu-item__button,.components-menu-item__button.components-button{ width:100%; } .components-menu-item__button.components-button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button.components-button[role=menuitemradio] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemradio] .components-menu-item__item:only-child{ box-sizing:initial; padding-left:48px; } .components-menu-item__button .components-menu-items__item-icon,.components-menu-item__button.components-button .components-menu-items__item-icon{ display:inline-block; flex:0 0 auto; } .components-menu-item__button .components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-items__item-icon.has-icon-right{ margin-left:-2px; margin-right:24px; } .components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right{ margin-right:8px; } .components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{ margin-left:8px; margin-right:-2px; } .components-menu-item__button.components-button.is-primary,.components-menu-item__button.is-primary{ justify-content:center; } .components-menu-item__button.components-button.is-primary .components-menu-item__item,.components-menu-item__button.is-primary .components-menu-item__item{ margin-left:0; } .components-menu-item__button.components-button:disabled.is-tertiary,.components-menu-item__button.components-button[aria-disabled=true].is-tertiary,.components-menu-item__button:disabled.is-tertiary,.components-menu-item__button[aria-disabled=true].is-tertiary{ background:none; color:var(--wp-components-color-accent-darker-10, var(--wp-admin-theme-color-darker-10, #2145e6)); opacity:.3; } .components-menu-item__info-wrapper{ display:flex; flex-direction:column; margin-left:auto; } .components-menu-item__info{ color:#757575; font-size:12px; margin-top:4px; white-space:normal; } .components-menu-item__item{ align-items:center; display:inline-flex; margin-left:auto; min-width:160px; white-space:nowrap; } .components-menu-item__shortcut{ align-self:center; color:currentColor; display:none; margin-left:0; margin-right:auto; padding-right:24px; } @media (min-width:480px){ .components-menu-item__shortcut{ display:inline; } } .components-menu-items-choice,.components-menu-items-choice.components-button{ height:auto; min-height:40px; } .components-menu-items-choice svg,.components-menu-items-choice.components-button svg{ margin-left:12px; } .components-menu-items-choice.components-button.has-icon,.components-menu-items-choice.has-icon{ padding-right:12px; } .components-modal__screen-overlay{ background-color:#00000059; bottom:0; display:flex; left:0; position:fixed; right:0; top:0; z-index:100000; } @keyframes __wp-base-styles-fade-in{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .components-modal__screen-overlay{ animation:__wp-base-styles-fade-in .08s linear 0s; animation-fill-mode:forwards; } } @keyframes __wp-base-styles-fade-out{ 0%{ opacity:1; } to{ opacity:0; } } @media not (prefers-reduced-motion){ .components-modal__screen-overlay.is-animating-out{ animation:__wp-base-styles-fade-out .08s linear 80ms; animation-fill-mode:forwards; } } .components-modal__frame{ animation-fill-mode:forwards; animation-name:components-modal__appear-animation; animation-timing-function:cubic-bezier(.29, 0, 0, 1); background:#fff; border-radius:8px 8px 0 0; box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; box-sizing:border-box; display:flex; margin:40px 0 0; overflow:hidden; width:100%; } .components-modal__frame *,.components-modal__frame :after,.components-modal__frame :before{ box-sizing:inherit; } @media not (prefers-reduced-motion){ .components-modal__frame{ animation-duration:var(--modal-frame-animation-duration); } } .components-modal__screen-overlay.is-animating-out .components-modal__frame{ animation-name:components-modal__disappear-animation; animation-timing-function:cubic-bezier(1, 0, .2, 1); } @media (min-width:600px){ .components-modal__frame{ border-radius:8px; margin:auto; max-height:calc(100% - 120px); max-width:calc(100% - 32px); min-width:350px; width:auto; } } @media (min-width:600px) and (min-width:600px){ .components-modal__frame.is-full-screen{ height:calc(100% - 32px); max-height:none; width:calc(100% - 32px); } } @media (min-width:600px) and (min-width:782px){ .components-modal__frame.is-full-screen{ height:calc(100% - 80px); max-width:none; width:calc(100% - 80px); } } @media (min-width:600px){ .components-modal__frame.has-size-large,.components-modal__frame.has-size-medium,.components-modal__frame.has-size-small{ width:100%; } .components-modal__frame.has-size-small{ max-width:384px; } .components-modal__frame.has-size-medium{ max-width:512px; } .components-modal__frame.has-size-large{ max-width:840px; } } @media (min-width:960px){ .components-modal__frame{ max-height:70%; } } @keyframes components-modal__appear-animation{ 0%{ opacity:0; transform:scale(.9); } to{ opacity:1; transform:scale(1); } } @keyframes components-modal__disappear-animation{ 0%{ opacity:1; transform:scale(1); } to{ opacity:0; transform:scale(.9); } } .components-modal__header{ align-items:center; border-bottom:1px solid #0000; box-sizing:border-box; display:flex; flex-direction:row; height:72px; justify-content:space-between; padding:24px 32px 8px; position:absolute; right:0; top:0; width:100%; z-index:10; } .components-modal__header .components-modal__header-heading{ font-size:1.2rem; font-weight:600; } .components-modal__header h1{ line-height:1; margin:0; } .components-modal__content.has-scrolled-content:not(.hide-header) .components-modal__header{ border-bottom-color:#ddd; } .components-modal__header+p{ margin-top:0; } .components-modal__header-heading-container{ align-items:center; display:flex; flex-direction:row; flex-grow:1; justify-content:right; } .components-modal__header-icon-container{ display:inline-block; } .components-modal__header-icon-container svg{ max-height:36px; max-width:36px; padding:8px; } .components-modal__content{ flex:1; margin-top:72px; overflow:auto; padding:4px 32px 32px; } .components-modal__content.hide-header{ margin-top:0; padding-top:32px; } .components-modal__content.is-scrollable:focus-visible{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:-2px; } .components-notice{ align-items:center; background-color:#fff; border-right:4px solid var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#1e1e1e; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; padding:8px 12px; } .components-notice.is-dismissible{ position:relative; } .components-notice.is-success{ background-color:#eff9f1; border-right-color:#4ab866; } .components-notice.is-warning{ background-color:#fef8ee; border-right-color:#f0b849; } .components-notice.is-error{ background-color:#f4a2a2; border-right-color:#cc1818; } .components-notice__content{ flex-grow:1; margin:4px 0 4px 25px; } .components-notice__actions{ display:flex; flex-wrap:wrap; } .components-notice__action.components-button{ margin-left:8px; } .components-notice__action.components-button,.components-notice__action.components-button.is-link{ margin-right:12px; } .components-notice__action.components-button.is-secondary{ vertical-align:initial; } .components-notice__dismiss{ align-self:flex-start; color:#757575; flex-shrink:0; } .components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{ background-color:initial; color:#1e1e1e; } .components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{ box-shadow:none; } .components-notice-list{ box-sizing:border-box; max-width:100vw; } .components-notice-list .components-notice__content{ line-height:2; margin-bottom:12px; margin-top:12px; } .components-notice-list .components-notice__action.components-button{ display:block; margin-right:0; margin-top:8px; } .components-panel{ background:#fff; border:1px solid #e0e0e0; } .components-panel>.components-panel__body:first-child,.components-panel>.components-panel__header:first-child{ margin-top:-1px; } .components-panel>.components-panel__body:last-child,.components-panel>.components-panel__header:last-child{ border-bottom-width:0; } .components-panel+.components-panel{ margin-top:-1px; } .components-panel__body{ border-bottom:1px solid #e0e0e0; border-top:1px solid #e0e0e0; } .components-panel__body h3{ margin:0 0 .5em; } .components-panel__body.is-opened{ padding:16px; } .components-panel__header{ align-items:center; border-bottom:1px solid #ddd; box-sizing:initial; display:flex; flex-shrink:0; height:47px; justify-content:space-between; padding:0 16px; } .components-panel__header h2{ color:inherit; font-size:inherit; margin:0; } .components-panel__body+.components-panel__body,.components-panel__body+.components-panel__header,.components-panel__header+.components-panel__body,.components-panel__header+.components-panel__header{ margin-top:-1px; } .components-panel__body>.components-panel__body-title{ display:block; font-size:inherit; margin-bottom:0; margin-top:0; padding:0; } @media not (prefers-reduced-motion){ .components-panel__body>.components-panel__body-title{ transition:background .1s ease-in-out; } } .components-panel__body.is-opened>.components-panel__body-title{ margin:-16px -16px 5px; } .components-panel__body>.components-panel__body-title:hover{ background:#f0f0f0; border:none; } .components-panel__body-toggle.components-button{ border:none; box-shadow:none; color:#1e1e1e; font-weight:500; height:auto; outline:none; padding:16px 16px 16px 48px; position:relative; text-align:right; width:100%; } @media not (prefers-reduced-motion){ .components-panel__body-toggle.components-button{ transition:background .1s ease-in-out; } } .components-panel__body-toggle.components-button:focus{ border-radius:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-panel__body-toggle.components-button .components-panel__arrow{ color:#1e1e1e; left:16px; position:absolute; top:50%; transform:translateY(-50%); fill:currentColor; } @media not (prefers-reduced-motion){ .components-panel__body-toggle.components-button .components-panel__arrow{ transition:color .1s ease-in-out; } } body.rtl .components-panel__body-toggle.components-button .dashicons-arrow-right{ -ms-filter:fliph; filter:FlipH; margin-top:-10px; transform:scaleX(-1); } .components-panel__icon{ color:#757575; margin:-2px 6px -2px 0; } .components-panel__body-toggle-icon{ margin-left:-5px; } .components-panel__color-title{ float:right; height:19px; } .components-panel__row{ align-items:center; display:flex; justify-content:space-between; margin-top:8px; min-height:36px; } .components-panel__row select{ min-width:0; } .components-panel__row label{ flex-shrink:0; margin-left:12px; max-width:75%; } .components-panel__row:empty,.components-panel__row:first-of-type{ margin-top:0; } .components-panel .circle-picker{ padding-bottom:20px; } .components-placeholder.components-placeholder{ align-items:flex-start; box-sizing:border-box; color:#1e1e1e; display:flex; flex-direction:column; font-size:13px; gap:16px; margin:0; padding:24px; position:relative; text-align:right; width:100%; -moz-font-smoothing:subpixel-antialiased; -webkit-font-smoothing:subpixel-antialiased; background-color:#fff; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; outline:1px solid #0000; } .components-placeholder__error,.components-placeholder__fieldset,.components-placeholder__instructions,.components-placeholder__label{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:400; letter-spacing:normal; line-height:normal; text-transform:none; } .components-placeholder__label{ align-items:center; display:flex; font-weight:600; } .components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{ margin-left:4px; fill:currentColor; } @media (forced-colors:active){ .components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{ fill:CanvasText; } } .components-placeholder__label:empty{ display:none; } .components-placeholder__fieldset,.components-placeholder__fieldset form{ display:flex; flex-direction:row; flex-wrap:wrap; gap:16px; justify-content:flex-start; width:100%; } .components-placeholder__fieldset form p,.components-placeholder__fieldset p{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .components-placeholder__fieldset.is-column-layout,.components-placeholder__fieldset.is-column-layout form{ flex-direction:column; } .components-placeholder__input[type=url]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; flex:1 1 auto; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:6px 8px; } @media not (prefers-reduced-motion){ .components-placeholder__input[type=url]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-placeholder__input[type=url]{ font-size:13px; line-height:normal; } } .components-placeholder__input[type=url]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-placeholder__input[type=url]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-placeholder__input[type=url]::-moz-placeholder{ color:#1e1e1e9e; } .components-placeholder__input[type=url]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-placeholder__error{ gap:8px; width:100%; } .components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link{ margin-left:10px; margin-right:10px; } .components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link:last-child{ margin-left:0; } .components-placeholder.is-medium .components-placeholder__instructions,.components-placeholder.is-small .components-placeholder__instructions{ display:none; } .components-placeholder.is-medium .components-placeholder__fieldset,.components-placeholder.is-medium .components-placeholder__fieldset form,.components-placeholder.is-small .components-placeholder__fieldset,.components-placeholder.is-small .components-placeholder__fieldset form{ flex-direction:column; } .components-placeholder.is-medium .components-button,.components-placeholder.is-medium .components-placeholder__fieldset>*,.components-placeholder.is-small .components-button,.components-placeholder.is-small .components-placeholder__fieldset>*{ justify-content:center; width:100%; } .components-placeholder.is-small{ padding:16px; } .components-placeholder.has-illustration{ -webkit-backdrop-filter:blur(100px); backdrop-filter:blur(100px); backface-visibility:hidden; background-color:initial; border-radius:0; box-shadow:none; color:inherit; display:flex; overflow:hidden; } .is-dark-theme .components-placeholder.has-illustration{ background-color:#0000001a; } .components-placeholder.has-illustration .components-placeholder__fieldset{ margin-left:0; margin-right:0; } .components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{ opacity:0; pointer-events:none; } @media not (prefers-reduced-motion){ .components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{ transition:opacity .1s linear; } } .is-selected>.components-placeholder.has-illustration .components-button,.is-selected>.components-placeholder.has-illustration .components-placeholder__instructions,.is-selected>.components-placeholder.has-illustration .components-placeholder__label{ opacity:1; pointer-events:auto; } .components-placeholder.has-illustration:before{ background:currentColor; bottom:0; content:""; left:0; opacity:.1; pointer-events:none; position:absolute; right:0; top:0; } .is-selected .components-placeholder.has-illustration{ overflow:auto; } .components-placeholder__preview{ display:flex; justify-content:center; } .components-placeholder__illustration{ box-sizing:initial; height:100%; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); width:100%; stroke:currentColor; opacity:.25; } .components-popover{ box-sizing:border-box; will-change:transform; z-index:1000000; } .components-popover *,.components-popover :after,.components-popover :before{ box-sizing:inherit; } .components-popover.is-expanded{ bottom:0; left:0; position:fixed; right:0; top:0; z-index:1000000 !important; } .components-popover__content{ background:#fff; border-radius:4px; box-shadow:0 0 0 1px #ccc,0 2px 3px #0000000d,0 4px 5px #0000000a,0 12px 12px #00000008,0 16px 16px #00000005; box-sizing:border-box; width:min-content; } .is-alternate .components-popover__content{ border-radius:2px; box-shadow:0 0 0 1px #1e1e1e; } .is-unstyled .components-popover__content{ background:none; border-radius:0; box-shadow:none; } .components-popover.is-expanded .components-popover__content{ box-shadow:0 -1px 0 0 #ccc; height:calc(100% - 48px); overflow-y:visible; position:static; width:auto; } .components-popover.is-expanded.is-alternate .components-popover__content{ box-shadow:0 -1px 0 #1e1e1e; } .components-popover__header{ align-items:center; background:#fff; display:flex; height:48px; justify-content:space-between; padding:0 16px 0 8px; } .components-popover__header-title{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:100%; } .components-popover__close.components-button{ z-index:5; } .components-popover__arrow{ display:flex; height:14px; pointer-events:none; position:absolute; width:14px; } .components-popover__arrow:before{ background-color:#fff; content:""; height:2px; left:1px; position:absolute; right:1px; top:-1px; } .components-popover__arrow.is-top{ bottom:-14px !important; transform:rotate(0); } .components-popover__arrow.is-right{ left:-14px !important; transform:rotate(90deg); } .components-popover__arrow.is-bottom{ top:-14px !important; transform:rotate(180deg); } .components-popover__arrow.is-left{ right:-14px !important; transform:rotate(-90deg); } .components-popover__triangle{ display:block; flex:1; } .components-popover__triangle-bg{ fill:#fff; } .components-popover__triangle-border{ fill:#0000; stroke-width:1px; stroke:#ccc; } .is-alternate .components-popover__triangle-border{ stroke:#1e1e1e; } .components-radio-control{ border:0; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; margin:0; padding:0; } .components-radio-control__group-wrapper.has-help{ margin-block-end:12px; } .components-radio-control__option{ align-items:center; column-gap:8px; display:grid; grid-template-columns:auto 1fr; grid-template-rows:auto minmax(0, max-content); } .components-radio-control__input[type=radio]{ appearance:none; border:1px solid #1e1e1e; border-radius:2px; border-radius:50%; box-shadow:0 0 0 #0000; cursor:pointer; display:inline-flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; grid-column:1; grid-row:1; height:24px; line-height:normal; margin:0; max-width:24px; min-width:24px; padding:0; position:relative; transition:none; width:24px; } @media not (prefers-reduced-motion){ .components-radio-control__input[type=radio]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-radio-control__input[type=radio]{ font-size:13px; line-height:normal; } } .components-radio-control__input[type=radio]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .components-radio-control__input[type=radio]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-radio-control__input[type=radio]::-moz-placeholder{ color:#1e1e1e9e; } .components-radio-control__input[type=radio]:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .components-radio-control__input[type=radio]{ height:16px; max-width:16px; min-width:16px; width:16px; } } .components-radio-control__input[type=radio]:checked:before{ background-color:#fff; border:4px solid #fff; box-sizing:inherit; height:12px; margin:0; position:absolute; right:50%; top:50%; transform:translate(50%, -50%); width:12px; } @media (min-width:600px){ .components-radio-control__input[type=radio]:checked:before{ height:8px; width:8px; } } .components-radio-control__input[type=radio]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); } .components-radio-control__input[type=radio]:checked{ background:var(--wp-admin-theme-color); border:none; } .components-radio-control__input[type=radio]:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .components-radio-control__input[type=radio]:checked{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-radio-control__input[type=radio]:checked:before{ border-radius:50%; content:""; } .components-radio-control__label{ cursor:pointer; grid-column:2; grid-row:1; line-height:24px; } @media (min-width:600px){ .components-radio-control__label{ line-height:16px; } } .components-radio-control__option-description{ grid-column:2; grid-row:2; padding-block-start:4px; } .components-radio-control__option-description.components-radio-control__option-description{ margin-top:0; } .components-resizable-box__handle{ display:none; height:23px; width:23px; z-index:2; } .components-resizable-box__container.has-show-handle .components-resizable-box__handle{ display:block; } .components-resizable-box__handle>div{ height:100%; outline:none; position:relative; width:100%; z-index:2; } .components-resizable-box__container>img{ width:inherit; } .components-resizable-box__handle:after{ background:#fff; border-radius:50%; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)), 0 1px 1px #00000008, 0 1px 2px #00000005, 0 3px 3px #00000005, 0 4px 4px #00000003; content:""; cursor:inherit; display:block; height:15px; left:calc(50% - 8px); outline:2px solid #0000; position:absolute; top:calc(50% - 8px); width:15px; } .components-resizable-box__side-handle:before{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-radius:9999px; content:""; cursor:inherit; display:block; height:3px; left:calc(50% - 1px); opacity:0; position:absolute; top:calc(50% - 1px); width:3px; } @media not (prefers-reduced-motion){ .components-resizable-box__side-handle:before{ transition:transform .1s ease-in; will-change:transform; } } .components-resizable-box__corner-handle,.components-resizable-box__side-handle{ z-index:2; } .components-resizable-box__side-handle.components-resizable-box__handle-bottom,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:before,.components-resizable-box__side-handle.components-resizable-box__handle-top,.components-resizable-box__side-handle.components-resizable-box__handle-top:before{ border-left:0; border-right:0; right:0; width:100%; } .components-resizable-box__side-handle.components-resizable-box__handle-left,.components-resizable-box__side-handle.components-resizable-box__handle-left:before,.components-resizable-box__side-handle.components-resizable-box__handle-right,.components-resizable-box__side-handle.components-resizable-box__handle-right:before{ border-bottom:0; border-top:0; height:100%; top:0; } @media not (prefers-reduced-motion){ .components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{ animation:components-resizable-box__top-bottom-animation .1s ease-out 0s; animation-fill-mode:forwards; } .components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before{ animation:components-resizable-box__left-right-animation .1s ease-out 0s; animation-fill-mode:forwards; } } @media not all and (min-resolution:0.001dpcm){ @supports (-webkit-appearance:none){ .components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{ animation:none; } } } @keyframes components-resizable-box__top-bottom-animation{ 0%{ opacity:0; transform:scaleX(0); } to{ opacity:1; transform:scaleX(1); } } @keyframes components-resizable-box__left-right-animation{ 0%{ opacity:0; transform:scaleY(0); } to{ opacity:1; transform:scaleY(1); } } .components-resizable-box__handle-right{ right:-11.5px; } .components-resizable-box__handle-left{ left:-11.5px; } .components-resizable-box__handle-top{ top:-11.5px; } .components-resizable-box__handle-bottom{ bottom:-11.5px; } .components-responsive-wrapper{ align-items:center; display:flex; justify-content:center; max-width:100%; position:relative; } .components-responsive-wrapper__content{ display:block; max-width:100%; width:100%; } .components-sandbox{ overflow:hidden; } iframe.components-sandbox{ width:100%; } body.lockscroll,html.lockscroll{ overflow:hidden; } .components-select-control__input{ outline:0; -webkit-tap-highlight-color:rgba(0, 0, 0, 0) !important; } @media (max-width:782px){ .components-base-control .components-base-control__field .components-select-control__input{ font-size:16px; } } .components-snackbar{ -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background:#000000d9; border-radius:4px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; box-sizing:border-box; color:#fff; cursor:pointer; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; max-width:600px; padding:12px 20px; pointer-events:auto; width:100%; } @media (min-width:600px){ .components-snackbar{ width:fit-content; } } .components-snackbar:focus{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-snackbar.components-snackbar-explicit-dismiss{ cursor:default; } .components-snackbar .components-snackbar__content-with-icon{ padding-right:24px; position:relative; } .components-snackbar .components-snackbar__icon{ position:absolute; right:-8px; top:-2.9px; } .components-snackbar .components-snackbar__dismiss-button{ cursor:pointer; margin-right:24px; } .components-snackbar__action.components-button{ color:#fff; flex-shrink:0; margin-right:32px; } .components-snackbar__action.components-button:focus{ box-shadow:none; outline:1px dotted #fff; } .components-snackbar__action.components-button:hover{ color:currentColor; text-decoration:none; } .components-snackbar__content{ align-items:baseline; display:flex; justify-content:space-between; line-height:1.4; } .components-snackbar-list{ box-sizing:border-box; pointer-events:none; position:absolute; width:100%; z-index:100000; } .components-snackbar-list__notice-container{ padding-top:8px; position:relative; } .components-tab-panel__tabs{ align-items:stretch; display:flex; flex-direction:row; } .components-tab-panel__tabs[aria-orientation=vertical]{ flex-direction:column; } .components-tab-panel__tabs-item{ background:#0000; border:none; border-radius:0; box-shadow:none; cursor:pointer; font-weight:500; height:48px !important; margin-right:0; padding:3px 16px; position:relative; } .components-tab-panel__tabs-item:focus:not(:disabled){ box-shadow:none; outline:none; position:relative; } .components-tab-panel__tabs-item:after{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-radius:0; bottom:0; content:""; height:calc(var(--wp-admin-border-width-focus)*0); left:0; pointer-events:none; position:absolute; right:0; } @media not (prefers-reduced-motion){ .components-tab-panel__tabs-item:after{ transition:all .1s linear; } } .components-tab-panel__tabs-item.is-active:after{ height:calc(var(--wp-admin-border-width-focus)*1); outline:2px solid #0000; outline-offset:-1px; } .components-tab-panel__tabs-item:before{ border-radius:2px; bottom:12px; box-shadow:0 0 0 0 #0000; content:""; left:12px; pointer-events:none; position:absolute; right:12px; top:12px; } @media not (prefers-reduced-motion){ .components-tab-panel__tabs-item:before{ transition:all .1s linear; } } .components-tab-panel__tabs-item:focus-visible:before{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; } .components-tab-panel__tab-content:focus{ box-shadow:none; outline:none; } .components-tab-panel__tab-content:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:0; } .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin:0; padding:6px 8px; width:100%; } @media not (prefers-reduced-motion){ .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ font-size:13px; line-height:normal; } } .components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{ color:#1e1e1e9e; } .components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-text-control__input.is-next-40px-default-size,.components-text-control__input[type=color].is-next-40px-default-size,.components-text-control__input[type=date].is-next-40px-default-size,.components-text-control__input[type=datetime-local].is-next-40px-default-size,.components-text-control__input[type=datetime].is-next-40px-default-size,.components-text-control__input[type=email].is-next-40px-default-size,.components-text-control__input[type=month].is-next-40px-default-size,.components-text-control__input[type=number].is-next-40px-default-size,.components-text-control__input[type=password].is-next-40px-default-size,.components-text-control__input[type=tel].is-next-40px-default-size,.components-text-control__input[type=text].is-next-40px-default-size,.components-text-control__input[type=time].is-next-40px-default-size,.components-text-control__input[type=url].is-next-40px-default-size,.components-text-control__input[type=week].is-next-40px-default-size{ height:40px; padding-left:12px; padding-right:12px; } .components-text-control__input[type=email],.components-text-control__input[type=url]{ direction:ltr; } .components-tip{ color:#757575; display:flex; } .components-tip svg{ align-self:center; fill:#f0b849; flex-shrink:0; margin-left:16px; } .components-tip p{ margin:0; } .components-toggle-control__label{ line-height:16px; } .components-toggle-control__label:not(.is-disabled){ cursor:pointer; } .components-toggle-control__help{ display:inline-block; margin-inline-start:40px; } .components-accessible-toolbar{ border:1px solid #1e1e1e; border-radius:2px; display:inline-flex; flex-shrink:0; } .components-accessible-toolbar>.components-toolbar-group:last-child{ border-left:none; } .components-accessible-toolbar.is-unstyled{ border:none; } .components-accessible-toolbar.is-unstyled>.components-toolbar-group{ border-left:none; } .components-accessible-toolbar[aria-orientation=vertical],.components-toolbar[aria-orientation=vertical]{ align-items:center; display:flex; flex-direction:column; } .components-accessible-toolbar .components-button,.components-toolbar .components-button{ height:48px; padding-left:16px; padding-right:16px; position:relative; z-index:1; } .components-accessible-toolbar .components-button:focus:not(:disabled),.components-toolbar .components-button:focus:not(:disabled){ box-shadow:none; outline:none; } .components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .components-accessible-toolbar .components-button svg,.components-toolbar .components-button svg{ margin-left:auto; margin-right:auto; position:relative; } .components-accessible-toolbar .components-button.is-pressed,.components-accessible-toolbar .components-button.is-pressed:hover,.components-toolbar .components-button.is-pressed,.components-toolbar .components-button.is-pressed:hover{ background:#0000; } .components-accessible-toolbar .components-button.is-pressed:before,.components-toolbar .components-button.is-pressed:before{ background:#1e1e1e; } .components-accessible-toolbar .components-button:focus:before,.components-toolbar .components-button:focus:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .components-accessible-toolbar .components-button.has-icon.has-icon,.components-toolbar .components-button.has-icon.has-icon{ min-width:48px; padding-left:8px; padding-right:8px; } @keyframes components-button__appear-animation{ 0%{ transform:scaleY(0); } to{ transform:scaleY(1); } } .components-toolbar__control.components-button{ position:relative; } .components-toolbar__control.components-button[data-subscript] svg{ padding:5px 0 5px 10px; } .components-toolbar__control.components-button[data-subscript]:after{ bottom:10px; content:attr(data-subscript); font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; left:8px; line-height:12px; position:absolute; } .components-toolbar__control.components-button:not(:disabled).is-pressed[data-subscript]:after{ color:#fff; } .components-toolbar-group{ background-color:#fff; border-left:1px solid #1e1e1e; display:inline-flex; flex-shrink:0; flex-wrap:wrap; line-height:0; min-height:48px; padding-left:6px; padding-right:6px; } .components-toolbar-group .components-toolbar-group.components-toolbar-group{ border-width:0; margin:0; } .components-toolbar-group .components-button.components-button,.components-toolbar-group .components-button.has-icon.has-icon{ justify-content:center; min-width:36px; padding-left:6px; padding-right:6px; } .components-toolbar-group .components-button.components-button svg,.components-toolbar-group .components-button.has-icon.has-icon svg{ min-width:24px; } .components-toolbar-group .components-button.components-button:before,.components-toolbar-group .components-button.has-icon.has-icon:before{ left:2px; right:2px; } .components-toolbar{ background-color:#fff; border:1px solid #1e1e1e; display:inline-flex; flex-shrink:0; flex-wrap:wrap; margin:0; min-height:48px; } .components-toolbar .components-toolbar.components-toolbar{ border-width:0; margin:0; } div.components-toolbar>div{ display:flex; margin:0; } div.components-toolbar>div+div.has-left-divider{ margin-right:6px; overflow:visible; position:relative; } div.components-toolbar>div+div.has-left-divider:before{ background-color:#ddd; box-sizing:initial; content:""; display:inline-block; height:20px; position:absolute; right:-3px; top:8px; width:1px; } .components-tooltip{ background:#000; border-radius:2px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; color:#f0f0f0; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:12px; line-height:1.4; padding:4px 8px; text-align:center; z-index:1000002; } .components-tooltip__shortcut{ margin-right:8px; }@charset "UTF-8"; :root{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } @media not (prefers-reduced-motion){ .components-animate__appear{ animation:components-animate__appear-animation .1s cubic-bezier(0, 0, .2, 1) 0s; animation-fill-mode:forwards; } } .components-animate__appear.is-from-top,.components-animate__appear.is-from-top.is-from-left{ transform-origin:top left; } .components-animate__appear.is-from-top.is-from-right{ transform-origin:top right; } .components-animate__appear.is-from-bottom,.components-animate__appear.is-from-bottom.is-from-left{ transform-origin:bottom left; } .components-animate__appear.is-from-bottom.is-from-right{ transform-origin:bottom right; } @keyframes components-animate__appear-animation{ 0%{ transform:translateY(-2em) scaleY(0) scaleX(0); } to{ transform:translateY(0) scaleY(1) scaleX(1); } } @media not (prefers-reduced-motion){ .components-animate__slide-in{ animation:components-animate__slide-in-animation .1s cubic-bezier(0, 0, .2, 1); animation-fill-mode:forwards; } .components-animate__slide-in.is-from-left{ transform:translateX(100%); } .components-animate__slide-in.is-from-right{ transform:translateX(-100%); } } @keyframes components-animate__slide-in-animation{ to{ transform:translateX(0); } } @media not (prefers-reduced-motion){ .components-animate__loading{ animation:components-animate__loading 1.6s ease-in-out infinite; } } @keyframes components-animate__loading{ 0%{ opacity:.5; } 50%{ opacity:1; } to{ opacity:.5; } } .components-autocomplete__popover .components-popover__content{ min-width:200px; padding:8px; } .components-autocomplete__result.components-button{ display:flex; height:auto; min-height:36px; text-align:left; width:100%; } .components-autocomplete__result.components-button:focus:not(:disabled){ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .components-badge{ align-items:center; background-color:color-mix(in srgb, #fff 90%, var(--base-color)); border-radius:2px; box-sizing:border-box; color:color-mix(in srgb, #000 50%, var(--base-color)); display:inline-flex; font-size:12px; font-weight:400; gap:2px; line-height:20px; max-width:100%; min-height:24px; padding:0 8px; } .components-badge *,.components-badge :after,.components-badge :before{ box-sizing:inherit; } .components-badge:where(.is-default){ background-color:#f0f0f0; color:#2f2f2f; } .components-badge.has-icon{ padding-inline-start:4px; } .components-badge.is-info{ --base-color:#3858e9; } .components-badge.is-warning{ --base-color:#f0b849; } .components-badge.is-error{ --base-color:#cc1818; } .components-badge.is-success{ --base-color:#4ab866; } .components-badge__icon{ flex-shrink:0; } .components-badge__content{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .components-button-group{ display:inline-block; } .components-button-group .components-button{ border-radius:0; box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; display:inline-flex; } .components-button-group .components-button+.components-button{ margin-left:-1px; } .components-button-group .components-button:first-child{ border-radius:2px 0 0 2px; } .components-button-group .components-button:last-child{ border-radius:0 2px 2px 0; } .components-button-group .components-button.is-primary,.components-button-group .components-button:focus{ position:relative; z-index:1; } .components-button-group .components-button.is-primary{ box-shadow:inset 0 0 0 1px #1e1e1e; } .components-button{ align-items:center; -webkit-appearance:none; background:none; border:0; border-radius:2px; box-sizing:border-box; color:var(--wp-components-color-foreground, #1e1e1e); cursor:pointer; display:inline-flex; font-family:inherit; font-size:13px; height:36px; margin:0; padding:6px 12px; text-decoration:none; } @media not (prefers-reduced-motion){ .components-button{ transition:box-shadow .1s linear; } } .components-button.is-next-40px-default-size{ height:40px; } .components-button:hover:not(:disabled,[aria-disabled=true]),.components-button[aria-expanded=true]{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button:focus:not(:disabled){ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:3px solid #0000; } .components-button.is-primary{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:var(--wp-components-color-accent-inverted, #fff); outline:1px solid #0000; text-decoration:none; text-shadow:none; white-space:nowrap; } .components-button.is-primary:hover:not(:disabled){ background:var(--wp-components-color-accent-darker-10, var(--wp-admin-theme-color-darker-10, #2145e6)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-primary:active:not(:disabled){ background:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); border-color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-primary:focus:not(:disabled){ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-primary:disabled,.components-button.is-primary:disabled:active:enabled,.components-button.is-primary[aria-disabled=true],.components-button.is-primary[aria-disabled=true]:active:enabled,.components-button.is-primary[aria-disabled=true]:enabled{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#fff6; outline:none; } .components-button.is-primary:disabled:active:enabled:focus:enabled,.components-button.is-primary:disabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:active:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:enabled:focus:enabled,.components-button.is-primary[aria-disabled=true]:focus:enabled{ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-primary.is-busy,.components-button.is-primary.is-busy:disabled,.components-button.is-primary.is-busy[aria-disabled=true]{ background-image:linear-gradient(-45deg, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 33%, var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)) 33%, var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)) 70%, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 70%); background-size:100px 100%; border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:var(--wp-components-color-accent-inverted, #fff); } .components-button.is-secondary,.components-button.is-tertiary{ outline:1px solid #0000; } .components-button.is-secondary:active:not(:disabled),.components-button.is-tertiary:active:not(:disabled){ box-shadow:none; } .components-button.is-secondary:disabled,.components-button.is-secondary[aria-disabled=true],.components-button.is-secondary[aria-disabled=true]:hover,.components-button.is-tertiary:disabled,.components-button.is-tertiary[aria-disabled=true],.components-button.is-tertiary[aria-disabled=true]:hover{ background:#0000; color:#949494; transform:none; } .components-button.is-secondary{ background:#0000; box-shadow:inset 0 0 0 1px var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)), 0 0 0 currentColor; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:1px solid #0000; white-space:nowrap; } .components-button.is-secondary:hover:not(:disabled,[aria-disabled=true],.is-pressed){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 4%, #0000); box-shadow:inset 0 0 0 1px var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); } .components-button.is-secondary:disabled:not(:focus),.components-button.is-secondary[aria-disabled=true]:hover:not(:focus),.components-button.is-secondary[aria-disabled=true]:not(:focus){ box-shadow:inset 0 0 0 1px #ddd; } .components-button.is-secondary:focus:not(:disabled){ box-shadow:0 0 0 currentColor inset, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-button.is-tertiary{ background:#0000; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); white-space:nowrap; } .components-button.is-tertiary:hover:not(:disabled,[aria-disabled=true],.is-pressed){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 4%, #0000); color:var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6)); } .components-button.is-tertiary:active:not(:disabled,[aria-disabled=true]){ background:color-mix(in srgb, var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)) 8%, #0000); } p+.components-button.is-tertiary{ margin-left:-6px; } .components-button.is-tertiary:disabled:not(:focus),.components-button.is-tertiary[aria-disabled=true]:hover:not(:focus),.components-button.is-tertiary[aria-disabled=true]:not(:focus){ box-shadow:none; outline:none; } .components-button.is-destructive{ --wp-components-color-accent:#cc1818; --wp-components-color-accent-darker-10:#9e1313; --wp-components-color-accent-darker-20:#710d0d; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link){ color:#cc1818; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):hover:not(:disabled,[aria-disabled=true]){ color:#710d0d; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #cc1818; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):active:not(:disabled,[aria-disabled=true]){ background:#ccc; } .components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link):disabled,.components-button.is-destructive:not(.is-primary):not(.is-secondary):not(.is-tertiary):not(.is-link)[aria-disabled=true]{ color:#949494; } .components-button.is-destructive.is-secondary:hover:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:hover:not(:disabled,[aria-disabled=true]){ background:#cc18180a; } .components-button.is-destructive.is-secondary:active:not(:disabled,[aria-disabled=true]),.components-button.is-destructive.is-tertiary:active:not(:disabled,[aria-disabled=true]){ background:#cc181814; } .components-button.is-link{ background:none; border:0; border-radius:0; box-shadow:none; color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); height:auto; margin:0; outline:none; padding:0; text-align:left; text-decoration:underline; } @media not (prefers-reduced-motion){ .components-button.is-link{ transition-duration:.05s; transition-property:border, background, color; transition-timing-function:ease-in-out; } } .components-button.is-link:focus{ border-radius:2px; } .components-button.is-link:disabled,.components-button.is-link[aria-disabled=true]{ color:#949494; } .components-button:not(:disabled,[aria-disabled=true]):active{ color:var(--wp-components-color-foreground, #1e1e1e); } .components-button:disabled,.components-button[aria-disabled=true]{ color:#949494; cursor:default; } .components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{ background-image:linear-gradient(-45deg, #fafafa 33%, #e0e0e0 0, #e0e0e0 70%, #fafafa 0); background-size:100px 100%; } @media not (prefers-reduced-motion){ .components-button.is-busy,.components-button.is-secondary.is-busy,.components-button.is-secondary.is-busy:disabled,.components-button.is-secondary.is-busy[aria-disabled=true]{ animation:components-button__busy-animation 2.5s linear infinite; } } .components-button.is-compact{ height:32px; } .components-button.is-compact.has-icon:not(.has-text){ min-width:32px; padding:0; width:32px; } .components-button.is-small{ font-size:11px; height:24px; line-height:22px; padding:0 8px; } .components-button.is-small.has-icon:not(.has-text){ min-width:24px; padding:0; width:24px; } .components-button.has-icon{ justify-content:center; min-width:36px; padding:6px; } .components-button.has-icon.is-next-40px-default-size{ min-width:40px; } .components-button.has-icon .dashicon{ align-items:center; box-sizing:initial; display:inline-flex; justify-content:center; padding:2px; } .components-button.has-icon.has-text{ gap:4px; justify-content:start; padding-left:8px; padding-right:12px; } .components-button.is-pressed,.components-button.is-pressed:hover{ color:var(--wp-components-color-foreground-inverted, #fff); } .components-button.is-pressed:hover:not(:disabled,[aria-disabled=true]),.components-button.is-pressed:not(:disabled,[aria-disabled=true]){ background:var(--wp-components-color-foreground, #1e1e1e); } .components-button.is-pressed:disabled,.components-button.is-pressed[aria-disabled=true]{ color:#949494; } .components-button.is-pressed:disabled:not(.is-primary):not(.is-secondary):not(.is-tertiary),.components-button.is-pressed[aria-disabled=true]:not(.is-primary):not(.is-secondary):not(.is-tertiary){ background:#949494; color:var(--wp-components-color-foreground-inverted, #fff); } .components-button.is-pressed:focus:not(:disabled){ box-shadow:inset 0 0 0 1px var(--wp-components-color-background, #fff), 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; } .components-button svg{ fill:currentColor; outline:none; } @media (forced-colors:active){ .components-button svg{ fill:CanvasText; } } .components-button .components-visually-hidden{ height:auto; } @keyframes components-button__busy-animation{ 0%{ background-position:200px 0; } } .components-checkbox-control{ --checkbox-input-size:24px; --checkbox-input-margin:8px; } @media (min-width:600px){ .components-checkbox-control{ --checkbox-input-size:16px; } } .components-checkbox-control__label{ cursor:pointer; line-height:var(--checkbox-input-size); } .components-checkbox-control__input[type=checkbox]{ appearance:none; background:#fff; border:1px solid #1e1e1e; border-radius:2px; box-shadow:0 0 0 #0000; clear:none; color:#1e1e1e; cursor:pointer; display:inline-block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:var(--checkbox-input-size); line-height:normal; line-height:0; margin:0 4px 0 0; outline:0; padding:6px 8px; padding:0 !important; text-align:center; transition:none; vertical-align:top; width:var(--checkbox-input-size); } @media not (prefers-reduced-motion){ .components-checkbox-control__input[type=checkbox]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-checkbox-control__input[type=checkbox]{ font-size:13px; line-height:normal; } } .components-checkbox-control__input[type=checkbox]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]::-moz-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-checkbox-control__input[type=checkbox]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]:checked{ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox]:checked::-ms-check{ opacity:0; } .components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ color:#fff; margin:-3px -5px; } @media (min-width:782px){ .components-checkbox-control__input[type=checkbox]:checked:before,.components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ margin:-4px 0 0 -5px; } } .components-checkbox-control__input[type=checkbox][aria-checked=mixed]{ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); } .components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ content:"\f460"; display:inline-block; float:left; font:normal 30px/1 dashicons; vertical-align:middle; width:16px; speak:none; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; } @media (min-width:782px){ .components-checkbox-control__input[type=checkbox][aria-checked=mixed]:before{ float:none; font-size:21px; } } .components-checkbox-control__input[type=checkbox]:disabled,.components-checkbox-control__input[type=checkbox][aria-disabled=true]{ background:#f0f0f0; border-color:#ddd; cursor:default; opacity:1; } @media not (prefers-reduced-motion){ .components-checkbox-control__input[type=checkbox]{ transition:border-color .1s ease-in-out; } } .components-checkbox-control__input[type=checkbox]:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .components-checkbox-control__input[type=checkbox]:checked,.components-checkbox-control__input[type=checkbox]:indeterminate{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-checkbox-control__input[type=checkbox]:checked::-ms-check,.components-checkbox-control__input[type=checkbox]:indeterminate::-ms-check{ opacity:0; } .components-checkbox-control__input[type=checkbox]:checked:before{ content:none; } .components-checkbox-control__input-container{ aspect-ratio:1; display:inline-block; flex-shrink:0; line-height:1; margin-right:var(--checkbox-input-margin); position:relative; vertical-align:middle; width:var(--checkbox-input-size); } svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{ --checkmark-size:var(--checkbox-input-size); fill:#fff; cursor:pointer; height:var(--checkmark-size); left:50%; pointer-events:none; position:absolute; top:50%; transform:translate(-50%, -50%); -webkit-user-select:none; user-select:none; width:var(--checkmark-size); } @media (min-width:600px){ svg.components-checkbox-control__checked,svg.components-checkbox-control__indeterminate{ --checkmark-size:calc(var(--checkbox-input-size) + 4px); } } .components-checkbox-control__help{ display:inline-block; margin-inline-start:calc(var(--checkbox-input-size) + var(--checkbox-input-margin)); } .components-circular-option-picker{ display:inline-block; min-width:188px; width:100%; } .components-circular-option-picker .components-circular-option-picker__custom-clear-wrapper{ display:flex; justify-content:flex-end; margin-top:12px; } .components-circular-option-picker .components-circular-option-picker__swatches{ display:flex; flex-wrap:wrap; gap:12px; position:relative; z-index:1; } .components-circular-option-picker>:not(.components-circular-option-picker__swatches){ position:relative; z-index:0; } .components-circular-option-picker__option-wrapper{ display:inline-block; height:28px; transform:scale(1); vertical-align:top; width:28px; } @media not (prefers-reduced-motion){ .components-circular-option-picker__option-wrapper{ transition:transform .1s ease; will-change:transform; } } .components-circular-option-picker__option-wrapper:hover{ transform:scale(1.2); } .components-circular-option-picker__option-wrapper>div{ height:100%; width:100%; } .components-circular-option-picker__option-wrapper:before{ background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none'%3E%3Cpath fill='%23555D65' d='M6 8V6H4v2zm2 0V6h2v2zm2 8H8v-2h2zm2 0v-2h2v2zm0 2v-2h-2v2H8v2h2v-2zm2 0v2h-2v-2zm2 0h-2v-2h2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M18 18h2v-2h-2v-2h2v-2h-2v-2h2V8h-2v2h-2V8h-2v2h2v2h-2v2h2v2h2zm-2-4v-2h2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' d='M18 18v2h-2v-2z'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M8 10V8H6v2H4v2h2v2H4v2h2v2H4v2h2v2H4v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2v2h-2V4h-2v2h-2V4h-2v2h-2V4h-2v2h2v2h-2v2zm0 2v-2H6v2zm2 0v-2h2v2zm0 2v-2H8v2H6v2h2v2H6v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h-2v2h-2V6h-2v2h-2v2h2v2h-2v2z' clip-rule='evenodd'/%3E%3Cpath fill='%23555D65' fill-rule='evenodd' d='M4 0H2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v2H0v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2h-2V0h-2v2H8V0H6v2H4zm0 4V2H2v2zm2 0V2h2v2zm0 2V4H4v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2H2v2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h2v2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2v-2h-2v-2h2V8h-2V6h2V4h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2h-2V2h-2v2H8v2z' clip-rule='evenodd'/%3E%3C/svg%3E"); border-radius:50%; bottom:1px; content:""; left:1px; position:absolute; right:1px; top:1px; z-index:-1; } .components-circular-option-picker__option{ aspect-ratio:1; background:#0000; border:none; border-radius:50%; box-shadow:inset 0 0 0 14px; cursor:pointer; display:inline-block; height:100% !important; vertical-align:top; } @media not (prefers-reduced-motion){ .components-circular-option-picker__option{ transition:box-shadow .1s ease; } } .components-circular-option-picker__option:hover{ box-shadow:inset 0 0 0 14px !important; } .components-circular-option-picker__option[aria-pressed=true],.components-circular-option-picker__option[aria-selected=true]{ box-shadow:inset 0 0 0 4px; overflow:visible; position:relative; z-index:1; } .components-circular-option-picker__option[aria-pressed=true]+svg,.components-circular-option-picker__option[aria-selected=true]+svg{ border-radius:50%; left:2px; pointer-events:none; position:absolute; top:2px; z-index:2; } .components-circular-option-picker__option:after{ border:1px solid #0000; border-radius:50%; bottom:-1px; box-shadow:inset 0 0 0 1px #0003; box-sizing:inherit; content:""; left:-1px; position:absolute; right:-1px; top:-1px; } .components-circular-option-picker__option:focus:after{ border:2px solid #757575; border-radius:50%; box-shadow:inset 0 0 0 2px #fff; content:""; height:calc(100% + 4px); left:50%; position:absolute; top:50%; transform:translate(-50%, -50%); width:calc(100% + 4px); } .components-circular-option-picker__option.components-button:focus{ background-color:initial; box-shadow:inset 0 0 0 14px; outline:none; } .components-circular-option-picker__button-action .components-circular-option-picker__option{ background:#fff; color:#fff; } .components-circular-option-picker__dropdown-link-action{ margin-right:16px; } .components-circular-option-picker__dropdown-link-action .components-button{ line-height:22px; } .components-palette-edit__popover-gradient-picker{ padding:8px; width:260px; } .components-dropdown-menu__menu .components-palette-edit__menu-button{ width:100%; } .component-color-indicator{ background:#fff linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); border-radius:50%; box-shadow:inset 0 0 0 1px #0003; display:inline-block; height:20px; padding:0; width:20px; } .components-combobox-control{ width:100%; } input.components-combobox-control__input[type=text]{ border:none; box-shadow:none; font-family:inherit; font-size:16px; line-height:inherit; margin:0; min-height:auto; padding:2px; width:100%; } @media (min-width:600px){ input.components-combobox-control__input[type=text]{ font-size:13px; } } input.components-combobox-control__input[type=text]:focus{ box-shadow:none; outline:none; } .components-combobox-control__suggestions-container{ align-items:flex-start; border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; display:flex; flex-wrap:wrap; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:0; width:100%; } @media not (prefers-reduced-motion){ .components-combobox-control__suggestions-container{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-combobox-control__suggestions-container{ font-size:13px; line-height:normal; } } .components-combobox-control__suggestions-container:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-combobox-control__suggestions-container::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container::-moz-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container:-ms-input-placeholder{ color:#1e1e1e9e; } .components-combobox-control__suggestions-container:focus-within{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-combobox-control__suggestions-container .components-spinner{ margin:0; } .components-color-palette__custom-color-wrapper{ position:relative; z-index:0; } .components-color-palette__custom-color-button{ background:none; border:none; border-radius:4px 4px 0 0; box-shadow:inset 0 0 0 1px #0003; box-sizing:border-box; cursor:pointer; height:64px; outline:1px solid #0000; position:relative; width:100%; } .components-color-palette__custom-color-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline-width:2px; } .components-color-palette__custom-color-button:after{ background-image:repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0), repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0); background-position:0 0, 24px 24px; background-size:48px 48px; border-radius:3px 3px 0 0; content:""; inset:1px; position:absolute; z-index:-1; } .components-color-palette__custom-color-text-wrapper{ border-radius:0 0 4px 4px; box-shadow:inset 0 -1px 0 0 #0003,inset 1px 0 0 0 #0003,inset -1px 0 0 0 #0003; font-size:13px; padding:12px 16px; position:relative; } .components-color-palette__custom-color-name{ color:var(--wp-components-color-foreground, #1e1e1e); margin:0 1px; } .components-color-palette__custom-color-value{ color:#757575; } .components-color-palette__custom-color-value--is-hex{ text-transform:uppercase; } .components-color-palette__custom-color-value:empty:after{ content:""; visibility:hidden; } .components-custom-gradient-picker__gradient-bar{ border-radius:2px; height:48px; position:relative; width:100%; z-index:1; } .components-custom-gradient-picker__gradient-bar.has-gradient{ background-image:repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0), repeating-linear-gradient(45deg, #e0e0e0 25%, #0000 0, #0000 75%, #e0e0e0 0, #e0e0e0); background-position:0 0, 12px 12px; background-size:24px 24px; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__gradient-bar-background{ inset:0; position:absolute; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__markers-container{ margin-left:auto; margin-right:auto; position:relative; width:calc(100% - 48px); } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-dropdown{ display:flex; height:16px; position:absolute; top:16px; width:16px; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown{ background:#fff; border-radius:50%; color:#1e1e1e; height:inherit; min-width:16px !important; padding:2px; position:relative; width:inherit; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__insert-point-dropdown svg{ height:100%; width:100%; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button{ border-radius:50%; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 2px 0 #00000040; height:inherit; outline:2px solid #0000; padding:0; width:inherit; } .components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button.is-active,.components-custom-gradient-picker__gradient-bar .components-custom-gradient-picker__control-point-button:focus{ box-shadow:inset 0 0 0 calc(var(--wp-admin-border-width-focus)*2) #fff, 0 0 2px 0 #00000040; outline:1.5px solid #0000; } .components-custom-gradient-picker__remove-control-point-wrapper{ padding-bottom:8px; } .components-custom-gradient-picker__inserter{ direction:ltr; } .components-custom-gradient-picker__liner-gradient-indicator{ display:inline-block; flex:0 auto; height:20px; width:20px; } .components-custom-gradient-picker__ui-line{ position:relative; z-index:0; } .block-editor-dimension-control .components-base-control__field{ align-items:center; display:flex; } .block-editor-dimension-control .components-base-control__label{ align-items:center; display:flex; margin-bottom:0; margin-right:1em; } .block-editor-dimension-control .components-base-control__label .dashicon{ margin-right:.5em; } .block-editor-dimension-control.is-manual .components-base-control__label{ width:10em; } body.is-dragging-components-draggable{ cursor:move; cursor:grabbing !important; } .components-draggable__invisible-drag-image{ height:50px; left:-1000px; position:fixed; width:50px; } .components-draggable__clone{ background:#0000; padding:0; pointer-events:none; position:fixed; z-index:1000000000; } .components-drop-zone{ border-radius:2px; bottom:0; left:0; opacity:0; position:absolute; right:0; top:0; visibility:hidden; z-index:40; } .components-drop-zone.is-active{ opacity:1; visibility:visible; } .components-drop-zone .components-drop-zone__content{ align-items:center; background-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); bottom:0; color:#fff; display:flex; height:100%; justify-content:center; left:0; opacity:0; pointer-events:none; position:absolute; right:0; text-align:center; top:0; width:100%; z-index:50; } .components-drop-zone .components-drop-zone__content-inner{ opacity:0; transform:scale(.9); } .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{ opacity:1; } @media not (prefers-reduced-motion){ .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content{ transition:opacity .2s ease-in-out; } } .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{ opacity:1; transform:scale(1); } @media not (prefers-reduced-motion){ .components-drop-zone.is-active.is-dragging-over-element .components-drop-zone__content-inner{ transition:opacity .1s ease-in-out .1s,transform .1s ease-in-out .1s; } } .components-drop-zone__content-icon,.components-drop-zone__content-text{ display:block; } .components-drop-zone__content-icon{ line-height:0; margin:0 auto 8px; fill:currentColor; pointer-events:none; } .components-drop-zone__content-text{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .components-dropdown{ display:inline-block; } .components-dropdown__content .components-popover__content{ padding:8px; } .components-dropdown__content .components-popover__content:has(.components-menu-group){ padding:0; } .components-dropdown__content .components-popover__content:has(.components-menu-group) .components-dropdown-menu__menu>.components-menu-item__button,.components-dropdown__content .components-popover__content:has(.components-menu-group)>.components-menu-item__button{ margin:8px; width:auto; } .components-dropdown__content [role=menuitem]{ white-space:nowrap; } .components-dropdown__content .components-menu-group{ padding:8px; } .components-dropdown__content .components-menu-group+.components-menu-group{ border-top:1px solid #ccc; padding:8px; } .components-dropdown__content.is-alternate .components-menu-group+.components-menu-group{ border-color:#1e1e1e; } .components-dropdown-menu__toggle{ vertical-align:top; } .components-dropdown-menu__menu{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:1.4; width:100%; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item,.components-dropdown-menu__menu .components-menu-item{ cursor:pointer; outline:none; padding:6px; white-space:nowrap; width:100%; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator,.components-dropdown-menu__menu .components-menu-item.has-separator{ margin-top:6px; overflow:visible; position:relative; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.has-separator:before,.components-dropdown-menu__menu .components-menu-item.has-separator:before{ background-color:#ddd; box-sizing:initial; content:""; display:block; height:1px; left:0; position:absolute; right:0; top:-3px; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-active svg,.components-dropdown-menu__menu .components-menu-item.is-active .dashicon,.components-dropdown-menu__menu .components-menu-item.is-active svg{ background:#1e1e1e; border-radius:1px; box-shadow:0 0 0 1px #1e1e1e; color:#fff; } .components-dropdown-menu__menu .components-dropdown-menu__menu-item.is-icon-only,.components-dropdown-menu__menu .components-menu-item.is-icon-only{ width:auto; } .components-dropdown-menu__menu .components-menu-item__button,.components-dropdown-menu__menu .components-menu-item__button.components-button{ height:auto; min-height:40px; padding-left:8px; padding-right:8px; text-align:left; } .components-duotone-picker__color-indicator:before{ background:#0000; } .components-duotone-picker__color-indicator>.components-button,.components-duotone-picker__color-indicator>.components-button.is-pressed:hover:not(:disabled){ background:linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); color:#0000; } .components-duotone-picker__color-indicator>.components-button:not([aria-disabled=true]):active{ color:#0000; } .components-color-list-picker,.components-color-list-picker__swatch-button{ width:100%; } .components-color-list-picker__color-picker{ margin:8px 0; } .components-color-list-picker__swatch-color{ margin:2px; } .components-external-link{ text-decoration:none; } .components-external-link__contents{ text-decoration:underline; } .components-external-link__icon{ font-weight:400; margin-left:.5ch; } .components-form-toggle,.components-form-toggle .components-form-toggle__track{ display:inline-block; height:16px; position:relative; } .components-form-toggle .components-form-toggle__track{ background-color:#fff; border:1px solid #949494; border-radius:8px; box-sizing:border-box; content:""; overflow:hidden; vertical-align:top; width:32px; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__track{ transition:background-color .2s ease,border-color .2s ease; } } .components-form-toggle .components-form-toggle__track:after{ border-top:16px solid #0000; box-sizing:border-box; content:""; inset:0; opacity:0; position:absolute; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__track:after{ transition:opacity .2s ease; } } .components-form-toggle .components-form-toggle__thumb{ background-color:#1e1e1e; border:6px solid #0000; border-radius:50%; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; box-sizing:border-box; display:block; height:12px; left:2px; position:absolute; top:2px; width:12px; } @media not (prefers-reduced-motion){ .components-form-toggle .components-form-toggle__thumb{ transition:transform .2s ease,background-color .2s ease-out; } } .components-form-toggle.is-checked .components-form-toggle__track{ background-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-form-toggle.is-checked .components-form-toggle__track:after{ opacity:1; } .components-form-toggle .components-form-toggle__input:focus+.components-form-toggle__track{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:2px; } .components-form-toggle.is-checked .components-form-toggle__thumb{ background-color:#fff; border-width:0; transform:translateX(16px); } .components-disabled .components-form-toggle,.components-form-toggle.is-disabled{ opacity:.3; } .components-form-toggle input.components-form-toggle__input[type=checkbox]{ border:none; height:100%; left:0; margin:0; opacity:0; padding:0; position:absolute; top:0; width:100%; z-index:1; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:checked{ background:none; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:before{ content:""; } .components-form-toggle input.components-form-toggle__input[type=checkbox]:not(:disabled,[aria-disabled=true]){ cursor:pointer; } .components-form-token-field__input-container{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; cursor:text; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:0; width:100%; } @media not (prefers-reduced-motion){ .components-form-token-field__input-container{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-form-token-field__input-container{ font-size:13px; line-height:normal; } } .components-form-token-field__input-container:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-form-token-field__input-container::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container::-moz-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container:-ms-input-placeholder{ color:#1e1e1e9e; } .components-form-token-field__input-container.is-disabled{ background:#ddd; border-color:#ddd; } .components-form-token-field__input-container.is-active{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-form-token-field__input-container input[type=text].components-form-token-field__input{ background:inherit; border:0; box-shadow:none; color:#1e1e1e; display:inline-block; flex:1; font-family:inherit; font-size:16px; margin-left:4px; max-width:100%; min-height:24px; min-width:50px; padding:0; width:100%; } @media (min-width:600px){ .components-form-token-field__input-container input[type=text].components-form-token-field__input{ font-size:13px; } } .components-form-token-field.is-active .components-form-token-field__input-container input[type=text].components-form-token-field__input,.components-form-token-field__input-container input[type=text].components-form-token-field__input:focus{ box-shadow:none; outline:none; } .components-form-token-field__input-container .components-form-token-field__token+input[type=text].components-form-token-field__input{ width:auto; } .components-form-token-field__token{ color:#1e1e1e; display:flex; font-size:13px; max-width:100%; } .components-form-token-field__token.is-success .components-form-token-field__remove-token,.components-form-token-field__token.is-success .components-form-token-field__token-text{ background:#4ab866; } .components-form-token-field__token.is-error .components-form-token-field__remove-token,.components-form-token-field__token.is-error .components-form-token-field__token-text{ background:#cc1818; } .components-form-token-field__token.is-validating .components-form-token-field__remove-token,.components-form-token-field__token.is-validating .components-form-token-field__token-text{ color:#757575; } .components-form-token-field__token.is-borderless{ padding:0 24px 0 0; position:relative; } .components-form-token-field__token.is-borderless .components-form-token-field__token-text{ background:#0000; } .components-form-token-field__token.is-borderless:not(.is-disabled) .components-form-token-field__token-text{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-form-token-field__token.is-borderless .components-form-token-field__remove-token{ background:#0000; color:#757575; position:absolute; right:0; top:1px; } .components-form-token-field__token.is-borderless.is-success .components-form-token-field__token-text{ color:#4ab866; } .components-form-token-field__token.is-borderless.is-error .components-form-token-field__token-text{ color:#cc1818; padding:0 4px 0 6px; } .components-form-token-field__token.is-borderless.is-validating .components-form-token-field__token-text{ color:#1e1e1e; } .components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{ background:#ddd; display:inline-block; height:auto; min-width:unset; } @media not (prefers-reduced-motion){ .components-form-token-field__remove-token.components-button,.components-form-token-field__token-text{ transition:all .2s cubic-bezier(.4, 1, .4, 1); } } .components-form-token-field__token-text{ border-radius:1px 0 0 1px; line-height:24px; overflow:hidden; padding:0 0 0 8px; text-overflow:ellipsis; white-space:nowrap; } .components-form-token-field__remove-token.components-button{ border-radius:0 1px 1px 0; color:#1e1e1e; line-height:10px; overflow:initial; } .components-form-token-field__remove-token.components-button:hover:not(:disabled){ color:#1e1e1e; } .components-form-token-field__suggestions-list{ box-shadow:inset 0 1px 0 0 #949494; flex:1 0 100%; list-style:none; margin:0; max-height:128px; min-width:100%; overflow-y:auto; padding:0; } @media not (prefers-reduced-motion){ .components-form-token-field__suggestions-list{ transition:all .15s ease-in-out; } } .components-form-token-field__suggestion{ box-sizing:border-box; color:#1e1e1e; display:block; font-size:13px; margin:0; min-height:32px; padding:8px 12px; } .components-form-token-field__suggestion.is-selected{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#fff; } .components-form-token-field__suggestion[aria-disabled=true]{ color:#949494; pointer-events:none; } .components-form-token-field__suggestion[aria-disabled=true].is-selected{ background-color:rgba(var(--wp-components-color-accent--rgb, var(--wp-admin-theme-color--rgb)), .04); } .components-form-token-field__suggestion:not(.is-empty){ cursor:pointer; } @media (min-width:600px){ .components-guide{ width:600px; } } .components-guide .components-modal__content{ margin-top:0; padding:0; } .components-guide .components-modal__content:before{ content:none; } .components-guide .components-modal__header{ border-bottom:none; height:60px; padding:0; position:sticky; } .components-guide .components-modal__header .components-button{ align-self:flex-start; margin:8px 8px 0 0; position:static; } .components-guide .components-modal__header .components-button:hover svg{ fill:#fff; } .components-guide .components-guide__container{ display:flex; flex-direction:column; justify-content:space-between; margin-top:-60px; min-height:100%; } .components-guide .components-guide__page{ display:flex; flex-direction:column; justify-content:center; position:relative; } @media (min-width:600px){ .components-guide .components-guide__page{ min-height:300px; } } .components-guide .components-guide__footer{ align-content:center; display:flex; height:36px; justify-content:center; margin:0 0 24px; padding:0 32px; position:relative; width:100%; } .components-guide .components-guide__page-control{ margin:0; text-align:center; } .components-guide .components-guide__page-control li{ display:inline-block; margin:0; } .components-guide .components-guide__page-control .components-button{ color:#e0e0e0; margin:-6px 0; } .components-guide .components-guide__page-control li[aria-current=step] .components-button{ color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-modal__frame.components-guide{ border:none; max-height:575px; min-width:312px; } @media (max-width:600px){ .components-modal__frame.components-guide{ margin:auto; max-width:calc(100vw - 32px); } } .components-button.components-guide__back-button,.components-button.components-guide__finish-button,.components-button.components-guide__forward-button{ position:absolute; } .components-button.components-guide__back-button{ left:32px; } .components-button.components-guide__finish-button,.components-button.components-guide__forward-button{ right:32px; } [role=region]{ position:relative; } .is-focusing-regions [role=region]:focus:after,[role=region].interface-interface-skeleton__content:focus-visible:after{ bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; z-index:1000000; } .is-focusing-regions .editor-post-publish-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-entities-saved-states-panel,.is-focusing-regions .interface-interface-skeleton__actions .editor-layout__toggle-publish-panel,.is-focusing-regions .interface-interface-skeleton__sidebar .editor-layout__toggle-sidebar-panel,.is-focusing-regions [role=region]:focus:after,.is-focusing-regions.is-distraction-free .interface-interface-skeleton__header .edit-post-header,[role=region].interface-interface-skeleton__content:focus-visible:after{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*2); } .components-menu-group+.components-menu-group{ border-top:1px solid #1e1e1e; padding-top:8px; } .components-menu-group+.components-menu-group.has-hidden-separator{ border-top:none; margin-top:0; padding-top:0; } .components-menu-group:has(>div:empty){ display:none; } .components-menu-group__label{ color:#757575; font-size:11px; font-weight:500; margin-bottom:12px; margin-top:4px; padding:0 8px; text-transform:uppercase; white-space:nowrap; } .components-menu-item__button,.components-menu-item__button.components-button{ width:100%; } .components-menu-item__button.components-button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button.components-button[role=menuitemradio] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemcheckbox] .components-menu-item__item:only-child,.components-menu-item__button[role=menuitemradio] .components-menu-item__item:only-child{ box-sizing:initial; padding-right:48px; } .components-menu-item__button .components-menu-items__item-icon,.components-menu-item__button.components-button .components-menu-items__item-icon{ display:inline-block; flex:0 0 auto; } .components-menu-item__button .components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-items__item-icon.has-icon-right{ margin-left:24px; margin-right:-2px; } .components-menu-item__button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right,.components-menu-item__button.components-button .components-menu-item__shortcut+.components-menu-items__item-icon.has-icon-right{ margin-left:8px; } .components-menu-item__button .block-editor-block-icon,.components-menu-item__button.components-button .block-editor-block-icon{ margin-left:-2px; margin-right:8px; } .components-menu-item__button.components-button.is-primary,.components-menu-item__button.is-primary{ justify-content:center; } .components-menu-item__button.components-button.is-primary .components-menu-item__item,.components-menu-item__button.is-primary .components-menu-item__item{ margin-right:0; } .components-menu-item__button.components-button:disabled.is-tertiary,.components-menu-item__button.components-button[aria-disabled=true].is-tertiary,.components-menu-item__button:disabled.is-tertiary,.components-menu-item__button[aria-disabled=true].is-tertiary{ background:none; color:var(--wp-components-color-accent-darker-10, var(--wp-admin-theme-color-darker-10, #2145e6)); opacity:.3; } .components-menu-item__info-wrapper{ display:flex; flex-direction:column; margin-right:auto; } .components-menu-item__info{ color:#757575; font-size:12px; margin-top:4px; white-space:normal; } .components-menu-item__item{ align-items:center; display:inline-flex; margin-right:auto; min-width:160px; white-space:nowrap; } .components-menu-item__shortcut{ align-self:center; color:currentColor; display:none; margin-left:auto; margin-right:0; padding-left:24px; } @media (min-width:480px){ .components-menu-item__shortcut{ display:inline; } } .components-menu-items-choice,.components-menu-items-choice.components-button{ height:auto; min-height:40px; } .components-menu-items-choice svg,.components-menu-items-choice.components-button svg{ margin-right:12px; } .components-menu-items-choice.components-button.has-icon,.components-menu-items-choice.has-icon{ padding-left:12px; } .components-modal__screen-overlay{ background-color:#00000059; bottom:0; display:flex; left:0; position:fixed; right:0; top:0; z-index:100000; } @keyframes __wp-base-styles-fade-in{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .components-modal__screen-overlay{ animation:__wp-base-styles-fade-in .08s linear 0s; animation-fill-mode:forwards; } } @keyframes __wp-base-styles-fade-out{ 0%{ opacity:1; } to{ opacity:0; } } @media not (prefers-reduced-motion){ .components-modal__screen-overlay.is-animating-out{ animation:__wp-base-styles-fade-out .08s linear 80ms; animation-fill-mode:forwards; } } .components-modal__frame{ animation-fill-mode:forwards; animation-name:components-modal__appear-animation; animation-timing-function:cubic-bezier(.29, 0, 0, 1); background:#fff; border-radius:8px 8px 0 0; box-shadow:0 5px 15px #00000014,0 15px 27px #00000012,0 30px 36px #0000000a,0 50px 43px #00000005; box-sizing:border-box; display:flex; margin:40px 0 0; overflow:hidden; width:100%; } .components-modal__frame *,.components-modal__frame :after,.components-modal__frame :before{ box-sizing:inherit; } @media not (prefers-reduced-motion){ .components-modal__frame{ animation-duration:var(--modal-frame-animation-duration); } } .components-modal__screen-overlay.is-animating-out .components-modal__frame{ animation-name:components-modal__disappear-animation; animation-timing-function:cubic-bezier(1, 0, .2, 1); } @media (min-width:600px){ .components-modal__frame{ border-radius:8px; margin:auto; max-height:calc(100% - 120px); max-width:calc(100% - 32px); min-width:350px; width:auto; } } @media (min-width:600px) and (min-width:600px){ .components-modal__frame.is-full-screen{ height:calc(100% - 32px); max-height:none; width:calc(100% - 32px); } } @media (min-width:600px) and (min-width:782px){ .components-modal__frame.is-full-screen{ height:calc(100% - 80px); max-width:none; width:calc(100% - 80px); } } @media (min-width:600px){ .components-modal__frame.has-size-large,.components-modal__frame.has-size-medium,.components-modal__frame.has-size-small{ width:100%; } .components-modal__frame.has-size-small{ max-width:384px; } .components-modal__frame.has-size-medium{ max-width:512px; } .components-modal__frame.has-size-large{ max-width:840px; } } @media (min-width:960px){ .components-modal__frame{ max-height:70%; } } @keyframes components-modal__appear-animation{ 0%{ opacity:0; transform:scale(.9); } to{ opacity:1; transform:scale(1); } } @keyframes components-modal__disappear-animation{ 0%{ opacity:1; transform:scale(1); } to{ opacity:0; transform:scale(.9); } } .components-modal__header{ align-items:center; border-bottom:1px solid #0000; box-sizing:border-box; display:flex; flex-direction:row; height:72px; justify-content:space-between; left:0; padding:24px 32px 8px; position:absolute; top:0; width:100%; z-index:10; } .components-modal__header .components-modal__header-heading{ font-size:1.2rem; font-weight:600; } .components-modal__header h1{ line-height:1; margin:0; } .components-modal__content.has-scrolled-content:not(.hide-header) .components-modal__header{ border-bottom-color:#ddd; } .components-modal__header+p{ margin-top:0; } .components-modal__header-heading-container{ align-items:center; display:flex; flex-direction:row; flex-grow:1; justify-content:left; } .components-modal__header-icon-container{ display:inline-block; } .components-modal__header-icon-container svg{ max-height:36px; max-width:36px; padding:8px; } .components-modal__content{ flex:1; margin-top:72px; overflow:auto; padding:4px 32px 32px; } .components-modal__content.hide-header{ margin-top:0; padding-top:32px; } .components-modal__content.is-scrollable:focus-visible{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:-2px; } .components-notice{ align-items:center; background-color:#fff; border-left:4px solid var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); color:#1e1e1e; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; padding:8px 12px; } .components-notice.is-dismissible{ position:relative; } .components-notice.is-success{ background-color:#eff9f1; border-left-color:#4ab866; } .components-notice.is-warning{ background-color:#fef8ee; border-left-color:#f0b849; } .components-notice.is-error{ background-color:#f4a2a2; border-left-color:#cc1818; } .components-notice__content{ flex-grow:1; margin:4px 25px 4px 0; } .components-notice__actions{ display:flex; flex-wrap:wrap; } .components-notice__action.components-button{ margin-right:8px; } .components-notice__action.components-button,.components-notice__action.components-button.is-link{ margin-left:12px; } .components-notice__action.components-button.is-secondary{ vertical-align:initial; } .components-notice__dismiss{ align-self:flex-start; color:#757575; flex-shrink:0; } .components-notice__dismiss:not(:disabled):not([aria-disabled=true]):focus,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):active,.components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{ background-color:initial; color:#1e1e1e; } .components-notice__dismiss:not(:disabled):not([aria-disabled=true]):not(.is-secondary):hover{ box-shadow:none; } .components-notice-list{ box-sizing:border-box; max-width:100vw; } .components-notice-list .components-notice__content{ line-height:2; margin-bottom:12px; margin-top:12px; } .components-notice-list .components-notice__action.components-button{ display:block; margin-left:0; margin-top:8px; } .components-panel{ background:#fff; border:1px solid #e0e0e0; } .components-panel>.components-panel__body:first-child,.components-panel>.components-panel__header:first-child{ margin-top:-1px; } .components-panel>.components-panel__body:last-child,.components-panel>.components-panel__header:last-child{ border-bottom-width:0; } .components-panel+.components-panel{ margin-top:-1px; } .components-panel__body{ border-bottom:1px solid #e0e0e0; border-top:1px solid #e0e0e0; } .components-panel__body h3{ margin:0 0 .5em; } .components-panel__body.is-opened{ padding:16px; } .components-panel__header{ align-items:center; border-bottom:1px solid #ddd; box-sizing:initial; display:flex; flex-shrink:0; height:47px; justify-content:space-between; padding:0 16px; } .components-panel__header h2{ color:inherit; font-size:inherit; margin:0; } .components-panel__body+.components-panel__body,.components-panel__body+.components-panel__header,.components-panel__header+.components-panel__body,.components-panel__header+.components-panel__header{ margin-top:-1px; } .components-panel__body>.components-panel__body-title{ display:block; font-size:inherit; margin-bottom:0; margin-top:0; padding:0; } @media not (prefers-reduced-motion){ .components-panel__body>.components-panel__body-title{ transition:background .1s ease-in-out; } } .components-panel__body.is-opened>.components-panel__body-title{ margin:-16px -16px 5px; } .components-panel__body>.components-panel__body-title:hover{ background:#f0f0f0; border:none; } .components-panel__body-toggle.components-button{ border:none; box-shadow:none; color:#1e1e1e; font-weight:500; height:auto; outline:none; padding:16px 48px 16px 16px; position:relative; text-align:left; width:100%; } @media not (prefers-reduced-motion){ .components-panel__body-toggle.components-button{ transition:background .1s ease-in-out; } } .components-panel__body-toggle.components-button:focus{ border-radius:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-panel__body-toggle.components-button .components-panel__arrow{ color:#1e1e1e; position:absolute; right:16px; top:50%; transform:translateY(-50%); fill:currentColor; } @media not (prefers-reduced-motion){ .components-panel__body-toggle.components-button .components-panel__arrow{ transition:color .1s ease-in-out; } } body.rtl .components-panel__body-toggle.components-button .dashicons-arrow-right{ -ms-filter:fliph; filter:FlipH; margin-top:-10px; transform:scaleX(-1); } .components-panel__icon{ color:#757575; margin:-2px 0 -2px 6px; } .components-panel__body-toggle-icon{ margin-right:-5px; } .components-panel__color-title{ float:left; height:19px; } .components-panel__row{ align-items:center; display:flex; justify-content:space-between; margin-top:8px; min-height:36px; } .components-panel__row select{ min-width:0; } .components-panel__row label{ flex-shrink:0; margin-right:12px; max-width:75%; } .components-panel__row:empty,.components-panel__row:first-of-type{ margin-top:0; } .components-panel .circle-picker{ padding-bottom:20px; } .components-placeholder.components-placeholder{ align-items:flex-start; box-sizing:border-box; color:#1e1e1e; display:flex; flex-direction:column; font-size:13px; gap:16px; margin:0; padding:24px; position:relative; text-align:left; width:100%; -moz-font-smoothing:subpixel-antialiased; -webkit-font-smoothing:subpixel-antialiased; background-color:#fff; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; outline:1px solid #0000; } .components-placeholder__error,.components-placeholder__fieldset,.components-placeholder__instructions,.components-placeholder__label{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:400; letter-spacing:normal; line-height:normal; text-transform:none; } .components-placeholder__label{ align-items:center; display:flex; font-weight:600; } .components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{ margin-right:4px; fill:currentColor; } @media (forced-colors:active){ .components-placeholder__label .block-editor-block-icon,.components-placeholder__label .dashicon,.components-placeholder__label>svg{ fill:CanvasText; } } .components-placeholder__label:empty{ display:none; } .components-placeholder__fieldset,.components-placeholder__fieldset form{ display:flex; flex-direction:row; flex-wrap:wrap; gap:16px; justify-content:flex-start; width:100%; } .components-placeholder__fieldset form p,.components-placeholder__fieldset p{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .components-placeholder__fieldset.is-column-layout,.components-placeholder__fieldset.is-column-layout form{ flex-direction:column; } .components-placeholder__input[type=url]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; flex:1 1 auto; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; line-height:normal; padding:6px 8px; } @media not (prefers-reduced-motion){ .components-placeholder__input[type=url]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-placeholder__input[type=url]{ font-size:13px; line-height:normal; } } .components-placeholder__input[type=url]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-placeholder__input[type=url]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-placeholder__input[type=url]::-moz-placeholder{ color:#1e1e1e9e; } .components-placeholder__input[type=url]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-placeholder__error{ gap:8px; width:100%; } .components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link{ margin-left:10px; margin-right:10px; } .components-placeholder__fieldset .components-button:not(.is-link)~.components-button.is-link:last-child{ margin-right:0; } .components-placeholder.is-medium .components-placeholder__instructions,.components-placeholder.is-small .components-placeholder__instructions{ display:none; } .components-placeholder.is-medium .components-placeholder__fieldset,.components-placeholder.is-medium .components-placeholder__fieldset form,.components-placeholder.is-small .components-placeholder__fieldset,.components-placeholder.is-small .components-placeholder__fieldset form{ flex-direction:column; } .components-placeholder.is-medium .components-button,.components-placeholder.is-medium .components-placeholder__fieldset>*,.components-placeholder.is-small .components-button,.components-placeholder.is-small .components-placeholder__fieldset>*{ justify-content:center; width:100%; } .components-placeholder.is-small{ padding:16px; } .components-placeholder.has-illustration{ -webkit-backdrop-filter:blur(100px); backdrop-filter:blur(100px); backface-visibility:hidden; background-color:initial; border-radius:0; box-shadow:none; color:inherit; display:flex; overflow:hidden; } .is-dark-theme .components-placeholder.has-illustration{ background-color:#0000001a; } .components-placeholder.has-illustration .components-placeholder__fieldset{ margin-left:0; margin-right:0; } .components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{ opacity:0; pointer-events:none; } @media not (prefers-reduced-motion){ .components-placeholder.has-illustration .components-button,.components-placeholder.has-illustration .components-placeholder__instructions,.components-placeholder.has-illustration .components-placeholder__label{ transition:opacity .1s linear; } } .is-selected>.components-placeholder.has-illustration .components-button,.is-selected>.components-placeholder.has-illustration .components-placeholder__instructions,.is-selected>.components-placeholder.has-illustration .components-placeholder__label{ opacity:1; pointer-events:auto; } .components-placeholder.has-illustration:before{ background:currentColor; bottom:0; content:""; left:0; opacity:.1; pointer-events:none; position:absolute; right:0; top:0; } .is-selected .components-placeholder.has-illustration{ overflow:auto; } .components-placeholder__preview{ display:flex; justify-content:center; } .components-placeholder__illustration{ box-sizing:initial; height:100%; left:50%; position:absolute; top:50%; transform:translate(-50%, -50%); width:100%; stroke:currentColor; opacity:.25; } .components-popover{ box-sizing:border-box; will-change:transform; z-index:1000000; } .components-popover *,.components-popover :after,.components-popover :before{ box-sizing:inherit; } .components-popover.is-expanded{ bottom:0; left:0; position:fixed; right:0; top:0; z-index:1000000 !important; } .components-popover__content{ background:#fff; border-radius:4px; box-shadow:0 0 0 1px #ccc,0 2px 3px #0000000d,0 4px 5px #0000000a,0 12px 12px #00000008,0 16px 16px #00000005; box-sizing:border-box; width:min-content; } .is-alternate .components-popover__content{ border-radius:2px; box-shadow:0 0 0 1px #1e1e1e; } .is-unstyled .components-popover__content{ background:none; border-radius:0; box-shadow:none; } .components-popover.is-expanded .components-popover__content{ box-shadow:0 -1px 0 0 #ccc; height:calc(100% - 48px); overflow-y:visible; position:static; width:auto; } .components-popover.is-expanded.is-alternate .components-popover__content{ box-shadow:0 -1px 0 #1e1e1e; } .components-popover__header{ align-items:center; background:#fff; display:flex; height:48px; justify-content:space-between; padding:0 8px 0 16px; } .components-popover__header-title{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; width:100%; } .components-popover__close.components-button{ z-index:5; } .components-popover__arrow{ display:flex; height:14px; pointer-events:none; position:absolute; width:14px; } .components-popover__arrow:before{ background-color:#fff; content:""; height:2px; left:1px; position:absolute; right:1px; top:-1px; } .components-popover__arrow.is-top{ bottom:-14px !important; transform:rotate(0); } .components-popover__arrow.is-right{ left:-14px !important; transform:rotate(90deg); } .components-popover__arrow.is-bottom{ top:-14px !important; transform:rotate(180deg); } .components-popover__arrow.is-left{ right:-14px !important; transform:rotate(-90deg); } .components-popover__triangle{ display:block; flex:1; } .components-popover__triangle-bg{ fill:#fff; } .components-popover__triangle-border{ fill:#0000; stroke-width:1px; stroke:#ccc; } .is-alternate .components-popover__triangle-border{ stroke:#1e1e1e; } .components-radio-control{ border:0; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; margin:0; padding:0; } .components-radio-control__group-wrapper.has-help{ margin-block-end:12px; } .components-radio-control__option{ align-items:center; column-gap:8px; display:grid; grid-template-columns:auto 1fr; grid-template-rows:auto minmax(0, max-content); } .components-radio-control__input[type=radio]{ appearance:none; border:1px solid #1e1e1e; border-radius:2px; border-radius:50%; box-shadow:0 0 0 #0000; cursor:pointer; display:inline-flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; grid-column:1; grid-row:1; height:24px; line-height:normal; margin:0; max-width:24px; min-width:24px; padding:0; position:relative; transition:none; width:24px; } @media not (prefers-reduced-motion){ .components-radio-control__input[type=radio]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-radio-control__input[type=radio]{ font-size:13px; line-height:normal; } } .components-radio-control__input[type=radio]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); } .components-radio-control__input[type=radio]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-radio-control__input[type=radio]::-moz-placeholder{ color:#1e1e1e9e; } .components-radio-control__input[type=radio]:-ms-input-placeholder{ color:#1e1e1e9e; } @media (min-width:600px){ .components-radio-control__input[type=radio]{ height:16px; max-width:16px; min-width:16px; width:16px; } } .components-radio-control__input[type=radio]:checked:before{ background-color:#fff; border:4px solid #fff; box-sizing:inherit; height:12px; left:50%; margin:0; position:absolute; top:50%; transform:translate(-50%, -50%); width:12px; } @media (min-width:600px){ .components-radio-control__input[type=radio]:checked:before{ height:8px; width:8px; } } .components-radio-control__input[type=radio]:focus{ box-shadow:0 0 0 2px #fff, 0 0 0 4px var(--wp-admin-theme-color); } .components-radio-control__input[type=radio]:checked{ background:var(--wp-admin-theme-color); border:none; } .components-radio-control__input[type=radio]:focus{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .components-radio-control__input[type=radio]:checked{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-color:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-radio-control__input[type=radio]:checked:before{ border-radius:50%; content:""; } .components-radio-control__label{ cursor:pointer; grid-column:2; grid-row:1; line-height:24px; } @media (min-width:600px){ .components-radio-control__label{ line-height:16px; } } .components-radio-control__option-description{ grid-column:2; grid-row:2; padding-block-start:4px; } .components-radio-control__option-description.components-radio-control__option-description{ margin-top:0; } .components-resizable-box__handle{ display:none; height:23px; width:23px; z-index:2; } .components-resizable-box__container.has-show-handle .components-resizable-box__handle{ display:block; } .components-resizable-box__handle>div{ height:100%; outline:none; position:relative; width:100%; z-index:2; } .components-resizable-box__container>img{ width:inherit; } .components-resizable-box__handle:after{ background:#fff; border-radius:50%; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)), 0 1px 1px #00000008, 0 1px 2px #00000005, 0 3px 3px #00000005, 0 4px 4px #00000003; content:""; cursor:inherit; display:block; height:15px; outline:2px solid #0000; position:absolute; right:calc(50% - 8px); top:calc(50% - 8px); width:15px; } .components-resizable-box__side-handle:before{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-radius:9999px; content:""; cursor:inherit; display:block; height:3px; opacity:0; position:absolute; right:calc(50% - 1px); top:calc(50% - 1px); width:3px; } @media not (prefers-reduced-motion){ .components-resizable-box__side-handle:before{ transition:transform .1s ease-in; will-change:transform; } } .components-resizable-box__corner-handle,.components-resizable-box__side-handle{ z-index:2; } .components-resizable-box__side-handle.components-resizable-box__handle-bottom,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:before,.components-resizable-box__side-handle.components-resizable-box__handle-top,.components-resizable-box__side-handle.components-resizable-box__handle-top:before{ border-left:0; border-right:0; left:0; width:100%; } .components-resizable-box__side-handle.components-resizable-box__handle-left,.components-resizable-box__side-handle.components-resizable-box__handle-left:before,.components-resizable-box__side-handle.components-resizable-box__handle-right,.components-resizable-box__side-handle.components-resizable-box__handle-right:before{ border-bottom:0; border-top:0; height:100%; top:0; } @media not (prefers-reduced-motion){ .components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{ animation:components-resizable-box__top-bottom-animation .1s ease-out 0s; animation-fill-mode:forwards; } .components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before{ animation:components-resizable-box__left-right-animation .1s ease-out 0s; animation-fill-mode:forwards; } } @media not all and (min-resolution:0.001dpcm){ @supports (-webkit-appearance:none){ .components-resizable-box__side-handle.components-resizable-box__handle-bottom:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-bottom:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-left:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-right:hover:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:active:before,.components-resizable-box__side-handle.components-resizable-box__handle-top:hover:before{ animation:none; } } } @keyframes components-resizable-box__top-bottom-animation{ 0%{ opacity:0; transform:scaleX(0); } to{ opacity:1; transform:scaleX(1); } } @keyframes components-resizable-box__left-right-animation{ 0%{ opacity:0; transform:scaleY(0); } to{ opacity:1; transform:scaleY(1); } } .components-resizable-box__handle-right{ right:-11.5px; } .components-resizable-box__handle-left{ left:-11.5px; } .components-resizable-box__handle-top{ top:-11.5px; } .components-resizable-box__handle-bottom{ bottom:-11.5px; } .components-responsive-wrapper{ align-items:center; display:flex; justify-content:center; max-width:100%; position:relative; } .components-responsive-wrapper__content{ display:block; max-width:100%; width:100%; } .components-sandbox{ overflow:hidden; } iframe.components-sandbox{ width:100%; } body.lockscroll,html.lockscroll{ overflow:hidden; } .components-select-control__input{ outline:0; -webkit-tap-highlight-color:rgba(0, 0, 0, 0) !important; } @media (max-width:782px){ .components-base-control .components-base-control__field .components-select-control__input{ font-size:16px; } } .components-snackbar{ -webkit-backdrop-filter:blur(16px) saturate(180%); backdrop-filter:blur(16px) saturate(180%); background:#000000d9; border-radius:4px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; box-sizing:border-box; color:#fff; cursor:pointer; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; max-width:600px; padding:12px 20px; pointer-events:auto; width:100%; } @media (min-width:600px){ .components-snackbar{ width:fit-content; } } .components-snackbar:focus{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); } .components-snackbar.components-snackbar-explicit-dismiss{ cursor:default; } .components-snackbar .components-snackbar__content-with-icon{ padding-left:24px; position:relative; } .components-snackbar .components-snackbar__icon{ left:-8px; position:absolute; top:-2.9px; } .components-snackbar .components-snackbar__dismiss-button{ cursor:pointer; margin-left:24px; } .components-snackbar__action.components-button{ color:#fff; flex-shrink:0; margin-left:32px; } .components-snackbar__action.components-button:focus{ box-shadow:none; outline:1px dotted #fff; } .components-snackbar__action.components-button:hover{ color:currentColor; text-decoration:none; } .components-snackbar__content{ align-items:baseline; display:flex; justify-content:space-between; line-height:1.4; } .components-snackbar-list{ box-sizing:border-box; pointer-events:none; position:absolute; width:100%; z-index:100000; } .components-snackbar-list__notice-container{ padding-top:8px; position:relative; } .components-tab-panel__tabs{ align-items:stretch; display:flex; flex-direction:row; } .components-tab-panel__tabs[aria-orientation=vertical]{ flex-direction:column; } .components-tab-panel__tabs-item{ background:#0000; border:none; border-radius:0; box-shadow:none; cursor:pointer; font-weight:500; height:48px !important; margin-left:0; padding:3px 16px; position:relative; } .components-tab-panel__tabs-item:focus:not(:disabled){ box-shadow:none; outline:none; position:relative; } .components-tab-panel__tabs-item:after{ background:var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); border-radius:0; bottom:0; content:""; height:calc(var(--wp-admin-border-width-focus)*0); left:0; pointer-events:none; position:absolute; right:0; } @media not (prefers-reduced-motion){ .components-tab-panel__tabs-item:after{ transition:all .1s linear; } } .components-tab-panel__tabs-item.is-active:after{ height:calc(var(--wp-admin-border-width-focus)*1); outline:2px solid #0000; outline-offset:-1px; } .components-tab-panel__tabs-item:before{ border-radius:2px; bottom:12px; box-shadow:0 0 0 0 #0000; content:""; left:12px; pointer-events:none; position:absolute; right:12px; top:12px; } @media not (prefers-reduced-motion){ .components-tab-panel__tabs-item:before{ transition:all .1s linear; } } .components-tab-panel__tabs-item:focus-visible:before{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; } .components-tab-panel__tab-content:focus{ box-shadow:none; outline:none; } .components-tab-panel__tab-content:focus-visible{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); outline:2px solid #0000; outline-offset:0; } .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ border:1px solid #949494; border-radius:2px; box-shadow:0 0 0 #0000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:16px; height:32px; line-height:normal; margin:0; padding:6px 8px; width:100%; } @media not (prefers-reduced-motion){ .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ transition:box-shadow .1s linear; } } @media (min-width:600px){ .components-text-control__input,.components-text-control__input[type=color],.components-text-control__input[type=date],.components-text-control__input[type=datetime-local],.components-text-control__input[type=datetime],.components-text-control__input[type=email],.components-text-control__input[type=month],.components-text-control__input[type=number],.components-text-control__input[type=password],.components-text-control__input[type=tel],.components-text-control__input[type=text],.components-text-control__input[type=time],.components-text-control__input[type=url],.components-text-control__input[type=week]{ font-size:13px; line-height:normal; } } .components-text-control__input:focus,.components-text-control__input[type=color]:focus,.components-text-control__input[type=date]:focus,.components-text-control__input[type=datetime-local]:focus,.components-text-control__input[type=datetime]:focus,.components-text-control__input[type=email]:focus,.components-text-control__input[type=month]:focus,.components-text-control__input[type=number]:focus,.components-text-control__input[type=password]:focus,.components-text-control__input[type=tel]:focus,.components-text-control__input[type=text]:focus,.components-text-control__input[type=time]:focus,.components-text-control__input[type=url]:focus,.components-text-control__input[type=week]:focus{ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 .5px var(--wp-admin-theme-color); outline:2px solid #0000; } .components-text-control__input::-webkit-input-placeholder,.components-text-control__input[type=color]::-webkit-input-placeholder,.components-text-control__input[type=date]::-webkit-input-placeholder,.components-text-control__input[type=datetime-local]::-webkit-input-placeholder,.components-text-control__input[type=datetime]::-webkit-input-placeholder,.components-text-control__input[type=email]::-webkit-input-placeholder,.components-text-control__input[type=month]::-webkit-input-placeholder,.components-text-control__input[type=number]::-webkit-input-placeholder,.components-text-control__input[type=password]::-webkit-input-placeholder,.components-text-control__input[type=tel]::-webkit-input-placeholder,.components-text-control__input[type=text]::-webkit-input-placeholder,.components-text-control__input[type=time]::-webkit-input-placeholder,.components-text-control__input[type=url]::-webkit-input-placeholder,.components-text-control__input[type=week]::-webkit-input-placeholder{ color:#1e1e1e9e; } .components-text-control__input::-moz-placeholder,.components-text-control__input[type=color]::-moz-placeholder,.components-text-control__input[type=date]::-moz-placeholder,.components-text-control__input[type=datetime-local]::-moz-placeholder,.components-text-control__input[type=datetime]::-moz-placeholder,.components-text-control__input[type=email]::-moz-placeholder,.components-text-control__input[type=month]::-moz-placeholder,.components-text-control__input[type=number]::-moz-placeholder,.components-text-control__input[type=password]::-moz-placeholder,.components-text-control__input[type=tel]::-moz-placeholder,.components-text-control__input[type=text]::-moz-placeholder,.components-text-control__input[type=time]::-moz-placeholder,.components-text-control__input[type=url]::-moz-placeholder,.components-text-control__input[type=week]::-moz-placeholder{ color:#1e1e1e9e; } .components-text-control__input:-ms-input-placeholder,.components-text-control__input[type=color]:-ms-input-placeholder,.components-text-control__input[type=date]:-ms-input-placeholder,.components-text-control__input[type=datetime-local]:-ms-input-placeholder,.components-text-control__input[type=datetime]:-ms-input-placeholder,.components-text-control__input[type=email]:-ms-input-placeholder,.components-text-control__input[type=month]:-ms-input-placeholder,.components-text-control__input[type=number]:-ms-input-placeholder,.components-text-control__input[type=password]:-ms-input-placeholder,.components-text-control__input[type=tel]:-ms-input-placeholder,.components-text-control__input[type=text]:-ms-input-placeholder,.components-text-control__input[type=time]:-ms-input-placeholder,.components-text-control__input[type=url]:-ms-input-placeholder,.components-text-control__input[type=week]:-ms-input-placeholder{ color:#1e1e1e9e; } .components-text-control__input.is-next-40px-default-size,.components-text-control__input[type=color].is-next-40px-default-size,.components-text-control__input[type=date].is-next-40px-default-size,.components-text-control__input[type=datetime-local].is-next-40px-default-size,.components-text-control__input[type=datetime].is-next-40px-default-size,.components-text-control__input[type=email].is-next-40px-default-size,.components-text-control__input[type=month].is-next-40px-default-size,.components-text-control__input[type=number].is-next-40px-default-size,.components-text-control__input[type=password].is-next-40px-default-size,.components-text-control__input[type=tel].is-next-40px-default-size,.components-text-control__input[type=text].is-next-40px-default-size,.components-text-control__input[type=time].is-next-40px-default-size,.components-text-control__input[type=url].is-next-40px-default-size,.components-text-control__input[type=week].is-next-40px-default-size{ height:40px; padding-left:12px; padding-right:12px; } .components-text-control__input[type=email],.components-text-control__input[type=url]{ direction:ltr; } .components-tip{ color:#757575; display:flex; } .components-tip svg{ align-self:center; fill:#f0b849; flex-shrink:0; margin-right:16px; } .components-tip p{ margin:0; } .components-toggle-control__label{ line-height:16px; } .components-toggle-control__label:not(.is-disabled){ cursor:pointer; } .components-toggle-control__help{ display:inline-block; margin-inline-start:40px; } .components-accessible-toolbar{ border:1px solid #1e1e1e; border-radius:2px; display:inline-flex; flex-shrink:0; } .components-accessible-toolbar>.components-toolbar-group:last-child{ border-right:none; } .components-accessible-toolbar.is-unstyled{ border:none; } .components-accessible-toolbar.is-unstyled>.components-toolbar-group{ border-right:none; } .components-accessible-toolbar[aria-orientation=vertical],.components-toolbar[aria-orientation=vertical]{ align-items:center; display:flex; flex-direction:column; } .components-accessible-toolbar .components-button,.components-toolbar .components-button{ height:48px; padding-left:16px; padding-right:16px; position:relative; z-index:1; } .components-accessible-toolbar .components-button:focus:not(:disabled),.components-toolbar .components-button:focus:not(:disabled){ box-shadow:none; outline:none; } .components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .components-accessible-toolbar .components-button:before,.components-toolbar .components-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .components-accessible-toolbar .components-button svg,.components-toolbar .components-button svg{ margin-left:auto; margin-right:auto; position:relative; } .components-accessible-toolbar .components-button.is-pressed,.components-accessible-toolbar .components-button.is-pressed:hover,.components-toolbar .components-button.is-pressed,.components-toolbar .components-button.is-pressed:hover{ background:#0000; } .components-accessible-toolbar .components-button.is-pressed:before,.components-toolbar .components-button.is-pressed:before{ background:#1e1e1e; } .components-accessible-toolbar .components-button:focus:before,.components-toolbar .components-button:focus:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .components-accessible-toolbar .components-button.has-icon.has-icon,.components-toolbar .components-button.has-icon.has-icon{ min-width:48px; padding-left:8px; padding-right:8px; } @keyframes components-button__appear-animation{ 0%{ transform:scaleY(0); } to{ transform:scaleY(1); } } .components-toolbar__control.components-button{ position:relative; } .components-toolbar__control.components-button[data-subscript] svg{ padding:5px 10px 5px 0; } .components-toolbar__control.components-button[data-subscript]:after{ bottom:10px; content:attr(data-subscript); font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:600; line-height:12px; position:absolute; right:8px; } .components-toolbar__control.components-button:not(:disabled).is-pressed[data-subscript]:after{ color:#fff; } .components-toolbar-group{ background-color:#fff; border-right:1px solid #1e1e1e; display:inline-flex; flex-shrink:0; flex-wrap:wrap; line-height:0; min-height:48px; padding-left:6px; padding-right:6px; } .components-toolbar-group .components-toolbar-group.components-toolbar-group{ border-width:0; margin:0; } .components-toolbar-group .components-button.components-button,.components-toolbar-group .components-button.has-icon.has-icon{ justify-content:center; min-width:36px; padding-left:6px; padding-right:6px; } .components-toolbar-group .components-button.components-button svg,.components-toolbar-group .components-button.has-icon.has-icon svg{ min-width:24px; } .components-toolbar-group .components-button.components-button:before,.components-toolbar-group .components-button.has-icon.has-icon:before{ left:2px; right:2px; } .components-toolbar{ background-color:#fff; border:1px solid #1e1e1e; display:inline-flex; flex-shrink:0; flex-wrap:wrap; margin:0; min-height:48px; } .components-toolbar .components-toolbar.components-toolbar{ border-width:0; margin:0; } div.components-toolbar>div{ display:flex; margin:0; } div.components-toolbar>div+div.has-left-divider{ margin-left:6px; overflow:visible; position:relative; } div.components-toolbar>div+div.has-left-divider:before{ background-color:#ddd; box-sizing:initial; content:""; display:inline-block; height:20px; left:-3px; position:absolute; top:8px; width:1px; } .components-tooltip{ background:#000; border-radius:2px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; color:#f0f0f0; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:12px; line-height:1.4; padding:4px 8px; text-align:center; z-index:1000002; } .components-tooltip__shortcut{ margin-left:8px; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-block-legacy-widget__edit-form{background:#fff;border:1px solid #1e1e1e;border-radius:2px;max-height:calc(100vh - 2px);overflow-y:scroll;padding:11px}.wp-block-legacy-widget__edit-form:not([hidden]){display:flow-root}.wp-block-legacy-widget__edit-form .wp-block-legacy-widget__edit-form-title{color:#000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:14px;font-weight:600;margin:0 0 12px}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside{border:none;box-shadow:none;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside p{margin:8px 0}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{font-size:13px;line-height:2.1}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside a,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{color:#000;font-family:system-ui;font-weight:400}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=date],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime-local],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=email],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=month],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=number],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=password],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=search],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=tel],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=text],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=time],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=url],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=week],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{background-color:initial;border:1px solid #757575;border-radius:3px;box-shadow:none;box-sizing:border-box;color:#000;display:block;font-family:system-ui;font-size:13px;font-weight:400;line-height:1;margin:0;min-height:30px;padding-bottom:8px;padding-right:8px;padding-top:8px;width:100%}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{padding-right:4px}.wp-block-legacy-widget__edit-form .widget.open,.wp-block-legacy-widget__edit-form .widget.open:focus-within{z-index:0}.wp-block-legacy-widget__edit-form.wp-block-legacy-widget__edit-form,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{color:#000}.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-preview{cursor:pointer}.wp-block-legacy-widget__edit-no-preview:hover:after,.wp-block-legacy-widget__edit-preview:hover:after{border:1px solid #949494;border-radius:2px;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.wp-block-legacy-widget__edit-preview.is-offscreen{position:absolute;right:-9999px;top:0;width:100%}.wp-block-legacy-widget__edit-preview-iframe{overflow:hidden;width:100%}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{background:#f0f0f0;padding:8px 12px}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3{font-size:14px;font-weight:600;margin:4px 0}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{margin:4px 0}.wp-block-legacy-widget-inspector-card{padding:0 52px 16px 16px}.interface-complementary-area .wp-block-legacy-widget-inspector-card__name{font-weight:500;margin:0 0 5px}.is-selected .wp-block-legacy-widget__container{min-height:50px;padding:8px 12px}.components-popover__content .wp-block-legacy-widget__edit-form{min-width:400px}.wp-block-widget-group.has-child-selected:after{border:1px solid var(--wp-admin-theme-color);border-radius:2px;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.wp-block-widget-group .widget-title{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:18px;font-weight:600}.wp-block-widget-group__placeholder .block-editor-inserter{width:100%}.is-dark-theme .wp-block-widget-group__placeholder .block-editor-button-block-appender{box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-block-legacy-widget__edit-form{background:#fff;border:1px solid #1e1e1e;border-radius:2px;max-height:calc(100vh - 2px);overflow-y:scroll;padding:11px}.wp-block-legacy-widget__edit-form:not([hidden]){display:flow-root}.wp-block-legacy-widget__edit-form .wp-block-legacy-widget__edit-form-title{color:#000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:14px;font-weight:600;margin:0 0 12px}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside{border:none;box-shadow:none;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside p{margin:8px 0}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{font-size:13px;line-height:2.1}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside a,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{color:#000;font-family:system-ui;font-weight:400}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=date],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime-local],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=email],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=month],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=number],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=password],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=search],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=tel],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=text],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=time],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=url],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=week],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{background-color:initial;border:1px solid #757575;border-radius:3px;box-shadow:none;box-sizing:border-box;color:#000;display:block;font-family:system-ui;font-size:13px;font-weight:400;line-height:1;margin:0;min-height:30px;padding-bottom:8px;padding-left:8px;padding-top:8px;width:100%}.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{padding-left:4px}.wp-block-legacy-widget__edit-form .widget.open,.wp-block-legacy-widget__edit-form .widget.open:focus-within{z-index:0}.wp-block-legacy-widget__edit-form.wp-block-legacy-widget__edit-form,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{color:#000}.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-preview{cursor:pointer}.wp-block-legacy-widget__edit-no-preview:hover:after,.wp-block-legacy-widget__edit-preview:hover:after{border:1px solid #949494;border-radius:2px;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.wp-block-legacy-widget__edit-preview.is-offscreen{left:-9999px;position:absolute;top:0;width:100%}.wp-block-legacy-widget__edit-preview-iframe{overflow:hidden;width:100%}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{background:#f0f0f0;padding:8px 12px}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3{font-size:14px;font-weight:600;margin:4px 0}.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{margin:4px 0}.wp-block-legacy-widget-inspector-card{padding:0 16px 16px 52px}.interface-complementary-area .wp-block-legacy-widget-inspector-card__name{font-weight:500;margin:0 0 5px}.is-selected .wp-block-legacy-widget__container{min-height:50px;padding:8px 12px}.components-popover__content .wp-block-legacy-widget__edit-form{min-width:400px}.wp-block-widget-group.has-child-selected:after{border:1px solid var(--wp-admin-theme-color);border-radius:2px;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.wp-block-widget-group .widget-title{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:18px;font-weight:600}.wp-block-widget-group__placeholder .block-editor-inserter{width:100%}.is-dark-theme .wp-block-widget-group__placeholder .block-editor-button-block-appender{box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .wp-block-legacy-widget__edit-form{ background:#fff; border:1px solid #1e1e1e; border-radius:2px; max-height:calc(100vh - 2px); overflow-y:scroll; padding:11px; } .wp-block-legacy-widget__edit-form:not([hidden]){ display:flow-root; } .wp-block-legacy-widget__edit-form .wp-block-legacy-widget__edit-form-title{ color:#000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:14px; font-weight:600; margin:0 0 12px; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside{ border:none; box-shadow:none; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside p{ margin:8px 0; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{ font-size:13px; line-height:2.1; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside a,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{ color:#000; font-family:system-ui; font-weight:400; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=date],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime-local],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=email],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=month],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=number],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=password],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=search],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=tel],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=text],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=time],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=url],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=week],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{ background-color:initial; border:1px solid #757575; border-radius:3px; box-shadow:none; box-sizing:border-box; color:#000; display:block; font-family:system-ui; font-size:13px; font-weight:400; line-height:1; margin:0; min-height:30px; padding-bottom:8px; padding-right:8px; padding-top:8px; width:100%; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{ padding-right:4px; } .wp-block-legacy-widget__edit-form .widget.open,.wp-block-legacy-widget__edit-form .widget.open:focus-within{ z-index:0; } .wp-block-legacy-widget__edit-form.wp-block-legacy-widget__edit-form,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{ color:#000; } .wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-preview{ cursor:pointer; } .wp-block-legacy-widget__edit-no-preview:hover:after,.wp-block-legacy-widget__edit-preview:hover:after{ border:1px solid #949494; border-radius:2px; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .wp-block-legacy-widget__edit-preview.is-offscreen{ position:absolute; right:-9999px; top:0; width:100%; } .wp-block-legacy-widget__edit-preview-iframe{ overflow:hidden; width:100%; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{ background:#f0f0f0; padding:8px 12px; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3{ font-size:14px; font-weight:600; margin:4px 0; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{ margin:4px 0; } .wp-block-legacy-widget-inspector-card{ padding:0 52px 16px 16px; } .interface-complementary-area .wp-block-legacy-widget-inspector-card__name{ font-weight:500; margin:0 0 5px; } .is-selected .wp-block-legacy-widget__container{ min-height:50px; padding:8px 12px; } .components-popover__content .wp-block-legacy-widget__edit-form{ min-width:400px; } .wp-block-widget-group.has-child-selected:after{ border:1px solid var(--wp-admin-theme-color); border-radius:2px; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .wp-block-widget-group .widget-title{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:18px; font-weight:600; } .wp-block-widget-group__placeholder .block-editor-inserter{ width:100%; } .is-dark-theme .wp-block-widget-group__placeholder .block-editor-button-block-appender{ box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .wp-block-legacy-widget__edit-form{ background:#fff; border:1px solid #1e1e1e; border-radius:2px; max-height:calc(100vh - 2px); overflow-y:scroll; padding:11px; } .wp-block-legacy-widget__edit-form:not([hidden]){ display:flow-root; } .wp-block-legacy-widget__edit-form .wp-block-legacy-widget__edit-form-title{ color:#000; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:14px; font-weight:600; margin:0 0 12px; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside{ border:none; box-shadow:none; display:block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside p{ margin:8px 0; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{ font-size:13px; line-height:2.1; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside a,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input,.wp-block-legacy-widget__edit-form .widget-inside.widget-inside label{ color:#000; font-family:system-ui; font-weight:400; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=date],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime-local],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=datetime],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=email],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=month],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=number],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=password],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=search],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=tel],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=text],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=time],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=url],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside input[type=week],.wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{ background-color:initial; border:1px solid #757575; border-radius:3px; box-shadow:none; box-sizing:border-box; color:#000; display:block; font-family:system-ui; font-size:13px; font-weight:400; line-height:1; margin:0; min-height:30px; padding-bottom:8px; padding-left:8px; padding-top:8px; width:100%; } .wp-block-legacy-widget__edit-form .widget-inside.widget-inside select{ padding-left:4px; } .wp-block-legacy-widget__edit-form .widget.open,.wp-block-legacy-widget__edit-form .widget.open:focus-within{ z-index:0; } .wp-block-legacy-widget__edit-form.wp-block-legacy-widget__edit-form,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{ color:#000; } .wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-preview{ cursor:pointer; } .wp-block-legacy-widget__edit-no-preview:hover:after,.wp-block-legacy-widget__edit-preview:hover:after{ border:1px solid #949494; border-radius:2px; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .wp-block-legacy-widget__edit-preview.is-offscreen{ left:-9999px; position:absolute; top:0; width:100%; } .wp-block-legacy-widget__edit-preview-iframe{ overflow:hidden; width:100%; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview{ background:#f0f0f0; padding:8px 12px; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3,.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview h3{ font-size:14px; font-weight:600; margin:4px 0; } .wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview.wp-block-legacy-widget__edit-no-preview p{ margin:4px 0; } .wp-block-legacy-widget-inspector-card{ padding:0 16px 16px 52px; } .interface-complementary-area .wp-block-legacy-widget-inspector-card__name{ font-weight:500; margin:0 0 5px; } .is-selected .wp-block-legacy-widget__container{ min-height:50px; padding:8px 12px; } .components-popover__content .wp-block-legacy-widget__edit-form{ min-width:400px; } .wp-block-widget-group.has-child-selected:after{ border:1px solid var(--wp-admin-theme-color); border-radius:2px; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .wp-block-widget-group .widget-title{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:18px; font-weight:600; } .wp-block-widget-group__placeholder .block-editor-inserter{ width:100%; } .is-dark-theme .wp-block-widget-group__placeholder .block-editor-button-block-appender{ box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.patterns-menu-items__convert-modal{z-index:1000001}.patterns-menu-items__convert-modal [role=dialog]>[role=document]{width:350px}.patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories{position:relative}.patterns-menu-items__convert-modal .components-form-token-field__suggestions-list:not(:empty){background-color:#fff;border:1px solid var(--wp-admin-theme-color);border-bottom-left-radius:2px;border-bottom-right-radius:2px;box-shadow:0 0 .5px .5px var(--wp-admin-theme-color);box-sizing:border-box;max-height:96px;min-width:auto;position:absolute;right:-1px;width:calc(100% + 2px);z-index:1}.patterns-create-modal__name-input input[type=text]{margin:0}.patterns-rename-pattern-category-modal__validation-message{color:#cc1818}@media (min-width:782px){.patterns-rename-pattern-category-modal__validation-message{width:320px}}.pattern-overrides-control__allow-overrides-button{justify-content:center;width:100%}.patterns-pattern-overrides-toolbar-indicator__popover .components-popover__content{min-width:260px;padding:16px}.patterns-pattern-overrides-toolbar-indicator .patterns-pattern-overrides-toolbar-indicator-icon.has-colors svg{fill:var(--wp-block-synced-color)}.editor-collapsible-block-toolbar .patterns-pattern-overrides-toolbar-indicator{height:32px}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.patterns-menu-items__convert-modal{z-index:1000001}.patterns-menu-items__convert-modal [role=dialog]>[role=document]{width:350px}.patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories{position:relative}.patterns-menu-items__convert-modal .components-form-token-field__suggestions-list:not(:empty){background-color:#fff;border:1px solid var(--wp-admin-theme-color);border-bottom-left-radius:2px;border-bottom-right-radius:2px;box-shadow:0 0 .5px .5px var(--wp-admin-theme-color);box-sizing:border-box;left:-1px;max-height:96px;min-width:auto;position:absolute;width:calc(100% + 2px);z-index:1}.patterns-create-modal__name-input input[type=text]{margin:0}.patterns-rename-pattern-category-modal__validation-message{color:#cc1818}@media (min-width:782px){.patterns-rename-pattern-category-modal__validation-message{width:320px}}.pattern-overrides-control__allow-overrides-button{justify-content:center;width:100%}.patterns-pattern-overrides-toolbar-indicator__popover .components-popover__content{min-width:260px;padding:16px}.patterns-pattern-overrides-toolbar-indicator .patterns-pattern-overrides-toolbar-indicator-icon.has-colors svg{fill:var(--wp-block-synced-color)}.editor-collapsible-block-toolbar .patterns-pattern-overrides-toolbar-indicator{height:32px}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .patterns-menu-items__convert-modal{ z-index:1000001; } .patterns-menu-items__convert-modal [role=dialog]>[role=document]{ width:350px; } .patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories{ position:relative; } .patterns-menu-items__convert-modal .components-form-token-field__suggestions-list:not(:empty){ background-color:#fff; border:1px solid var(--wp-admin-theme-color); border-bottom-left-radius:2px; border-bottom-right-radius:2px; box-shadow:0 0 .5px .5px var(--wp-admin-theme-color); box-sizing:border-box; max-height:96px; min-width:auto; position:absolute; right:-1px; width:calc(100% + 2px); z-index:1; } .patterns-create-modal__name-input input[type=text]{ margin:0; } .patterns-rename-pattern-category-modal__validation-message{ color:#cc1818; } @media (min-width:782px){ .patterns-rename-pattern-category-modal__validation-message{ width:320px; } } .pattern-overrides-control__allow-overrides-button{ justify-content:center; width:100%; } .patterns-pattern-overrides-toolbar-indicator__popover .components-popover__content{ min-width:260px; padding:16px; } .patterns-pattern-overrides-toolbar-indicator .patterns-pattern-overrides-toolbar-indicator-icon.has-colors svg{ fill:var(--wp-block-synced-color); } .editor-collapsible-block-toolbar .patterns-pattern-overrides-toolbar-indicator{ height:32px; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .patterns-menu-items__convert-modal{ z-index:1000001; } .patterns-menu-items__convert-modal [role=dialog]>[role=document]{ width:350px; } .patterns-menu-items__convert-modal .patterns-menu-items__convert-modal-categories{ position:relative; } .patterns-menu-items__convert-modal .components-form-token-field__suggestions-list:not(:empty){ background-color:#fff; border:1px solid var(--wp-admin-theme-color); border-bottom-left-radius:2px; border-bottom-right-radius:2px; box-shadow:0 0 .5px .5px var(--wp-admin-theme-color); box-sizing:border-box; left:-1px; max-height:96px; min-width:auto; position:absolute; width:calc(100% + 2px); z-index:1; } .patterns-create-modal__name-input input[type=text]{ margin:0; } .patterns-rename-pattern-category-modal__validation-message{ color:#cc1818; } @media (min-width:782px){ .patterns-rename-pattern-category-modal__validation-message{ width:320px; } } .pattern-overrides-control__allow-overrides-button{ justify-content:center; width:100%; } .patterns-pattern-overrides-toolbar-indicator__popover .components-popover__content{ min-width:260px; padding:16px; } .patterns-pattern-overrides-toolbar-indicator .patterns-pattern-overrides-toolbar-indicator-icon.has-colors svg{ fill:var(--wp-block-synced-color); } .editor-collapsible-block-toolbar .patterns-pattern-overrides-toolbar-indicator{ height:32px; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-block-icon{align-items:center;display:flex;height:24px;justify-content:center;width:24px}.block-editor-block-icon.has-colors svg{fill:currentColor}@media (forced-colors:active){.block-editor-block-icon.has-colors svg{fill:CanvasText}}.block-editor-block-icon svg{max-height:24px;max-width:24px;min-height:20px;min-width:20px}.block-editor-block-styles .block-editor-block-list__block{margin:0}@keyframes selection-overlay__fade-in-animation{0%{opacity:0}to{opacity:.4}}:root .block-editor-block-list__layout::selection,:root [data-has-multi-selection=true] .block-editor-block-list__layout::selection,_::-webkit-full-page-media,_:future{background-color:initial}.block-editor-block-list__layout{position:relative}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) ::selection,.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected)::selection{background:#0000}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{background:var(--wp-admin-theme-color);bottom:0;content:"";left:0;opacity:.4;outline:2px solid #0000;pointer-events:none;position:absolute;right:0;top:0;z-index:1}@media not (prefers-reduced-motion){.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{animation:selection-overlay__fade-in-animation .1s ease-out;animation-fill-mode:forwards}}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected).is-highlighted:after{outline-color:#0000}.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus{outline:none}.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted:after,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected:after,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus:after{bottom:0;content:"";left:0;outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);pointer-events:none;position:absolute;right:0;top:0;z-index:1}.block-editor-block-list__layout [class^=components-]{-webkit-user-select:text;user-select:text}.block-editor-block-list__layout .block-editor-block-list__block{overflow-wrap:break-word;pointer-events:auto;position:relative}.block-editor-block-list__layout .block-editor-block-list__block.is-editing-disabled{pointer-events:none}.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.has-child-selected,.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.is-selected{z-index:20}.block-editor-block-list__layout .block-editor-block-list__block .reusable-block-edit-panel *{z-index:1}.block-editor-block-list__layout .block-editor-block-list__block .components-placeholder .components-with-notices-ui{margin:-10px 0 12px}.block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui{margin:0 0 12px;width:100%}.block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui .components-notice .components-notice__content{font-size:13px}.block-editor-block-list__layout .block-editor-block-list__block.has-warning{min-height:48px}.block-editor-block-list__layout .block-editor-block-list__block.has-warning>*{pointer-events:none;-webkit-user-select:none;user-select:none}.block-editor-block-list__layout .block-editor-block-list__block.has-warning .block-editor-warning{pointer-events:all}.block-editor-block-list__layout .block-editor-block-list__block.has-warning:after{background-color:#fff6;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.block-editor-block-list__layout .block-editor-block-list__block.has-warning.is-multi-selected:after{background-color:initial}.block-editor-block-list__layout .block-editor-block-list__block.is-reusable.has-child-selected:after{box-shadow:0 0 0 1px var(--wp-admin-theme-color)}.block-editor-block-list__layout .block-editor-block-list__block[data-clear=true]{float:none}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected{cursor:default}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered.rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected.rich-text{cursor:auto}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered:not(.is-selected):after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline):not(.rich-text):not([contenteditable=true]).is-selected:after{bottom:0;content:"";left:0;outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);pointer-events:none;position:absolute;right:0;top:0}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{outline-color:var(--wp-block-synced-color)}@keyframes block-editor-is-editable__animation{0%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}to{background-color:rgba(var(--wp-admin-theme-color--rgb),0)}}@keyframes block-editor-is-editable__animation_reduce-motion{0%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}99%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}to{background-color:rgba(var(--wp-admin-theme-color--rgb),0)}}.is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{animation-delay:.1s;animation-duration:.8s;animation-fill-mode:backwards;animation-name:block-editor-is-editable__animation;animation-timing-function:ease-out;bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0}@media (prefers-reduced-motion:reduce){.is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{animation-delay:0s;animation-name:block-editor-is-editable__animation_reduce-motion}}.is-focus-mode .block-editor-block-list__block:not(.has-child-selected){opacity:.2}@media not (prefers-reduced-motion){.is-focus-mode .block-editor-block-list__block:not(.has-child-selected){transition:opacity .1s linear}}.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected) .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-multi-selected,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-selected{opacity:1}.wp-block.alignleft,.wp-block.alignright,.wp-block[data-align=left]>*,.wp-block[data-align=right]>*{z-index:21}.wp-site-blocks>[data-align=left]{float:right;margin-left:2em}.wp-site-blocks>[data-align=right]{float:left;margin-right:2em}.wp-site-blocks>[data-align=center]{justify-content:center;margin-left:auto;margin-right:auto}.block-editor-block-list .block-editor-inserter{cursor:move;cursor:grab;margin:8px}@keyframes block-editor-inserter__toggle__fade-in-animation{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.wp-block .block-list-appender .block-editor-inserter__toggle{animation:block-editor-inserter__toggle__fade-in-animation .1s ease;animation-fill-mode:forwards}}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender{display:none}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender .block-editor-inserter__toggle{opacity:0;transform:scale(0)}.block-editor-block-list__block .block-editor-block-list__block-html-textarea{border:none;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;display:block;font-family:Menlo,Consolas,monaco,monospace;font-size:15px;line-height:1.5;margin:0;outline:none;overflow:hidden;padding:12px;resize:none;width:100%}@media not (prefers-reduced-motion){.block-editor-block-list__block .block-editor-block-list__block-html-textarea{transition:padding .2s linear}}.block-editor-block-list__block .block-editor-block-list__block-html-textarea:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-block-list__block .block-editor-warning{position:relative;z-index:5}.block-editor-block-list__block .block-editor-warning.block-editor-block-list__block-crash-warning{margin-bottom:auto}.block-editor-block-list__zoom-out-separator{align-items:center;background:#ddd;color:#000;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:400;justify-content:center;margin-left:-1px;margin-right:-1px;overflow:hidden}@media not (prefers-reduced-motion){.block-editor-block-list__zoom-out-separator{transition:background-color .3s ease}}.is-zoomed-out .block-editor-block-list__zoom-out-separator{font-size:calc(13px/var(--wp-block-editor-iframe-zoom-out-scale))}.block-editor-block-list__zoom-out-separator.is-dragged-over{background:#ccc}.block-editor-block-list__layout.is-root-container.has-global-padding>.block-editor-block-list__zoom-out-separator,.has-global-padding>.block-editor-block-list__zoom-out-separator{margin:0 calc(var(--wp--style--root--padding-left)*-1 - 1px) 0 calc(var(--wp--style--root--padding-right)*-1 - 1px)!important;max-width:none}.is-dragging{cursor:grabbing}.is-vertical .block-list-appender{margin-left:auto;margin-right:12px;margin-top:12px;width:24px}.block-list-appender>.block-editor-inserter{display:block}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected):not(.block-editor-block-list__layout) .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle{opacity:0;transform:scale(0)}.block-editor-block-list__block.has-block-overlay{cursor:default}.block-editor-block-list__block.has-block-overlay .block-editor-block-list__block{pointer-events:none}.block-editor-block-list__block.has-block-overlay .block-editor-block-list__block.has-block-overlay:before{left:0;right:0;width:auto}.block-editor-block-list__layout .is-dragging{border-radius:2px!important;opacity:.1!important}.block-editor-block-list__layout .is-dragging iframe{pointer-events:none}.block-editor-block-list__layout .is-dragging::selection{background:#0000!important}.block-editor-block-list__layout .is-dragging:after{content:none!important}.wp-block img:not([draggable]),.wp-block svg:not([draggable]){pointer-events:none}.block-editor-block-preview__content-iframe .block-list-appender{display:none}.block-editor-block-preview__live-content *{pointer-events:none}.block-editor-block-preview__live-content .block-list-appender{display:none}.block-editor-block-preview__live-content .components-button:disabled{opacity:1}.block-editor-block-preview__live-content .block-editor-block-list__block[data-empty=true],.block-editor-block-preview__live-content .components-placeholder{display:none}.block-editor-block-variation-picker__skip,.block-editor-block-variation-picker__variations,.wp-block-group-placeholder__variations{display:flex;flex-direction:row;flex-wrap:wrap;font-size:12px;gap:8px;justify-content:flex-start;list-style:none;margin:0;padding:0;width:100%}.block-editor-block-variation-picker__skip svg,.block-editor-block-variation-picker__variations svg,.wp-block-group-placeholder__variations svg{fill:#949494!important}.block-editor-block-variation-picker__skip .components-button,.block-editor-block-variation-picker__variations .components-button,.wp-block-group-placeholder__variations .components-button{padding:4px}.block-editor-block-variation-picker__skip .components-button:hover,.block-editor-block-variation-picker__variations .components-button:hover,.wp-block-group-placeholder__variations .components-button:hover{background:none!important}.block-editor-block-variation-picker__skip .components-button:hover svg,.block-editor-block-variation-picker__variations .components-button:hover svg,.wp-block-group-placeholder__variations .components-button:hover svg{fill:var(--wp-admin-theme-color)!important}.block-editor-block-variation-picker__skip>li,.block-editor-block-variation-picker__variations>li,.wp-block-group-placeholder__variations>li{align-items:center;display:flex;flex-direction:column;gap:4px;width:auto}.block-editor-button-block-appender{align-items:center;box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e;display:flex;flex-direction:column;height:auto;justify-content:center;width:100%}.is-dark-theme .block-editor-button-block-appender{box-shadow:inset 0 0 0 1px #ffffffa6;color:#ffffffa6}.block-editor-button-block-appender:hover{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);color:var(--wp-admin-theme-color)}.block-editor-button-block-appender:focus{box-shadow:inset 0 0 0 2px var(--wp-admin-theme-color)}.block-editor-button-block-appender:active{color:#000}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child{pointer-events:none}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after{border:1px dashed;bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter{opacity:0}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within{opacity:1}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after{border:none}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter{visibility:visible}.block-editor-block-list__block:not(.is-selected)>.block-editor-block-list__block>.block-list-appender:only-child:after{border:none}.block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{background-color:var(--wp-admin-theme-color);box-shadow:inset 0 0 0 1px #ffffffa6;color:#ffffffa6}@media not (prefers-reduced-motion){.block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{transition:background-color .2s ease-in-out}}.block-editor-default-block-appender{clear:both;margin-left:auto;margin-right:auto;position:relative}.block-editor-default-block-appender[data-root-client-id=""] .block-editor-default-block-appender__content:hover{outline:1px solid #0000}.block-editor-default-block-appender .block-editor-default-block-appender__content{margin-block-end:0;margin-block-start:0;opacity:.62}.block-editor-default-block-appender .components-drop-zone__content-icon{display:none}.block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon{background:#1e1e1e;color:#fff;height:24px;min-width:24px;padding:0}.block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-default-block-appender .block-editor-inserter{left:0;line-height:0;position:absolute;top:0}.block-editor-default-block-appender .block-editor-inserter:disabled{display:none}.block-editor-block-list__block .block-list-appender{bottom:0;left:0;list-style:none;padding:0;position:absolute;z-index:2}.block-editor-block-list__block .block-list-appender.block-list-appender{line-height:0;margin:0}.block-editor-block-list__block .block-list-appender .block-editor-inserter:disabled{display:none}.block-editor-block-list__block .block-list-appender .block-editor-default-block-appender{height:24px}.block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle{background:#1e1e1e;box-shadow:none;color:#fff;display:none;flex-direction:row;height:24px;min-width:24px;padding:0!important;width:24px}.block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-block-list__block .block-list-appender .block-editor-default-block-appender__content{display:none}.block-editor-block-list__block .block-list-appender:only-child{align-self:center;left:auto;line-height:inherit;list-style:none;position:relative}.block-editor-block-list__block .block-list-appender:only-child .block-editor-default-block-appender__content{display:block}.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle,.block-editor-block-list__block.is-selected>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected>.block-list-appender .block-list-appender__toggle{display:flex}.block-editor-default-block-appender__content{cursor:text}.block-editor-iframe__body{position:relative}.block-editor-iframe__html{transform-origin:top center}@media not (prefers-reduced-motion){.block-editor-iframe__html{transition:background-color .4s}}.block-editor-iframe__html.zoom-out-animation{bottom:0;left:0;overflow-y:var(--wp-block-editor-iframe-zoom-out-overflow-behavior,scroll);position:fixed;right:0;top:calc(var(--wp-block-editor-iframe-zoom-out-scroll-top, 0)*-1)}.block-editor-iframe__html.is-zoomed-out{background-color:#ddd;margin-bottom:calc(var(--wp-block-editor-iframe-zoom-out-content-height)*(1 - var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1 + var(--wp-block-editor-iframe-zoom-out-frame-size, 0)*2/var(--wp-block-editor-iframe-zoom-out-scale, 1)*-1 + -2px);padding-bottom:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1));padding-top:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1));scale:var(--wp-block-editor-iframe-zoom-out-scale,1);transform:translateX(calc(((var(--wp-block-editor-iframe-zoom-out-scale-container-width) - var(--wp-block-editor-iframe-zoom-out-container-width, 100vw))/2/var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1))}.block-editor-iframe__html.is-zoomed-out body{min-height:calc((var(--wp-block-editor-iframe-zoom-out-inner-height) - 2*var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1))/var(--wp-block-editor-iframe-zoom-out-scale, 1))}.block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content){display:flex;flex:1;flex-direction:column;height:100%}.block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content)>main{flex:1}.block-editor-iframe__html.is-zoomed-out .wp-block[draggable]{cursor:grab}.block-editor-media-placeholder__cancel-button.is-link{display:block;margin:1em}.block-editor-media-placeholder.is-appender{min-height:0}.block-editor-media-placeholder.is-appender:hover{box-shadow:0 0 0 1px var(--wp-admin-theme-color);cursor:pointer}.block-editor-plain-text{border:none;box-shadow:none;color:inherit;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;padding:0;width:100%}.rich-text [data-rich-text-placeholder]{pointer-events:none}.rich-text [data-rich-text-placeholder]:after{content:attr(data-rich-text-placeholder);opacity:.62}.rich-text:focus{outline:none}figcaption.block-editor-rich-text__editable [data-rich-text-placeholder]:before{opacity:.8}[data-rich-text-script]{display:inline}[data-rich-text-script]:before{background:#ff0;content:"</>"}[data-rich-text-comment],[data-rich-text-format-boundary]{border-radius:2px}[data-rich-text-comment]{background-color:currentColor}[data-rich-text-comment] span{color:currentColor;filter:invert(100%);padding:0 2px}.block-editor-warning{align-items:center;background-color:#fff;border:1px solid #1e1e1e;border-radius:2px;display:flex;flex-wrap:wrap;padding:1em}.block-editor-warning,.block-editor-warning .block-editor-warning__message{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.block-editor-warning .block-editor-warning__message{color:#1e1e1e;font-size:13px;line-height:1.4;margin:0}.block-editor-warning p.block-editor-warning__message.block-editor-warning__message{min-height:auto}.block-editor-warning .block-editor-warning__contents{align-items:baseline;display:flex;flex-direction:row;flex-wrap:wrap;gap:12px;justify-content:space-between;width:100%}.block-editor-warning .block-editor-warning__actions{align-items:center;display:flex;gap:8px}.components-popover.block-editor-warning__dropdown{z-index:99998}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-block-icon{ align-items:center; display:flex; height:24px; justify-content:center; width:24px; } .block-editor-block-icon.has-colors svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-block-icon.has-colors svg{ fill:CanvasText; } } .block-editor-block-icon svg{ max-height:24px; max-width:24px; min-height:20px; min-width:20px; } .block-editor-block-styles .block-editor-block-list__block{ margin:0; } @keyframes selection-overlay__fade-in-animation{ 0%{ opacity:0; } to{ opacity:.4; } } :root .block-editor-block-list__layout::selection,:root [data-has-multi-selection=true] .block-editor-block-list__layout::selection,_::-webkit-full-page-media,_:future{ background-color:initial; } .block-editor-block-list__layout{ position:relative; } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) ::selection,.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected)::selection{ background:#0000; } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{ background:var(--wp-admin-theme-color); bottom:0; content:""; left:0; opacity:.4; outline:2px solid #0000; pointer-events:none; position:absolute; right:0; top:0; z-index:1; } @media not (prefers-reduced-motion){ .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{ animation:selection-overlay__fade-in-animation .1s ease-out; animation-fill-mode:forwards; } } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected).is-highlighted:after{ outline-color:#0000; } .block-editor-block-list__layout .block-editor-block-list__block.is-highlighted,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus{ outline:none; } .block-editor-block-list__layout .block-editor-block-list__block.is-highlighted:after,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected:after,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus:after{ bottom:0; content:""; left:0; outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); pointer-events:none; position:absolute; right:0; top:0; z-index:1; } .block-editor-block-list__layout [class^=components-]{ -webkit-user-select:text; user-select:text; } .block-editor-block-list__layout .block-editor-block-list__block{ overflow-wrap:break-word; pointer-events:auto; position:relative; } .block-editor-block-list__layout .block-editor-block-list__block.is-editing-disabled{ pointer-events:none; } .block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.has-child-selected,.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.is-selected{ z-index:20; } .block-editor-block-list__layout .block-editor-block-list__block .reusable-block-edit-panel *{ z-index:1; } .block-editor-block-list__layout .block-editor-block-list__block .components-placeholder .components-with-notices-ui{ margin:-10px 0 12px; } .block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui{ margin:0 0 12px; width:100%; } .block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui .components-notice .components-notice__content{ font-size:13px; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning{ min-height:48px; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning>*{ pointer-events:none; -webkit-user-select:none; user-select:none; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning .block-editor-warning{ pointer-events:all; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning:after{ background-color:#fff6; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning.is-multi-selected:after{ background-color:initial; } .block-editor-block-list__layout .block-editor-block-list__block.is-reusable.has-child-selected:after{ box-shadow:0 0 0 1px var(--wp-admin-theme-color); } .block-editor-block-list__layout .block-editor-block-list__block[data-clear=true]{ float:none; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected{ cursor:default; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered.rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected.rich-text{ cursor:auto; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered:not(.is-selected):after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline):not(.rich-text):not([contenteditable=true]).is-selected:after{ bottom:0; content:""; left:0; outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); pointer-events:none; position:absolute; right:0; top:0; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{ outline-color:var(--wp-block-synced-color); } @keyframes block-editor-is-editable__animation{ 0%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } to{ background-color:rgba(var(--wp-admin-theme-color--rgb), 0); } } @keyframes block-editor-is-editable__animation_reduce-motion{ 0%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } 99%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } to{ background-color:rgba(var(--wp-admin-theme-color--rgb), 0); } } .is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{ animation-delay:.1s; animation-duration:.8s; animation-fill-mode:backwards; animation-name:block-editor-is-editable__animation; animation-timing-function:ease-out; bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; } @media (prefers-reduced-motion:reduce){ .is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{ animation-delay:0s; animation-name:block-editor-is-editable__animation_reduce-motion; } } .is-focus-mode .block-editor-block-list__block:not(.has-child-selected){ opacity:.2; } @media not (prefers-reduced-motion){ .is-focus-mode .block-editor-block-list__block:not(.has-child-selected){ transition:opacity .1s linear; } } .is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected) .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-multi-selected,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-selected{ opacity:1; } .wp-block.alignleft,.wp-block.alignright,.wp-block[data-align=left]>*,.wp-block[data-align=right]>*{ z-index:21; } .wp-site-blocks>[data-align=left]{ float:right; margin-left:2em; } .wp-site-blocks>[data-align=right]{ float:left; margin-right:2em; } .wp-site-blocks>[data-align=center]{ justify-content:center; margin-left:auto; margin-right:auto; } .block-editor-block-list .block-editor-inserter{ cursor:move; cursor:grab; margin:8px; } @keyframes block-editor-inserter__toggle__fade-in-animation{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .wp-block .block-list-appender .block-editor-inserter__toggle{ animation:block-editor-inserter__toggle__fade-in-animation .1s ease; animation-fill-mode:forwards; } } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender{ display:none; } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender .block-editor-inserter__toggle{ opacity:0; transform:scale(0); } .block-editor-block-list__block .block-editor-block-list__block-html-textarea{ border:none; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; display:block; font-family:Menlo,Consolas,monaco,monospace; font-size:15px; line-height:1.5; margin:0; outline:none; overflow:hidden; padding:12px; resize:none; width:100%; } @media not (prefers-reduced-motion){ .block-editor-block-list__block .block-editor-block-list__block-html-textarea{ transition:padding .2s linear; } } .block-editor-block-list__block .block-editor-block-list__block-html-textarea:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-block-list__block .block-editor-warning{ position:relative; z-index:5; } .block-editor-block-list__block .block-editor-warning.block-editor-block-list__block-crash-warning{ margin-bottom:auto; } .block-editor-block-list__zoom-out-separator{ align-items:center; background:#ddd; color:#000; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:400; justify-content:center; margin-left:-1px; margin-right:-1px; overflow:hidden; } @media not (prefers-reduced-motion){ .block-editor-block-list__zoom-out-separator{ transition:background-color .3s ease; } } .is-zoomed-out .block-editor-block-list__zoom-out-separator{ font-size:calc(13px/var(--wp-block-editor-iframe-zoom-out-scale)); } .block-editor-block-list__zoom-out-separator.is-dragged-over{ background:#ccc; } .block-editor-block-list__layout.is-root-container.has-global-padding>.block-editor-block-list__zoom-out-separator,.has-global-padding>.block-editor-block-list__zoom-out-separator{ margin:0 calc(var(--wp--style--root--padding-left)*-1 - 1px) 0 calc(var(--wp--style--root--padding-right)*-1 - 1px) !important; max-width:none; } .is-dragging{ cursor:grabbing; } .is-vertical .block-list-appender{ margin-left:auto; margin-right:12px; margin-top:12px; width:24px; } .block-list-appender>.block-editor-inserter{ display:block; } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected):not(.block-editor-block-list__layout) .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle{ opacity:0; transform:scale(0); } .block-editor-block-list__block.has-block-overlay{ cursor:default; } .block-editor-block-list__block.has-block-overlay .block-editor-block-list__block{ pointer-events:none; } .block-editor-block-list__block.has-block-overlay .block-editor-block-list__block.has-block-overlay:before{ left:0; right:0; width:auto; } .block-editor-block-list__layout .is-dragging{ border-radius:2px !important; opacity:.1 !important; } .block-editor-block-list__layout .is-dragging iframe{ pointer-events:none; } .block-editor-block-list__layout .is-dragging::selection{ background:#0000 !important; } .block-editor-block-list__layout .is-dragging:after{ content:none !important; } .wp-block img:not([draggable]),.wp-block svg:not([draggable]){ pointer-events:none; } .block-editor-block-preview__content-iframe .block-list-appender{ display:none; } .block-editor-block-preview__live-content *{ pointer-events:none; } .block-editor-block-preview__live-content .block-list-appender{ display:none; } .block-editor-block-preview__live-content .components-button:disabled{ opacity:1; } .block-editor-block-preview__live-content .block-editor-block-list__block[data-empty=true],.block-editor-block-preview__live-content .components-placeholder{ display:none; } .block-editor-block-variation-picker__skip,.block-editor-block-variation-picker__variations,.wp-block-group-placeholder__variations{ display:flex; flex-direction:row; flex-wrap:wrap; font-size:12px; gap:8px; justify-content:flex-start; list-style:none; margin:0; padding:0; width:100%; } .block-editor-block-variation-picker__skip svg,.block-editor-block-variation-picker__variations svg,.wp-block-group-placeholder__variations svg{ fill:#949494 !important; } .block-editor-block-variation-picker__skip .components-button,.block-editor-block-variation-picker__variations .components-button,.wp-block-group-placeholder__variations .components-button{ padding:4px; } .block-editor-block-variation-picker__skip .components-button:hover,.block-editor-block-variation-picker__variations .components-button:hover,.wp-block-group-placeholder__variations .components-button:hover{ background:none !important; } .block-editor-block-variation-picker__skip .components-button:hover svg,.block-editor-block-variation-picker__variations .components-button:hover svg,.wp-block-group-placeholder__variations .components-button:hover svg{ fill:var(--wp-admin-theme-color) !important; } .block-editor-block-variation-picker__skip>li,.block-editor-block-variation-picker__variations>li,.wp-block-group-placeholder__variations>li{ align-items:center; display:flex; flex-direction:column; gap:4px; width:auto; } .block-editor-button-block-appender{ align-items:center; box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; display:flex; flex-direction:column; height:auto; justify-content:center; width:100%; } .is-dark-theme .block-editor-button-block-appender{ box-shadow:inset 0 0 0 1px #ffffffa6; color:#ffffffa6; } .block-editor-button-block-appender:hover{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); color:var(--wp-admin-theme-color); } .block-editor-button-block-appender:focus{ box-shadow:inset 0 0 0 2px var(--wp-admin-theme-color); } .block-editor-button-block-appender:active{ color:#000; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child{ pointer-events:none; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after{ border:1px dashed; bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter{ opacity:0; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within{ opacity:1; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after{ border:none; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter{ visibility:visible; } .block-editor-block-list__block:not(.is-selected)>.block-editor-block-list__block>.block-list-appender:only-child:after{ border:none; } .block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{ background-color:var(--wp-admin-theme-color); box-shadow:inset 0 0 0 1px #ffffffa6; color:#ffffffa6; } @media not (prefers-reduced-motion){ .block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{ transition:background-color .2s ease-in-out; } } .block-editor-default-block-appender{ clear:both; margin-left:auto; margin-right:auto; position:relative; } .block-editor-default-block-appender[data-root-client-id=""] .block-editor-default-block-appender__content:hover{ outline:1px solid #0000; } .block-editor-default-block-appender .block-editor-default-block-appender__content{ margin-block-end:0; margin-block-start:0; opacity:.62; } .block-editor-default-block-appender .components-drop-zone__content-icon{ display:none; } .block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon{ background:#1e1e1e; color:#fff; height:24px; min-width:24px; padding:0; } .block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-default-block-appender .block-editor-inserter{ left:0; line-height:0; position:absolute; top:0; } .block-editor-default-block-appender .block-editor-inserter:disabled{ display:none; } .block-editor-block-list__block .block-list-appender{ bottom:0; left:0; list-style:none; padding:0; position:absolute; z-index:2; } .block-editor-block-list__block .block-list-appender.block-list-appender{ line-height:0; margin:0; } .block-editor-block-list__block .block-list-appender .block-editor-inserter:disabled{ display:none; } .block-editor-block-list__block .block-list-appender .block-editor-default-block-appender{ height:24px; } .block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle{ background:#1e1e1e; box-shadow:none; color:#fff; display:none; flex-direction:row; height:24px; min-width:24px; padding:0 !important; width:24px; } .block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-block-list__block .block-list-appender .block-editor-default-block-appender__content{ display:none; } .block-editor-block-list__block .block-list-appender:only-child{ align-self:center; left:auto; line-height:inherit; list-style:none; position:relative; } .block-editor-block-list__block .block-list-appender:only-child .block-editor-default-block-appender__content{ display:block; } .block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle,.block-editor-block-list__block.is-selected>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected>.block-list-appender .block-list-appender__toggle{ display:flex; } .block-editor-default-block-appender__content{ cursor:text; } .block-editor-iframe__body{ position:relative; } .block-editor-iframe__html{ transform-origin:top center; } @media not (prefers-reduced-motion){ .block-editor-iframe__html{ transition:background-color .4s; } } .block-editor-iframe__html.zoom-out-animation{ bottom:0; left:0; overflow-y:var(--wp-block-editor-iframe-zoom-out-overflow-behavior, scroll); position:fixed; right:0; top:calc(var(--wp-block-editor-iframe-zoom-out-scroll-top, 0)*-1); } .block-editor-iframe__html.is-zoomed-out{ background-color:#ddd; margin-bottom:calc(var(--wp-block-editor-iframe-zoom-out-content-height)*(1 - var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1 + var(--wp-block-editor-iframe-zoom-out-frame-size, 0)*2/var(--wp-block-editor-iframe-zoom-out-scale, 1)*-1 + -2px); padding-bottom:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1)); padding-top:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1)); scale:var(--wp-block-editor-iframe-zoom-out-scale, 1); transform:translateX(calc(((var(--wp-block-editor-iframe-zoom-out-scale-container-width) - var(--wp-block-editor-iframe-zoom-out-container-width, 100vw))/2/var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1)); } .block-editor-iframe__html.is-zoomed-out body{ min-height:calc((var(--wp-block-editor-iframe-zoom-out-inner-height) - 2*var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1))/var(--wp-block-editor-iframe-zoom-out-scale, 1)); } .block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content){ display:flex; flex:1; flex-direction:column; height:100%; } .block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content)>main{ flex:1; } .block-editor-iframe__html.is-zoomed-out .wp-block[draggable]{ cursor:grab; } .block-editor-media-placeholder__cancel-button.is-link{ display:block; margin:1em; } .block-editor-media-placeholder.is-appender{ min-height:0; } .block-editor-media-placeholder.is-appender:hover{ box-shadow:0 0 0 1px var(--wp-admin-theme-color); cursor:pointer; } .block-editor-plain-text{ border:none; box-shadow:none; color:inherit; font-family:inherit; font-size:inherit; line-height:inherit; margin:0; padding:0; width:100%; } .rich-text [data-rich-text-placeholder]{ pointer-events:none; } .rich-text [data-rich-text-placeholder]:after{ content:attr(data-rich-text-placeholder); opacity:.62; } .rich-text:focus{ outline:none; } figcaption.block-editor-rich-text__editable [data-rich-text-placeholder]:before{ opacity:.8; } [data-rich-text-script]{ display:inline; } [data-rich-text-script]:before{ background:#ff0; content:"</>"; } [data-rich-text-comment],[data-rich-text-format-boundary]{ border-radius:2px; } [data-rich-text-comment]{ background-color:currentColor; } [data-rich-text-comment] span{ color:currentColor; filter:invert(100%); padding:0 2px; } .block-editor-warning{ align-items:center; background-color:#fff; border:1px solid #1e1e1e; border-radius:2px; display:flex; flex-wrap:wrap; padding:1em; } .block-editor-warning,.block-editor-warning .block-editor-warning__message{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; } .block-editor-warning .block-editor-warning__message{ color:#1e1e1e; font-size:13px; line-height:1.4; margin:0; } .block-editor-warning p.block-editor-warning__message.block-editor-warning__message{ min-height:auto; } .block-editor-warning .block-editor-warning__contents{ align-items:baseline; display:flex; flex-direction:row; flex-wrap:wrap; gap:12px; justify-content:space-between; width:100%; } .block-editor-warning .block-editor-warning__actions{ align-items:center; display:flex; gap:8px; } .components-popover.block-editor-warning__dropdown{ z-index:99998; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:18px;line-height:1.5;--wp--style--block-gap:2em}p{line-height:1.8}.editor-post-title__block{font-size:2.5em;font-weight:800;margin-bottom:1em;margin-top:2em}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-block-icon{ align-items:center; display:flex; height:24px; justify-content:center; width:24px; } .block-editor-block-icon.has-colors svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-block-icon.has-colors svg{ fill:CanvasText; } } .block-editor-block-icon svg{ max-height:24px; max-width:24px; min-height:20px; min-width:20px; } .block-editor-block-styles .block-editor-block-list__block{ margin:0; } @keyframes selection-overlay__fade-in-animation{ 0%{ opacity:0; } to{ opacity:.4; } } :root .block-editor-block-list__layout::selection,:root [data-has-multi-selection=true] .block-editor-block-list__layout::selection,_::-webkit-full-page-media,_:future{ background-color:initial; } .block-editor-block-list__layout{ position:relative; } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) ::selection,.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected)::selection{ background:#0000; } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{ background:var(--wp-admin-theme-color); bottom:0; content:""; left:0; opacity:.4; outline:2px solid #0000; pointer-events:none; position:absolute; right:0; top:0; z-index:1; } @media not (prefers-reduced-motion){ .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{ animation:selection-overlay__fade-in-animation .1s ease-out; animation-fill-mode:forwards; } } .block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected).is-highlighted:after{ outline-color:#0000; } .block-editor-block-list__layout .block-editor-block-list__block.is-highlighted,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus{ outline:none; } .block-editor-block-list__layout .block-editor-block-list__block.is-highlighted:after,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected:after,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus:after{ bottom:0; content:""; left:0; outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); pointer-events:none; position:absolute; right:0; top:0; z-index:1; } .block-editor-block-list__layout [class^=components-]{ -webkit-user-select:text; user-select:text; } .block-editor-block-list__layout .block-editor-block-list__block{ overflow-wrap:break-word; pointer-events:auto; position:relative; } .block-editor-block-list__layout .block-editor-block-list__block.is-editing-disabled{ pointer-events:none; } .block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.has-child-selected,.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.is-selected{ z-index:20; } .block-editor-block-list__layout .block-editor-block-list__block .reusable-block-edit-panel *{ z-index:1; } .block-editor-block-list__layout .block-editor-block-list__block .components-placeholder .components-with-notices-ui{ margin:-10px 0 12px; } .block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui{ margin:0 0 12px; width:100%; } .block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui .components-notice .components-notice__content{ font-size:13px; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning{ min-height:48px; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning>*{ pointer-events:none; -webkit-user-select:none; user-select:none; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning .block-editor-warning{ pointer-events:all; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning:after{ background-color:#fff6; bottom:0; content:""; left:0; position:absolute; right:0; top:0; } .block-editor-block-list__layout .block-editor-block-list__block.has-warning.is-multi-selected:after{ background-color:initial; } .block-editor-block-list__layout .block-editor-block-list__block.is-reusable.has-child-selected:after{ box-shadow:0 0 0 1px var(--wp-admin-theme-color); } .block-editor-block-list__layout .block-editor-block-list__block[data-clear=true]{ float:none; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected{ cursor:default; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered.rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected.rich-text{ cursor:auto; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered:not(.is-selected):after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline):not(.rich-text):not([contenteditable=true]).is-selected:after{ bottom:0; content:""; left:0; outline-color:var(--wp-admin-theme-color); outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); outline-style:solid; outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1); pointer-events:none; position:absolute; right:0; top:0; } .is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{ outline-color:var(--wp-block-synced-color); } @keyframes block-editor-is-editable__animation{ 0%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } to{ background-color:rgba(var(--wp-admin-theme-color--rgb), 0); } } @keyframes block-editor-is-editable__animation_reduce-motion{ 0%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } 99%{ background-color:rgba(var(--wp-admin-theme-color--rgb), .1); } to{ background-color:rgba(var(--wp-admin-theme-color--rgb), 0); } } .is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{ animation-delay:.1s; animation-duration:.8s; animation-fill-mode:backwards; animation-name:block-editor-is-editable__animation; animation-timing-function:ease-out; bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; } @media (prefers-reduced-motion:reduce){ .is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{ animation-delay:0s; animation-name:block-editor-is-editable__animation_reduce-motion; } } .is-focus-mode .block-editor-block-list__block:not(.has-child-selected){ opacity:.2; } @media not (prefers-reduced-motion){ .is-focus-mode .block-editor-block-list__block:not(.has-child-selected){ transition:opacity .1s linear; } } .is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected) .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-multi-selected,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-selected{ opacity:1; } .wp-block.alignleft,.wp-block.alignright,.wp-block[data-align=left]>*,.wp-block[data-align=right]>*{ z-index:21; } .wp-site-blocks>[data-align=left]{ float:left; margin-right:2em; } .wp-site-blocks>[data-align=right]{ float:right; margin-left:2em; } .wp-site-blocks>[data-align=center]{ justify-content:center; margin-left:auto; margin-right:auto; } .block-editor-block-list .block-editor-inserter{ cursor:move; cursor:grab; margin:8px; } @keyframes block-editor-inserter__toggle__fade-in-animation{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .wp-block .block-list-appender .block-editor-inserter__toggle{ animation:block-editor-inserter__toggle__fade-in-animation .1s ease; animation-fill-mode:forwards; } } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender{ display:none; } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender .block-editor-inserter__toggle{ opacity:0; transform:scale(0); } .block-editor-block-list__block .block-editor-block-list__block-html-textarea{ border:none; border-radius:2px; box-shadow:inset 0 0 0 1px #1e1e1e; display:block; font-family:Menlo,Consolas,monaco,monospace; font-size:15px; line-height:1.5; margin:0; outline:none; overflow:hidden; padding:12px; resize:none; width:100%; } @media not (prefers-reduced-motion){ .block-editor-block-list__block .block-editor-block-list__block-html-textarea{ transition:padding .2s linear; } } .block-editor-block-list__block .block-editor-block-list__block-html-textarea:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-block-list__block .block-editor-warning{ position:relative; z-index:5; } .block-editor-block-list__block .block-editor-warning.block-editor-block-list__block-crash-warning{ margin-bottom:auto; } .block-editor-block-list__zoom-out-separator{ align-items:center; background:#ddd; color:#000; display:flex; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; font-weight:400; justify-content:center; margin-left:-1px; margin-right:-1px; overflow:hidden; } @media not (prefers-reduced-motion){ .block-editor-block-list__zoom-out-separator{ transition:background-color .3s ease; } } .is-zoomed-out .block-editor-block-list__zoom-out-separator{ font-size:calc(13px/var(--wp-block-editor-iframe-zoom-out-scale)); } .block-editor-block-list__zoom-out-separator.is-dragged-over{ background:#ccc; } .block-editor-block-list__layout.is-root-container.has-global-padding>.block-editor-block-list__zoom-out-separator,.has-global-padding>.block-editor-block-list__zoom-out-separator{ margin:0 calc(var(--wp--style--root--padding-right)*-1 - 1px) 0 calc(var(--wp--style--root--padding-left)*-1 - 1px) !important; max-width:none; } .is-dragging{ cursor:grabbing; } .is-vertical .block-list-appender{ margin-left:12px; margin-right:auto; margin-top:12px; width:24px; } .block-list-appender>.block-editor-inserter{ display:block; } .block-editor-block-list__block:not(.is-selected):not(.has-child-selected):not(.block-editor-block-list__layout) .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle{ opacity:0; transform:scale(0); } .block-editor-block-list__block.has-block-overlay{ cursor:default; } .block-editor-block-list__block.has-block-overlay .block-editor-block-list__block{ pointer-events:none; } .block-editor-block-list__block.has-block-overlay .block-editor-block-list__block.has-block-overlay:before{ left:0; right:0; width:auto; } .block-editor-block-list__layout .is-dragging{ border-radius:2px !important; opacity:.1 !important; } .block-editor-block-list__layout .is-dragging iframe{ pointer-events:none; } .block-editor-block-list__layout .is-dragging::selection{ background:#0000 !important; } .block-editor-block-list__layout .is-dragging:after{ content:none !important; } .wp-block img:not([draggable]),.wp-block svg:not([draggable]){ pointer-events:none; } .block-editor-block-preview__content-iframe .block-list-appender{ display:none; } .block-editor-block-preview__live-content *{ pointer-events:none; } .block-editor-block-preview__live-content .block-list-appender{ display:none; } .block-editor-block-preview__live-content .components-button:disabled{ opacity:1; } .block-editor-block-preview__live-content .block-editor-block-list__block[data-empty=true],.block-editor-block-preview__live-content .components-placeholder{ display:none; } .block-editor-block-variation-picker__skip,.block-editor-block-variation-picker__variations,.wp-block-group-placeholder__variations{ display:flex; flex-direction:row; flex-wrap:wrap; font-size:12px; gap:8px; justify-content:flex-start; list-style:none; margin:0; padding:0; width:100%; } .block-editor-block-variation-picker__skip svg,.block-editor-block-variation-picker__variations svg,.wp-block-group-placeholder__variations svg{ fill:#949494 !important; } .block-editor-block-variation-picker__skip .components-button,.block-editor-block-variation-picker__variations .components-button,.wp-block-group-placeholder__variations .components-button{ padding:4px; } .block-editor-block-variation-picker__skip .components-button:hover,.block-editor-block-variation-picker__variations .components-button:hover,.wp-block-group-placeholder__variations .components-button:hover{ background:none !important; } .block-editor-block-variation-picker__skip .components-button:hover svg,.block-editor-block-variation-picker__variations .components-button:hover svg,.wp-block-group-placeholder__variations .components-button:hover svg{ fill:var(--wp-admin-theme-color) !important; } .block-editor-block-variation-picker__skip>li,.block-editor-block-variation-picker__variations>li,.wp-block-group-placeholder__variations>li{ align-items:center; display:flex; flex-direction:column; gap:4px; width:auto; } .block-editor-button-block-appender{ align-items:center; box-shadow:inset 0 0 0 1px #1e1e1e; color:#1e1e1e; display:flex; flex-direction:column; height:auto; justify-content:center; width:100%; } .is-dark-theme .block-editor-button-block-appender{ box-shadow:inset 0 0 0 1px #ffffffa6; color:#ffffffa6; } .block-editor-button-block-appender:hover{ box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color); color:var(--wp-admin-theme-color); } .block-editor-button-block-appender:focus{ box-shadow:inset 0 0 0 2px var(--wp-admin-theme-color); } .block-editor-button-block-appender:active{ color:#000; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child{ pointer-events:none; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after{ border:1px dashed; bottom:0; content:""; left:0; pointer-events:none; position:absolute; right:0; top:0; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter{ opacity:0; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within{ opacity:1; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after{ border:none; } .block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter{ visibility:visible; } .block-editor-block-list__block:not(.is-selected)>.block-editor-block-list__block>.block-list-appender:only-child:after{ border:none; } .block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{ background-color:var(--wp-admin-theme-color); box-shadow:inset 0 0 0 1px #ffffffa6; color:#ffffffa6; } @media not (prefers-reduced-motion){ .block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{ transition:background-color .2s ease-in-out; } } .block-editor-default-block-appender{ clear:both; margin-left:auto; margin-right:auto; position:relative; } .block-editor-default-block-appender[data-root-client-id=""] .block-editor-default-block-appender__content:hover{ outline:1px solid #0000; } .block-editor-default-block-appender .block-editor-default-block-appender__content{ margin-block-end:0; margin-block-start:0; opacity:.62; } .block-editor-default-block-appender .components-drop-zone__content-icon{ display:none; } .block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon{ background:#1e1e1e; color:#fff; height:24px; min-width:24px; padding:0; } .block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-default-block-appender .block-editor-inserter{ line-height:0; position:absolute; right:0; top:0; } .block-editor-default-block-appender .block-editor-inserter:disabled{ display:none; } .block-editor-block-list__block .block-list-appender{ bottom:0; list-style:none; padding:0; position:absolute; right:0; z-index:2; } .block-editor-block-list__block .block-list-appender.block-list-appender{ line-height:0; margin:0; } .block-editor-block-list__block .block-list-appender .block-editor-inserter:disabled{ display:none; } .block-editor-block-list__block .block-list-appender .block-editor-default-block-appender{ height:24px; } .block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle{ background:#1e1e1e; box-shadow:none; color:#fff; display:none; flex-direction:row; height:24px; min-width:24px; padding:0 !important; width:24px; } .block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-block-list__block .block-list-appender .block-editor-default-block-appender__content{ display:none; } .block-editor-block-list__block .block-list-appender:only-child{ align-self:center; line-height:inherit; list-style:none; position:relative; right:auto; } .block-editor-block-list__block .block-list-appender:only-child .block-editor-default-block-appender__content{ display:block; } .block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle,.block-editor-block-list__block.is-selected>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected>.block-list-appender .block-list-appender__toggle{ display:flex; } .block-editor-default-block-appender__content{ cursor:text; } .block-editor-iframe__body{ position:relative; } .block-editor-iframe__html{ transform-origin:top center; } @media not (prefers-reduced-motion){ .block-editor-iframe__html{ transition:background-color .4s; } } .block-editor-iframe__html.zoom-out-animation{ bottom:0; left:0; overflow-y:var(--wp-block-editor-iframe-zoom-out-overflow-behavior, scroll); position:fixed; right:0; top:calc(var(--wp-block-editor-iframe-zoom-out-scroll-top, 0)*-1); } .block-editor-iframe__html.is-zoomed-out{ background-color:#ddd; margin-bottom:calc(var(--wp-block-editor-iframe-zoom-out-content-height)*(1 - var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1 + var(--wp-block-editor-iframe-zoom-out-frame-size, 0)*2/var(--wp-block-editor-iframe-zoom-out-scale, 1)*-1 + -2px); padding-bottom:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1)); padding-top:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1)); scale:var(--wp-block-editor-iframe-zoom-out-scale, 1); transform:translateX(calc((var(--wp-block-editor-iframe-zoom-out-scale-container-width) - var(--wp-block-editor-iframe-zoom-out-container-width, 100vw))/2/var(--wp-block-editor-iframe-zoom-out-scale, 1))); } .block-editor-iframe__html.is-zoomed-out body{ min-height:calc((var(--wp-block-editor-iframe-zoom-out-inner-height) - 2*var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1))/var(--wp-block-editor-iframe-zoom-out-scale, 1)); } .block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content){ display:flex; flex:1; flex-direction:column; height:100%; } .block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content)>main{ flex:1; } .block-editor-iframe__html.is-zoomed-out .wp-block[draggable]{ cursor:grab; } .block-editor-media-placeholder__cancel-button.is-link{ display:block; margin:1em; } .block-editor-media-placeholder.is-appender{ min-height:0; } .block-editor-media-placeholder.is-appender:hover{ box-shadow:0 0 0 1px var(--wp-admin-theme-color); cursor:pointer; } .block-editor-plain-text{ border:none; box-shadow:none; color:inherit; font-family:inherit; font-size:inherit; line-height:inherit; margin:0; padding:0; width:100%; } .rich-text [data-rich-text-placeholder]{ pointer-events:none; } .rich-text [data-rich-text-placeholder]:after{ content:attr(data-rich-text-placeholder); opacity:.62; } .rich-text:focus{ outline:none; } figcaption.block-editor-rich-text__editable [data-rich-text-placeholder]:before{ opacity:.8; } [data-rich-text-script]{ display:inline; } [data-rich-text-script]:before{ background:#ff0; content:"</>"; } [data-rich-text-comment],[data-rich-text-format-boundary]{ border-radius:2px; } [data-rich-text-comment]{ background-color:currentColor; } [data-rich-text-comment] span{ color:currentColor; filter:invert(100%); padding:0 2px; } .block-editor-warning{ align-items:center; background-color:#fff; border:1px solid #1e1e1e; border-radius:2px; display:flex; flex-wrap:wrap; padding:1em; } .block-editor-warning,.block-editor-warning .block-editor-warning__message{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; } .block-editor-warning .block-editor-warning__message{ color:#1e1e1e; font-size:13px; line-height:1.4; margin:0; } .block-editor-warning p.block-editor-warning__message.block-editor-warning__message{ min-height:auto; } .block-editor-warning .block-editor-warning__contents{ align-items:baseline; display:flex; flex-direction:row; flex-wrap:wrap; gap:12px; justify-content:space-between; width:100%; } .block-editor-warning .block-editor-warning__actions{ align-items:center; display:flex; gap:8px; } .components-popover.block-editor-warning__dropdown{ z-index:99998; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-autocompleters__block{white-space:nowrap}.block-editor-autocompleters__block .block-editor-block-icon{margin-left:8px}.block-editor-autocompleters__block[aria-selected=true] .block-editor-block-icon{color:inherit!important}.block-editor-autocompleters__link{white-space:nowrap}.block-editor-autocompleters__link .block-editor-block-icon{margin-left:8px}.block-editor-global-styles-background-panel__inspector-media-replace-container{border:1px solid #ddd;border-radius:2px;grid-column:1/-1}.block-editor-global-styles-background-panel__inspector-media-replace-container.is-open{background-color:#f0f0f0}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item{border:0;flex-grow:1}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{display:block}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__inspector-preview-inner{height:100%}.block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown{display:block}.block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown .block-editor-global-styles-background-panel__dropdown-toggle{height:40px}.block-editor-global-styles-background-panel__image-tools-panel-item{border:1px solid #ddd;grid-column:1/-1;position:relative}.block-editor-global-styles-background-panel__image-tools-panel-item .components-drop-zone__content-icon{display:none}.block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{display:block}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button{color:#1e1e1e;display:block;width:100%}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:hover{color:var(--wp-admin-theme-color)}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading{height:100%;padding:10px 0 0;position:absolute;width:100%;z-index:1}.block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading svg{margin:0}.block-editor-global-styles-background-panel__dropdown-toggle,.block-editor-global-styles-background-panel__image-preview-content{height:100%;padding-right:12px;width:100%}.block-editor-global-styles-background-panel__dropdown-toggle{background:#0000;border:none;cursor:pointer}.block-editor-global-styles-background-panel__inspector-media-replace-title{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-editor-global-styles-background-panel__inspector-preview-inner .block-editor-global-styles-background-panel__inspector-image-indicator-wrapper{height:20px;min-width:auto;width:20px}.block-editor-global-styles-background-panel__inspector-image-indicator{background-size:cover;border-radius:50%;display:block;height:20px;position:relative;width:20px}.block-editor-global-styles-background-panel__inspector-image-indicator:after{border:1px solid #0000;border-radius:50%;bottom:-1px;box-shadow:inset 0 0 0 1px #0003;box-sizing:inherit;content:"";left:-1px;position:absolute;right:-1px;top:-1px}.block-editor-global-styles-background-panel__dropdown-content-wrapper{min-width:260px;overflow-x:hidden}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker-wrapper{background-color:#f0f0f0;border:1px solid #ddd;border-radius:2px;width:100%}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker__media--image{max-height:180px}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker:after{content:none}.modal-open .block-editor-global-styles-background-panel__popover{z-index:159890}.block-editor-global-styles-background-panel__media-replace-popover .components-popover__content{width:226px}.block-editor-global-styles-background-panel__media-replace-popover .components-button{padding:0 8px}.block-editor-global-styles-background-panel__media-replace-popover .components-button .components-menu-items__item-icon.has-icon-right{margin-right:16px}.block-editor-block-alignment-control__menu-group .components-menu-item__info{margin-top:0}iframe[name=editor-canvas]{background-color:#ddd;box-sizing:border-box;display:block;height:100%;width:100%}@media not (prefers-reduced-motion){iframe[name=editor-canvas]{transition:all .4s cubic-bezier(.46,.03,.52,.96)}}.block-editor-block-icon{align-items:center;display:flex;height:24px;justify-content:center;width:24px}.block-editor-block-icon.has-colors svg{fill:currentColor}@media (forced-colors:active){.block-editor-block-icon.has-colors svg{fill:CanvasText}}.block-editor-block-icon svg{max-height:24px;max-width:24px;min-height:20px;min-width:20px}.block-editor-block-inspector p:not(.components-base-control__help){margin-top:0}.block-editor-block-inspector h2,.block-editor-block-inspector h3{color:#1e1e1e;font-size:13px;margin-bottom:1.5em}.block-editor-block-inspector .components-base-control:where(:not(:last-child)),.block-editor-block-inspector .components-radio-control:where(:not(:last-child)){margin-bottom:16px}.block-editor-block-inspector .components-focal-point-picker-control .components-base-control,.block-editor-block-inspector .components-query-controls .components-base-control,.block-editor-block-inspector .components-range-control .components-base-control{margin-bottom:0}.block-editor-block-inspector .components-panel__body{border:none;border-top:1px solid #e0e0e0;margin-top:-1px}.block-editor-block-inspector__no-block-tools,.block-editor-block-inspector__no-blocks{background:#fff;display:block;font-size:13px;padding:32px 16px;text-align:center}.block-editor-block-inspector__no-block-tools{border-top:1px solid #ddd}.block-editor-block-list__insertion-point{bottom:0;left:0;position:absolute;right:0;top:0}.block-editor-block-list__insertion-point-indicator{background:var(--wp-admin-theme-color);border-radius:2px;opacity:0;position:absolute;transform-origin:center;will-change:transform,opacity}.block-editor-block-list__insertion-point.is-vertical>.block-editor-block-list__insertion-point-indicator{height:4px;top:calc(50% - 2px);width:100%}.block-editor-block-list__insertion-point.is-horizontal>.block-editor-block-list__insertion-point-indicator{bottom:0;right:calc(50% - 2px);top:0;width:4px}.block-editor-block-list__insertion-point-inserter{display:none;justify-content:center;position:absolute;right:calc(50% - 12px);top:calc(50% - 12px);will-change:transform}@media (min-width:480px){.block-editor-block-list__insertion-point-inserter{display:flex}}.block-editor-block-list__block-side-inserter-popover .components-popover__content>div{pointer-events:none}.block-editor-block-list__block-side-inserter-popover .components-popover__content>div>*{pointer-events:all}.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter{left:0;line-height:0;position:absolute;top:0}.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter:disabled{display:none}.block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{background:#1e1e1e;color:#fff;height:24px;min-width:24px;padding:0}.block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{background:var(--wp-admin-theme-color)}.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{background:#1e1e1e}@keyframes hide-during-dragging{to{position:fixed;transform:translate(-9999px,9999px)}}.components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar{border:1px solid #1e1e1e;border-radius:2px;margin-bottom:8px;margin-top:8px;overflow:visible;pointer-events:all;position:static;width:auto}.components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{margin-right:56px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{margin-right:0}.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar{overflow:visible}.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar-group{border-left-color:#1e1e1e}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar{background-color:#1e1e1e;color:#f0f0f0}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar.block-editor-block-contextual-toolbar{border-color:#2f2f2f}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button{color:#ddd}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:hover{color:#fff}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:focus:before{box-shadow:inset 0 0 0 1px #1e1e1e,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:disabled,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button[aria-disabled=true]{color:#757575}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-parent-selector .block-editor-block-parent-selector__button{background-color:#1e1e1e;border-color:#2f2f2f}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-switcher__toggle{color:#f0f0f0}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar-group{border-left-color:#2f2f2f!important}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .is-pressed{color:var(--wp-admin-theme-color)}.components-popover.block-editor-block-list__block-popover.is-insertion-point-visible{visibility:hidden}.is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{opacity:0}@media not (prefers-reduced-motion){.is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{animation:hide-during-dragging 1ms linear forwards}}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{position:absolute;right:-57px}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector:before{content:""}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{background-color:#fff;border:1px solid #1e1e1e;padding-left:6px;padding-right:6px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{padding-left:12px;padding-right:12px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{margin-right:-1px;position:relative;right:auto}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-mover__move-button-container,.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar__block-controls .block-editor-block-mover{border-right:1px solid #1e1e1e}.is-dragging-components-draggable .components-tooltip{display:none}.components-popover.block-editor-block-popover__inbetween .block-editor-button-pattern-inserter__button{pointer-events:all;position:absolute;right:50%;top:50%;transform:translateX(50%) translateY(-50%)}.block-editor-block-lock-modal{z-index:1000001}@media (min-width:600px){.block-editor-block-lock-modal .components-modal__frame{max-width:480px}}.block-editor-block-lock-modal__options legend{margin-bottom:16px;padding:0}.block-editor-block-lock-modal__checklist{margin:0}.block-editor-block-lock-modal__options-all{padding:12px 0}.block-editor-block-lock-modal__options-all .components-checkbox-control__label{font-weight:600}.block-editor-block-lock-modal__checklist-item{align-items:center;display:flex;gap:12px;justify-content:space-between;margin-bottom:0;padding:12px 32px 12px 0}.block-editor-block-lock-modal__checklist-item .block-editor-block-lock-modal__lock-icon{flex-shrink:0;margin-left:12px;fill:#1e1e1e}.block-editor-block-lock-modal__checklist-item:hover{background-color:#f0f0f0;border-radius:2px}.block-editor-block-lock-modal__template-lock{border-top:1px solid #ddd;margin-top:16px;padding-top:16px}.block-editor-block-lock-modal__actions{margin-top:24px}.block-editor-block-lock-toolbar .components-button.has-icon{min-width:36px!important}.block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{margin-right:-6px!important}.show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{border-right:1px solid #1e1e1e;margin-left:-6px;margin-right:6px!important}.block-editor-block-breadcrumb{list-style:none;margin:0;padding:0}.block-editor-block-breadcrumb li{display:inline-flex;margin:0}.block-editor-block-breadcrumb li .block-editor-block-breadcrumb__separator{fill:currentColor;margin-left:-4px;margin-right:-4px;transform:scaleX(-1)}.block-editor-block-breadcrumb li:last-child .block-editor-block-breadcrumb__separator{display:none}.block-editor-block-breadcrumb__current{cursor:default}.block-editor-block-breadcrumb__button.block-editor-block-breadcrumb__button,.block-editor-block-breadcrumb__current{color:#1e1e1e;font-size:inherit;padding:0 8px}.block-editor-block-card{align-items:flex-start;color:#1e1e1e;display:flex;padding:16px}.block-editor-block-card__title{align-items:center;display:flex;flex-wrap:wrap;font-weight:500;gap:4px 8px}.block-editor-block-card__title.block-editor-block-card__title{font-size:13px;line-height:1.4;margin:0}.block-editor-block-card__name{padding:3px 0}.block-editor-block-card .block-editor-block-icon{flex:0 0 24px;height:24px;margin-left:12px;margin-right:0;width:24px}.block-editor-block-card.is-synced .block-editor-block-icon{color:var(--wp-block-synced-color)}.block-editor-block-compare{height:auto}.block-editor-block-compare__wrapper{display:flex;padding-bottom:16px}.block-editor-block-compare__wrapper>div{display:flex;flex-direction:column;justify-content:space-between;max-width:600px;min-width:200px;padding:0 0 0 16px;width:50%}.block-editor-block-compare__wrapper>div button{float:left}.block-editor-block-compare__wrapper .block-editor-block-compare__converted{border-right:1px solid #ddd;padding-left:0;padding-right:15px}.block-editor-block-compare__wrapper .block-editor-block-compare__html{border-bottom:1px solid #ddd;color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:12px;line-height:1.7;padding-bottom:15px}.block-editor-block-compare__wrapper .block-editor-block-compare__html span{background-color:#e6ffed;padding-bottom:3px;padding-top:3px}.block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__added{background-color:#acf2bd}.block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__removed{background-color:#cc1818}.block-editor-block-compare__wrapper .block-editor-block-compare__preview{padding:16px 0 0}.block-editor-block-compare__wrapper .block-editor-block-compare__preview p{font-size:12px;margin-top:0}.block-editor-block-compare__wrapper .block-editor-block-compare__action{margin-top:16px}.block-editor-block-compare__wrapper .block-editor-block-compare__heading{font-size:1em;font-weight:400;margin:.67em 0}.block-editor-block-draggable-chip-wrapper{position:absolute;right:0;top:-24px}.block-editor-block-draggable-chip{background-color:#1e1e1e;border-radius:2px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;color:#fff;cursor:grabbing;display:inline-flex;height:48px;padding:0 13px;position:relative;-webkit-user-select:none;user-select:none;width:max-content}.block-editor-block-draggable-chip svg{fill:currentColor}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content{justify-content:flex-start;margin:auto}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item{margin-left:6px}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item:last-child{margin-left:0}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content .block-editor-block-icon svg{min-height:18px;min-width:18px}.block-editor-block-draggable-chip .components-flex__item{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{align-items:center;background-color:initial;bottom:0;display:flex;justify-content:center;left:0;opacity:0;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{transition:all .1s linear .1s}}.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled .block-editor-block-draggable-chip__disabled-icon{background:#0000 linear-gradient(45deg,#0000 47.5%,#fff 0,#fff 52.5%,#0000 0);border-radius:50%;box-shadow:inset 0 0 0 1.5px #fff;display:inline-block;height:20px;padding:0;width:20px}.block-draggable-invalid-drag-token .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{background-color:#757575;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;opacity:1}.block-editor-block-manager__no-results{font-style:italic;padding:24px 0;text-align:center}.block-editor-block-manager__search{margin:16px 0}.block-editor-block-manager__disabled-blocks-count{background-color:#fff;border:1px solid #ddd;border-width:1px 0;box-shadow:32px 0 0 0 #fff,-32px 0 0 0 #fff;padding:8px;position:sticky;text-align:center;top:-5px;z-index:2}.block-editor-block-manager__disabled-blocks-count~.block-editor-block-manager__results .block-editor-block-manager__category-title{top:31px}.block-editor-block-manager__disabled-blocks-count .is-link{margin-right:12px}.block-editor-block-manager__category{margin:0 0 24px}.block-editor-block-manager__category-title{background-color:#fff;padding:16px 0;position:sticky;top:-4px;z-index:1}.block-editor-block-manager__category-title .components-checkbox-control__label{font-weight:600}.block-editor-block-manager__checklist{margin-top:0}.block-editor-block-manager__category-title,.block-editor-block-manager__checklist-item{border-bottom:1px solid #ddd}.block-editor-block-manager__checklist-item{align-items:center;display:flex;justify-content:space-between;margin-bottom:0;padding:8px 16px 8px 0}.components-modal__content .block-editor-block-manager__checklist-item.components-checkbox-control__input-container{margin:0 8px}.block-editor-block-manager__checklist-item .block-editor-block-icon{margin-left:10px;fill:#1e1e1e}.block-editor-block-manager__results{border-top:1px solid #ddd}.block-editor-block-manager__disabled-blocks-count+.block-editor-block-manager__results{border-top-width:0}.block-editor-block-mover__move-button-container{border:none;display:flex;justify-content:center;padding:0}@media (min-width:600px){.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{flex-direction:column}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>*{height:20px;min-width:0!important;width:100%}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>:before{height:calc(100% - 4px)}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{flex-shrink:0;top:3px}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{bottom:3px;flex-shrink:0}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{width:48px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container>*{min-width:0!important;overflow:hidden;width:24px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button{padding-left:0;padding-right:0}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{right:5px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{left:5px}}.block-editor-block-mover__drag-handle{cursor:grab}@media (min-width:600px){.block-editor-block-mover__drag-handle{min-width:0!important;overflow:hidden;width:24px}.block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon.has-icon{padding-left:0;padding-right:0}}.components-button.block-editor-block-mover-button{overflow:hidden}.components-button.block-editor-block-mover-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.components-button.block-editor-block-mover-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.components-button.block-editor-block-mover-button:focus,.components-button.block-editor-block-mover-button:focus:before,.components-button.block-editor-block-mover-button:focus:enabled{box-shadow:none;outline:none}.components-button.block-editor-block-mover-button:focus-visible:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-navigation__container{min-width:280px}.block-editor-block-navigation__label{color:#757575;font-size:11px;font-weight:500;margin:0 0 12px;text-transform:uppercase}.block-editor-block-patterns-list__list-item{cursor:pointer;margin-bottom:16px;position:relative}.block-editor-block-patterns-list__list-item.is-placeholder{min-height:100px}.block-editor-block-patterns-list__list-item[draggable=true]{cursor:grab}.block-editor-block-patterns-list__item{height:100%;outline:0;scroll-margin-bottom:56px;scroll-margin-top:24px}.block-editor-block-patterns-list__item .block-editor-block-patterns-list__item-title{flex-grow:1;font-size:12px;text-align:right}.block-editor-block-patterns-list__item .block-editor-block-preview__container{align-items:center;border-radius:4px;display:flex;overflow:hidden}.block-editor-block-patterns-list__item .block-editor-block-preview__container:after{border-radius:4px;outline:1px solid #0000001a;outline-offset:-1px}@media not (prefers-reduced-motion){.block-editor-block-patterns-list__item .block-editor-block-preview__container:after{transition:outline .1s linear}}.block-editor-block-patterns-list__item.is-selected .block-editor-block-preview__container:after{outline-color:#1e1e1e;outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}.block-editor-block-patterns-list__item:hover .block-editor-block-preview__container:after{outline-color:#0000004d}.block-editor-block-patterns-list__item[data-focus-visible] .block-editor-block-preview__container:after{outline-color:var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-details:not(:empty){align-items:center;margin-top:8px;padding-bottom:4px}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper{height:24px;min-width:24px}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper .block-editor-patterns__pattern-icon{fill:var(--wp-block-synced-color)}.block-editor-patterns__grid-pagination-wrapper .block-editor-patterns__grid-pagination{border-top:1px solid #2f2f2f;justify-content:center;padding:4px}.show-icon-labels .block-editor-patterns__grid-pagination-button{width:auto}.show-icon-labels .block-editor-patterns__grid-pagination-button span{display:none}.show-icon-labels .block-editor-patterns__grid-pagination-button:before{content:attr(aria-label)}.components-popover.block-editor-block-popover{margin:0!important;pointer-events:none;position:absolute;z-index:31}.components-popover.block-editor-block-popover .components-popover__content{margin:0!important;min-width:auto;overflow-y:visible;width:max-content}.components-popover.block-editor-block-popover:not(.block-editor-block-popover__inbetween,.block-editor-block-popover__drop-zone,.block-editor-block-list__block-side-inserter-popover) .components-popover__content *{pointer-events:all}.components-popover.block-editor-block-popover__inbetween,.components-popover.block-editor-block-popover__inbetween *{pointer-events:none}.components-popover.block-editor-block-popover__inbetween .is-with-inserter,.components-popover.block-editor-block-popover__inbetween .is-with-inserter *{pointer-events:all}.components-popover.block-editor-block-popover__drop-zone *{pointer-events:none}.components-popover.block-editor-block-popover__drop-zone .block-editor-block-popover__drop-zone-foreground{background-color:var(--wp-admin-theme-color);border-radius:2px;inset:0;position:absolute}.block-editor-block-preview__container{overflow:hidden;position:relative;width:100%}.block-editor-block-preview__container .block-editor-block-preview__content{margin:0;min-height:auto;overflow:visible;right:0;text-align:initial;top:0;transform-origin:top right;width:100%}.block-editor-block-preview__container .block-editor-block-preview__content .block-editor-block-list__insertion-point,.block-editor-block-preview__container .block-editor-block-preview__content .block-list-appender{display:none}.block-editor-block-preview__container:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.block-editor-block-rename-modal{z-index:1000001}.block-editor-block-styles__preview-panel{display:none;z-index:90}@media (min-width:782px){.block-editor-block-styles__preview-panel{display:block}}.block-editor-block-styles__preview-panel .block-editor-block-icon{display:none}.block-editor-block-styles__variants{display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item{box-shadow:inset 0 0 0 1px #ddd;color:#1e1e1e;display:inline-block;width:calc(50% - 4px)}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:hover{box-shadow:inset 0 0 0 1px #ddd;color:var(--wp-admin-theme-color)}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover{background-color:#1e1e1e;box-shadow:none}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active .block-editor-block-styles__item-text,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover .block-editor-block-styles__item-text{color:#fff}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:focus,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:focus{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-styles__variants .block-editor-block-styles__item-text{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-editor-block-styles__block-preview-container,.block-editor-block-styles__block-preview-container *{box-sizing:border-box!important}.block-editor-block-switcher{position:relative}.block-editor-block-switcher .components-button.components-dropdown-menu__toggle.has-icon.has-icon{min-width:36px}.block-editor-block-switcher__no-switcher-icon,.block-editor-block-switcher__toggle{position:relative}.components-button.block-editor-block-switcher__no-switcher-icon,.components-button.block-editor-block-switcher__toggle{display:block;height:48px;margin:0}.components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.components-button.block-editor-block-switcher__toggle .block-editor-block-icon{margin:auto}.components-button.block-editor-block-switcher__no-switcher-icon{display:flex}.components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{margin-left:auto;margin-right:auto;min-width:24px!important}.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true],.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true]:hover{color:#1e1e1e}.components-popover.block-editor-block-switcher__popover .components-popover__content{min-width:300px}.block-editor-block-switcher__popover-preview-container{bottom:0;pointer-events:none;position:absolute;right:0;top:-1px;width:100%}.block-editor-block-switcher__popover-preview{overflow:hidden}.block-editor-block-switcher__popover-preview .components-popover__content{background:#fff;border:1px solid #1e1e1e;border-radius:4px;box-shadow:none;outline:none;overflow:auto;width:300px}.block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview{margin:16px 0;max-height:468px;overflow:hidden;padding:0 16px}.block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview.is-pattern-list-preview{overflow:unset}.block-editor-block-switcher__preview-title{color:#757575;font-size:11px;font-weight:500;margin-bottom:12px;text-transform:uppercase}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon{min-width:36px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle{height:48px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{height:48px;width:48px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{padding:12px}.block-editor-block-switcher__preview-patterns-container{padding-bottom:16px}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item{margin-top:16px}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-preview__container{cursor:pointer}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{border:1px solid #0000;border-radius:2px;height:100%;position:relative}@media not (prefers-reduced-motion){.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{transition:all .05s ease-in-out}}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:focus,.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) #1e1e1e}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item .block-editor-block-switcher__preview-patterns-container-list__item-title{cursor:pointer;font-size:12px;padding:4px;text-align:center}.block-editor-block-switcher__no-transforms{color:#757575;margin:0;padding:6px 8px}.block-editor-block-switcher__binding-indicator{display:block;padding:8px}.block-editor-block-types-list>[role=presentation]{display:flex;flex-wrap:wrap;overflow:hidden}.block-editor-block-pattern-setup{align-items:flex-start;border-radius:2px;display:flex;flex-direction:column;justify-content:center;width:100%}.block-editor-block-pattern-setup.view-mode-grid{padding-top:4px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar{justify-content:center}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{column-count:2;column-gap:24px;display:block;padding:0 32px;width:100%}@media (min-width:1440px){.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{column-count:3}}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button]{cursor:pointer}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item{scroll-margin:5px 0}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-preview__container{box-shadow:0 0 0 2px var(--wp-admin-theme-color)}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-preview__container{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-pattern-setup-list__item-title,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-pattern-setup-list__item-title{color:var(--wp-admin-theme-color)}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item{break-inside:avoid-column;margin-bottom:24px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-pattern-setup-list__item-title{cursor:pointer;font-size:12px;padding-top:8px;text-align:center}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container{border:1px solid #ddd;border-radius:4px;min-height:100px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content{width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar{align-items:center;align-self:stretch;background-color:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;color:#1e1e1e;display:flex;flex-direction:row;height:60px;justify-content:space-between;margin:0;padding:16px;position:absolute;text-align:right;width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls{display:flex}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions,.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__navigation{display:flex;width:calc(50% - 36px)}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions{justify-content:flex-end}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container{box-sizing:border-box;display:flex;flex-direction:column;height:100%;width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container{height:100%;list-style:none;margin:0;overflow:hidden;padding:0;position:relative;transform-style:preserve-3d}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container *{box-sizing:border-box}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{background-color:#fff;height:100%;margin:auto;padding:0;position:absolute;top:0;width:100%;z-index:100}@media not (prefers-reduced-motion){.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{transition:transform .5s,z-index .5s}}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide{opacity:1;position:relative;z-index:102}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.previous-slide{transform:translateX(100%);z-index:101}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.next-slide{transform:translateX(-100%);z-index:101}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .block-list-appender{display:none}.block-editor-block-pattern-setup__carousel,.block-editor-block-pattern-setup__grid{width:100%}.block-editor-block-variation-transforms{padding:0 52px 16px 16px;width:100%}.block-editor-block-variation-transforms .components-dropdown-menu__toggle{border:1px solid #757575;border-radius:2px;justify-content:right;min-height:30px;padding:6px 12px;position:relative;text-align:right;width:100%}.block-editor-block-variation-transforms .components-dropdown-menu__toggle.components-dropdown-menu__toggle{padding-left:24px}.block-editor-block-variation-transforms .components-dropdown-menu__toggle:focus:not(:disabled){border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 calc(var(--wp-admin-border-width-focus) - 1px) var(--wp-admin-theme-color)}.block-editor-block-variation-transforms .components-dropdown-menu__toggle svg{height:100%;left:0;padding:0;position:absolute;top:0}.block-editor-block-variation-transforms__popover .components-popover__content{min-width:230px}.components-border-radius-control{margin-bottom:12px}.components-border-radius-control legend{margin-bottom:8px}.components-border-radius-control .components-border-radius-control__wrapper{align-items:flex-start;display:flex;justify-content:space-between}.components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__unit-control{flex-shrink:0;margin-bottom:0;margin-left:16px;width:calc(50% - 8px)}.components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__range-control{flex:1;margin-left:12px}.components-border-radius-control .components-border-radius-control__input-controls-wrapper{display:grid;gap:16px;grid-template-columns:repeat(2,minmax(0,1fr));margin-left:12px}.components-border-radius-control .component-border-radius-control__linked-button{display:flex;justify-content:center;margin-top:8px}.components-border-radius-control .component-border-radius-control__linked-button svg{margin-left:0}.block-editor-color-gradient-control .block-editor-color-gradient-control__color-indicator{margin-bottom:12px}.block-editor-color-gradient-control__fieldset{min-width:0}.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings,.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings>div:not(:first-of-type){display:block}@media screen and (min-width:782px){.block-editor-panel-color-gradient-settings .components-circular-option-picker__swatches{display:grid;grid-template-columns:repeat(6,28px)}}.block-editor-block-inspector .block-editor-panel-color-gradient-settings .components-base-control{margin-bottom:inherit}.block-editor-panel-color-gradient-settings__dropdown-content .block-editor-color-gradient-control__panel{padding:16px;width:260px}.block-editor-panel-color-gradient-settings__color-indicator{background:linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.block-editor-tools-panel-color-gradient-settings__item{border-bottom:1px solid #ddd;border-left:1px solid #ddd;border-right:1px solid #ddd;max-width:100%;padding:0;position:relative}.block-editor-tools-panel-color-gradient-settings__item:nth-child(1 of .block-editor-tools-panel-color-gradient-settings__item){border-top:1px solid #ddd;border-top-left-radius:2px;border-top-right-radius:2px;margin-top:24px}.block-editor-tools-panel-color-gradient-settings__item:nth-last-child(1 of .block-editor-tools-panel-color-gradient-settings__item){border-bottom-left-radius:2px;border-bottom-right-radius:2px}.block-editor-tools-panel-color-gradient-settings__item>div,.block-editor-tools-panel-color-gradient-settings__item>div>button{border-radius:inherit}.block-editor-tools-panel-color-gradient-settings__dropdown{display:block;padding:0}.block-editor-tools-panel-color-gradient-settings__dropdown>button{height:auto;padding-bottom:10px;padding-top:10px;text-align:right}.block-editor-tools-panel-color-gradient-settings__dropdown>button.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.block-editor-tools-panel-color-gradient-settings__dropdown .block-editor-panel-color-gradient-settings__color-name{max-width:calc(100% - 44px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-panel-color-gradient-settings__dropdown{width:100%}.block-editor-panel-color-gradient-settings__dropdown .component-color-indicator{flex-shrink:0}.block-editor-panel-color-gradient-settings__reset{left:0;margin:auto 8px;opacity:0;position:absolute;top:8px}@media not (prefers-reduced-motion){.block-editor-panel-color-gradient-settings__reset{transition:opacity .1s ease-in-out}}.block-editor-panel-color-gradient-settings__reset.block-editor-panel-color-gradient-settings__reset{border-radius:2px}.block-editor-panel-color-gradient-settings__dropdown:hover+.block-editor-panel-color-gradient-settings__reset,.block-editor-panel-color-gradient-settings__reset:focus,.block-editor-panel-color-gradient-settings__reset:hover{opacity:1}@media (hover:none){.block-editor-panel-color-gradient-settings__reset{opacity:1}}.block-editor-date-format-picker{border:none;margin:0 0 16px;padding:0}.block-editor-date-format-picker__custom-format-select-control__custom-option{border-top:1px solid #ddd}.block-editor-duotone-control__popover.components-popover>.components-popover__content{padding:8px;width:260px}.block-editor-duotone-control__popover.components-popover .components-menu-group__label{padding:0}.block-editor-duotone-control__popover.components-popover .components-circular-option-picker__swatches{display:grid;gap:12px;grid-template-columns:repeat(6,28px);justify-content:space-between}.block-editor-duotone-control__unset-indicator{background:linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.components-font-appearance-control [role=option]{color:#1e1e1e;text-transform:capitalize}.block-editor-font-family-control:not(.is-next-has-no-margin-bottom){margin-bottom:8px}.block-editor-global-styles__toggle-icon{fill:currentColor}.block-editor-global-styles__shadow-popover-container{width:230px}.block-editor-global-styles__shadow__list{display:flex;flex-wrap:wrap;gap:12px;padding-bottom:8px}.block-editor-global-styles__clear-shadow{text-align:left}.block-editor-global-styles-filters-panel__dropdown,.block-editor-global-styles__shadow-dropdown{display:block;padding:0;position:relative}.block-editor-global-styles-filters-panel__dropdown button,.block-editor-global-styles__shadow-dropdown button{padding:8px;width:100%}.block-editor-global-styles-filters-panel__dropdown button.is-open,.block-editor-global-styles__shadow-dropdown button.is-open{background-color:#f0f0f0}.block-editor-global-styles__shadow-editor__remove-button{left:0;margin:auto 8px;opacity:0;position:absolute;top:8px}@media not (prefers-reduced-motion){.block-editor-global-styles__shadow-editor__remove-button{transition:opacity .1s ease-in-out}}.block-editor-global-styles__shadow-dropdown:hover .block-editor-global-styles__shadow-editor__remove-button,.block-editor-global-styles__shadow-editor__remove-button:focus,.block-editor-global-styles__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.block-editor-global-styles__shadow-editor__remove-button{opacity:1}}.block-editor-global-styles-filters-panel__dropdown{border:1px solid #ddd;border-radius:2px}.block-editor-global-styles__shadow-indicator{align-items:center;appearance:none;background:none;border:1px solid #e0e0e0;border-radius:2px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:inline-flex;height:26px;padding:0;transform:scale(1);width:26px;will-change:transform}@media not (prefers-reduced-motion){.block-editor-global-styles__shadow-indicator{transition:transform .1s ease}}.block-editor-global-styles__shadow-indicator:focus{border:2px solid #757575}.block-editor-global-styles__shadow-indicator:hover{transform:scale(1.2)}.block-editor-global-styles__shadow-indicator.unset{background:linear-gradient(45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.block-editor-global-styles-advanced-panel__custom-css-input textarea{direction:ltr;font-family:Menlo,Consolas,monaco,monospace}.block-editor-panel-duotone-settings__reset{left:0;margin:auto 8px;opacity:0;position:absolute;top:8px}@media not (prefers-reduced-motion){.block-editor-panel-duotone-settings__reset{transition:opacity .1s ease-in-out}}.block-editor-global-styles-filters-panel__dropdown:hover .block-editor-panel-duotone-settings__reset,.block-editor-panel-duotone-settings__reset:focus,.block-editor-panel-duotone-settings__reset:hover{opacity:1}@media (hover:none){.block-editor-panel-duotone-settings__reset{opacity:1}}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer{z-index:30}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .components-popover__content *{pointer-events:none}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer.is-dropping-allowed .block-editor-grid-visualizer__drop-zone{pointer-events:all}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .block-editor-inserter *{pointer-events:auto}.block-editor-grid-visualizer__grid{display:grid;position:absolute}.block-editor-grid-visualizer__cell{display:grid;position:relative}.block-editor-grid-visualizer__cell .block-editor-inserter{bottom:0;color:inherit;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:32}.block-editor-grid-visualizer__cell .block-editor-inserter .block-editor-grid-visualizer__appender{box-shadow:inset 0 0 0 1px color-mix(in srgb,currentColor 20%,#0000);color:inherit;height:100%;opacity:0;overflow:hidden;padding:0!important;width:100%}.block-editor-grid-visualizer__cell.is-highlighted .block-editor-grid-visualizer__drop-zone,.block-editor-grid-visualizer__cell.is-highlighted .block-editor-inserter{background:var(--wp-admin-theme-color)}.block-editor-grid-visualizer__cell .block-editor-grid-visualizer__appender:focus,.block-editor-grid-visualizer__cell:hover .block-editor-grid-visualizer__appender{background-color:color-mix(in srgb,currentColor 20%,#0000);opacity:1}.block-editor-grid-visualizer__drop-zone{background:#cccccc1a;grid-column:1;grid-row:1;height:100%;min-height:8px;min-width:8px;width:100%}.block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer{z-index:30}.block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer .components-popover__content *{pointer-events:none}.block-editor-grid-item-resizer__box{border:1px solid var(--wp-admin-theme-color)}.block-editor-grid-item-resizer__box .components-resizable-box__handle.components-resizable-box__handle.components-resizable-box__handle{pointer-events:all}.block-editor-grid-item-mover__move-button-container{border:none;display:flex;justify-content:center;padding:0}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button{min-width:0!important;padding-left:0;padding-right:0;width:24px}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button svg{min-width:24px}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:before,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:enabled{box-shadow:none;outline:none}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus-visible:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-grid-item-mover__move-vertical-button-container{display:flex;position:relative}@media (min-width:600px){.block-editor-grid-item-mover__move-vertical-button-container{flex-direction:column;justify-content:space-around}.block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button{height:20px!important;min-width:0!important;width:100%}.block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button:before{height:calc(100% - 4px)}.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-down-button svg,.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-up-button svg{flex-shrink:0;height:20px}.editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container{height:40px;position:relative;top:-5px}}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container{position:relative}@media (min-width:600px){.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#e0e0e0;content:"";height:100%;position:absolute;top:0;width:1px}}@media (min-width:782px){.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left{padding-left:6px}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left:before{left:0}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right{padding-right:6px}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right:before{right:0}@media (min-width:600px){.show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{background:#e0e0e0;content:"";height:1px;margin-top:-.5px;position:absolute;right:50%;top:50%;transform:translate(50%);width:100%}}@media (min-width:782px){.show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-grid-item-mover-button{white-space:nowrap}.show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#ddd;height:24px;top:4px}.show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container:before{background:#ddd;width:calc(100% - 24px)}.block-editor-height-control{border:0;margin:0;padding:0}.block-editor-iframe__container{height:100%;width:100%}.block-editor-iframe__scale-container{height:100%}.block-editor-iframe__scale-container.is-zoomed-out{left:0;position:absolute;width:var(--wp-block-editor-iframe-zoom-out-scale-container-width,100vw)}.block-editor-image-size-control{margin-bottom:1em}.block-editor-image-size-control .block-editor-image-size-control__height,.block-editor-image-size-control .block-editor-image-size-control__width{margin-bottom:1.115em}.block-editor-block-types-list__list-item{display:block;margin:0;padding:0;width:33.33%}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled) .block-editor-block-icon.has-colors{color:var(--wp-block-synced-color)}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{color:var(--wp-block-synced-color)!important;filter:brightness(.95)}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{color:var(--wp-block-synced-color)!important}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):after{background:var(--wp-block-synced-color)}.components-button.block-editor-block-types-list__item{align-items:stretch;background:#0000;color:#1e1e1e;cursor:pointer;display:flex;flex-direction:column;font-size:13px;height:auto;justify-content:center;padding:8px;position:relative;width:100%;word-break:break-word}@media not (prefers-reduced-motion){.components-button.block-editor-block-types-list__item{transition:all .05s ease-in-out}}.components-button.block-editor-block-types-list__item:disabled{cursor:default;opacity:.6}.components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{color:var(--wp-admin-theme-color)!important;filter:brightness(.95)}.components-button.block-editor-block-types-list__item:not(:disabled):hover svg{color:var(--wp-admin-theme-color)!important}.components-button.block-editor-block-types-list__item:not(:disabled):hover:after{background:var(--wp-admin-theme-color);border-radius:2px;bottom:0;content:"";left:0;opacity:.04;pointer-events:none;position:absolute;right:0;top:0}.components-button.block-editor-block-types-list__item:not(:disabled):focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-button.block-editor-block-types-list__item:not(:disabled).is-active{background:#1e1e1e;color:#fff;outline:2px solid #0000;outline-offset:-2px}.block-editor-block-types-list__item-icon{color:#1e1e1e;padding:12px 20px}@media not (prefers-reduced-motion){.block-editor-block-types-list__item-icon{transition:all .05s ease-in-out}}.block-editor-block-types-list__item-icon .block-editor-block-icon{margin-left:auto;margin-right:auto}@media not (prefers-reduced-motion){.block-editor-block-types-list__item-icon svg{transition:all .15s ease-out}}.block-editor-block-types-list__list-item[draggable=true] .block-editor-block-types-list__item-icon{cursor:grab}.block-editor-block-types-list__item-title{font-size:12px;hyphens:auto;padding:4px 2px 8px}.block-editor-block-inspector__tabs [role=tablist]{width:100%}.block-editor-inspector-popover-header{margin-bottom:16px}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}@keyframes loadingpulse{0%{opacity:1}50%{opacity:0}to{opacity:1}}.block-editor-link-control{min-width:350px;position:relative}.components-popover__content .block-editor-link-control{max-width:350px;min-width:auto;width:90vw}.show-icon-labels .block-editor-link-control .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-link-control .components-button.has-icon:before{content:attr(aria-label)}.show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top{flex-wrap:wrap;gap:4px}.show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon{padding:4px;width:auto}.show-icon-labels .block-editor-link-control .is-preview .block-editor-link-control__search-item-header{margin-left:0;min-width:100%}.block-editor-link-control__search-input-wrapper{margin-bottom:8px;position:relative}.block-editor-link-control__search-input-container,.block-editor-link-control__search-input-wrapper{position:relative}.block-editor-link-control__field{margin:16px}.block-editor-link-control__field .components-base-control__label{color:#1e1e1e}.block-editor-link-control__search-error{margin:-8px 16px 16px}.block-editor-link-control__search-actions{padding:8px 16px 16px}.block-editor-link-control__search-results-wrapper{position:relative}.block-editor-link-control__search-results-wrapper:after,.block-editor-link-control__search-results-wrapper:before{content:"";display:block;left:16px;pointer-events:none;position:absolute;right:-1px;z-index:100}.block-editor-link-control__search-results-wrapper:before{bottom:auto;height:8px;top:0}.block-editor-link-control__search-results-wrapper:after{bottom:0;height:16px;top:auto}.block-editor-link-control__search-results{margin-top:-16px;max-height:200px;overflow-y:auto;padding:8px}.block-editor-link-control__search-results.is-loading{opacity:.2}.block-editor-link-control__search-item.components-button.components-menu-item__button{height:auto;text-align:right}.block-editor-link-control__search-item .components-menu-item__item{display:inline-block;overflow:hidden;text-overflow:ellipsis;width:100%}.block-editor-link-control__search-item .components-menu-item__item mark{background-color:initial;color:inherit;font-weight:600}.block-editor-link-control__search-item .components-menu-item__shortcut{color:#757575;text-transform:capitalize;white-space:nowrap}.block-editor-link-control__search-item[aria-selected]{background:#f0f0f0}.block-editor-link-control__search-item.is-current{background:#0000;border:0;cursor:default;flex-direction:column;padding:16px;width:100%}.block-editor-link-control__search-item .block-editor-link-control__search-item-header{align-items:center;display:block;flex-direction:row;gap:8px;margin-left:8px;overflow-wrap:break-word;white-space:pre-wrap}.block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-info{color:#757575;font-size:12px;line-height:1.1;word-break:break-all}.block-editor-link-control__search-item.is-preview .block-editor-link-control__search-item-header{display:flex;flex:1}.block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-header{align-items:center}.block-editor-link-control__search-item.is-url-title .block-editor-link-control__search-item-title{word-break:break-all}.block-editor-link-control__search-item .block-editor-link-control__search-item-details{display:flex;flex-direction:column;gap:4px;justify-content:space-between}.block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-icon{background-color:#f0f0f0;border-radius:2px;height:32px;width:32px}.block-editor-link-control__search-item .block-editor-link-control__search-item-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center;position:relative}.block-editor-link-control__search-item .block-editor-link-control__search-item-icon img{width:16px}.block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-icon{max-height:32px;top:0;width:32px}.block-editor-link-control__search-item .block-editor-link-control__search-item-title{line-height:1.1}.block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus{box-shadow:none}.block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus-visible{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000;text-decoration:none}.block-editor-link-control__search-item .block-editor-link-control__search-item-title mark{background-color:initial;color:inherit;font-weight:600}.block-editor-link-control__search-item .block-editor-link-control__search-item-title span{font-weight:400}.block-editor-link-control__search-item .block-editor-link-control__search-item-title .components-external-link__icon{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.block-editor-link-control__search-item-top{align-items:center;display:flex;flex-direction:row;width:100%}.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon img,.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon svg{opacity:0}.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{background-color:#f0f0f0;border-radius:100%;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{animation:loadingpulse 1s linear infinite;animation-delay:.5s}}.block-editor-link-control__loading{align-items:center;display:flex;margin:16px}.block-editor-link-control__loading .components-spinner{margin-top:0}.components-button+.block-editor-link-control__search-create{overflow:visible;padding:12px 16px}.components-button+.block-editor-link-control__search-create:before{content:"";display:block;position:absolute;right:0;top:-10px;width:100%}.block-editor-link-control__search-create{align-items:center}.block-editor-link-control__search-create .block-editor-link-control__search-item-title{margin-bottom:0}.block-editor-link-control__search-create .block-editor-link-control__search-item-icon{top:0}.block-editor-link-control__drawer-inner{display:flex;flex-basis:100%;flex-direction:column;position:relative}.block-editor-link-control__setting{flex:1;margin-bottom:0;padding:8px 24px 8px 0}.block-editor-link-control__setting .components-base-control__field{display:flex}.block-editor-link-control__setting .components-base-control__field .components-checkbox-control__label{color:#1e1e1e}.block-editor-link-control__setting input{margin-right:0}.is-preview .block-editor-link-control__setting{padding:20px 0 8px 8px}.block-editor-link-control__tools{margin-top:-16px;padding:8px 8px 0}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle{gap:0;padding-right:0}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true]{color:#1e1e1e}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{transform:rotate(-90deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{transition:transform .1s ease}}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{transform:rotate(0deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{transition:transform .1s ease}}.block-editor-link-control .block-editor-link-control__search-input .components-spinner{display:block}.block-editor-link-control .block-editor-link-control__search-input .components-spinner.components-spinner{bottom:auto;left:40px;position:absolute;right:auto;top:calc(50% - 8px)}.block-editor-link-control .block-editor-link-control__search-input-wrapper.has-actions .components-spinner{left:12px;top:calc(50% + 4px)}.block-editor-list-view-tree{border-collapse:collapse;margin:0;padding:0;width:100%}.components-modal__content .block-editor-list-view-tree{margin:-12px -6px 0;width:calc(100% + 12px)}.block-editor-list-view-tree.is-dragging tbody{pointer-events:none}.block-editor-list-view-leaf{position:relative;transform:translateY(0)}.block-editor-list-view-leaf.is-draggable,.block-editor-list-view-leaf.is-draggable .block-editor-list-view-block-contents{cursor:grab}.block-editor-list-view-leaf .block-editor-list-view-block-select-button[aria-expanded=true]{color:inherit}.block-editor-list-view-leaf .block-editor-list-view-block-select-button:hover{color:var(--wp-admin-theme-color)}.block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{fill:currentColor}@media (forced-colors:active){.block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{fill:CanvasText}}.is-dragging-components-draggable .block-editor-list-view-leaf:not(.is-selected) .block-editor-list-view-block-select-button:hover{color:inherit}.block-editor-list-view-leaf.is-selected td{background:var(--wp-admin-theme-color)}.block-editor-list-view-leaf.is-selected.is-synced td{background:var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents .block-editor-block-icon,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:hover{color:var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents,.block-editor-list-view-leaf.is-selected .components-button.has-icon{color:#fff}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-list-view-leaf.is-selected.is-synced .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block__menu:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff}.block-editor-list-view-leaf.is-first-selected td:first-child{border-top-right-radius:2px}.block-editor-list-view-leaf.is-first-selected td:last-child{border-top-left-radius:2px}.block-editor-list-view-leaf.is-last-selected td:first-child{border-bottom-right-radius:2px}.block-editor-list-view-leaf.is-last-selected td:last-child{border-bottom-left-radius:2px}.block-editor-list-view-leaf.is-branch-selected:not(.is-selected):not(.is-synced-branch){background:rgba(var(--wp-admin-theme-color--rgb),.04)}.block-editor-list-view-leaf.is-synced-branch.is-branch-selected{background:rgba(var(--wp-block-synced-color--rgb),.04)}.block-editor-list-view-leaf.is-branch-selected.is-first-selected td:first-child{border-top-right-radius:2px}.block-editor-list-view-leaf.is-branch-selected.is-first-selected td:last-child{border-top-left-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:first-child{border-top-right-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:last-child{border-top-left-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:first-child{border-bottom-right-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:last-child{border-bottom-left-radius:2px}.block-editor-list-view-leaf.is-branch-selected:not(.is-selected) td{border-radius:0}.block-editor-list-view-leaf.is-displacement-normal{transform:translateY(0)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-normal{transition:transform .2s}}.block-editor-list-view-leaf.is-displacement-up{transform:translateY(-32px)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-up{transition:transform .2s}}.block-editor-list-view-leaf.is-displacement-down{transform:translateY(32px)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-down{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks{transform:translateY(calc(var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{transform:translateY(calc(-32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{transform:translateY(calc(32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{transition:transform .2s}}.block-editor-list-view-leaf.is-dragging{opacity:0;pointer-events:none;right:0;z-index:-9999}.block-editor-list-view-leaf .block-editor-list-view-block-contents{align-items:center;border-radius:2px;box-sizing:border-box;color:inherit;display:flex;font-family:inherit;font-size:13px;font-weight:400;height:32px;margin:0;padding:6px 0 6px 4px;position:relative;text-align:right;text-decoration:none;white-space:nowrap;width:100%}@media not (prefers-reduced-motion){.block-editor-list-view-leaf .block-editor-list-view-block-contents{transition:box-shadow .1s linear}}.components-modal__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{padding-left:0;padding-right:0}.block-editor-list-view-leaf .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents{box-shadow:none}.block-editor-list-view-leaf .block-editor-list-view-block-contents:focus:after,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents:after{border-radius:inherit;bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";left:-29px;pointer-events:none;position:absolute;right:0;top:0;z-index:2}.block-editor-list-view-leaf.has-single-cell .block-editor-list-view-block-contents:focus:after{left:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view__menu{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);z-index:1}.block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{opacity:1}@keyframes __wp-base-styles-fade-in{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{animation:__wp-base-styles-fade-in .08s linear 0s;animation-fill-mode:forwards}}.block-editor-list-view-leaf .block-editor-block-icon{flex:0 0 24px;margin-left:4px}.block-editor-list-view-leaf .block-editor-list-view-block__contents-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{padding:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{line-height:0;vertical-align:middle;width:36px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell>*{opacity:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:hover>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:hover>*{opacity:1}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell .components-button.has-icon{min-width:24px;padding:0;width:24px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell{padding-left:4px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon{height:24px}.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell-alignment-wrapper{align-items:center;display:flex;flex-direction:column;height:100%}.block-editor-list-view-leaf .block-editor-block-mover-button{height:24px;position:relative;width:36px}.block-editor-list-view-leaf .block-editor-block-mover-button svg{height:24px;position:relative}.block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button{align-items:flex-end;margin-top:-6px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button svg{bottom:-4px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button{align-items:flex-start;margin-bottom:-6px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button svg{top:-4px}.block-editor-list-view-leaf .block-editor-block-mover-button:before{height:16px;left:0;min-width:100%;right:0}.block-editor-list-view-leaf .block-editor-inserter__toggle{background:#1e1e1e;color:#fff;height:24px;margin:6px 1px 6px 6px;min-width:24px}.block-editor-list-view-leaf .block-editor-inserter__toggle:active{color:#fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__label-wrapper svg{position:relative;right:2px}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__title{flex:1;position:relative}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__title .components-truncate{position:absolute;transform:translateY(-50%);width:100%}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor-wrapper{max-width:min(110px,40%);position:relative;width:100%}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor{left:0;position:absolute;transform:translateY(-50%)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__anchor{background:#0000004d;color:#fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,.block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky{line-height:0}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__images{display:flex}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image{background-size:cover;border-radius:1px;height:18px;width:18px}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:only-child){box-shadow:0 0 0 2px #fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:first-child){margin-right:-6px}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__image:not(:only-child){box-shadow:0 0 0 2px var(--wp-admin-theme-color)}.block-editor-list-view-draggable-chip{opacity:.8}.block-editor-list-view-appender__cell .block-editor-list-view-appender__container,.block-editor-list-view-appender__cell .block-editor-list-view-block__contents-container,.block-editor-list-view-block__contents-cell .block-editor-list-view-appender__container,.block-editor-list-view-block__contents-cell .block-editor-list-view-block__contents-container{display:flex}.block-editor-list-view__expander{cursor:pointer;height:24px;width:24px}.block-editor-list-view-leaf[aria-level] .block-editor-list-view__expander{margin-right:192px}.block-editor-list-view-leaf[aria-level="1"] .block-editor-list-view__expander{margin-right:0}.block-editor-list-view-leaf[aria-level="2"] .block-editor-list-view__expander{margin-right:24px}.block-editor-list-view-leaf[aria-level="3"] .block-editor-list-view__expander{margin-right:48px}.block-editor-list-view-leaf[aria-level="4"] .block-editor-list-view__expander{margin-right:72px}.block-editor-list-view-leaf[aria-level="5"] .block-editor-list-view__expander{margin-right:96px}.block-editor-list-view-leaf[aria-level="6"] .block-editor-list-view__expander{margin-right:120px}.block-editor-list-view-leaf[aria-level="7"] .block-editor-list-view__expander{margin-right:144px}.block-editor-list-view-leaf[aria-level="8"] .block-editor-list-view__expander{margin-right:168px}.block-editor-list-view-leaf .block-editor-list-view__expander{visibility:hidden}.block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{transform:rotate(-90deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{transition:transform .2s ease}}.block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{transform:rotate(0deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{transition:transform .2s ease}}.block-editor-list-view-drop-indicator{pointer-events:none}.block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line{background:var(--wp-admin-theme-color);border-radius:4px;height:4px}.block-editor-list-view-drop-indicator--preview{pointer-events:none}.block-editor-list-view-drop-indicator--preview .components-popover__content{overflow:hidden!important}.block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:4px;height:32px;overflow:hidden}.block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line--darker{background:rgba(var(--wp-admin-theme-color--rgb),.09)}.block-editor-list-view-placeholder{height:32px;margin:0;padding:0}.list-view-appender .block-editor-inserter__toggle{background-color:#1e1e1e;color:#fff;height:24px;margin:8px 24px 0 0;padding:0}.list-view-appender .block-editor-inserter__toggle.has-icon.is-next-40px-default-size{min-width:24px}.list-view-appender .block-editor-inserter__toggle:focus,.list-view-appender .block-editor-inserter__toggle:hover{background:var(--wp-admin-theme-color);color:#fff}.list-view-appender__description{display:none}.block-editor-media-placeholder__url-input-form{min-width:260px}@media (min-width:600px){.block-editor-media-placeholder__url-input-form{width:300px}}.block-editor-media-placeholder__url-input-form input{direction:ltr}.modal-open .block-editor-media-replace-flow__options{display:none}.block-editor-media-replace-flow__indicator{margin-right:4px}.block-editor-media-replace-flow__media-upload-menu:not(:empty)+.block-editor-media-flow__url-input{border-top:1px solid #1e1e1e;margin-top:8px;padding-bottom:8px}.block-editor-media-flow__url-input{margin-left:-8px;margin-right:-8px;padding:16px}.block-editor-media-flow__url-input .block-editor-media-replace-flow__image-url-label{display:block;margin-bottom:8px;top:16px}.block-editor-media-flow__url-input .block-editor-link-control{width:300px}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-url-input{margin:0;padding:0}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-info,.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-title{max-width:200px;white-space:nowrap}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__tools{justify-content:flex-end;padding:16px var(--wp-admin-border-width-focus) var(--wp-admin-border-width-focus)}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item.is-current{padding:0;width:auto}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-input.block-editor-link-control__search-input input[type=text]{margin:0;width:100%}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-actions{padding:8px 0 0}.block-editor-media-flow__error{max-width:255px;padding:0 20px 20px}.block-editor-media-flow__error .components-with-notices-ui{max-width:255px}.block-editor-media-flow__error .components-with-notices-ui .components-notice__content{overflow:hidden;word-wrap:break-word}.block-editor-media-flow__error .components-with-notices-ui .components-notice__dismiss{left:10px;position:absolute}.block-editor-multi-selection-inspector__card{padding:16px}.block-editor-multi-selection-inspector__card-title{font-weight:500}.block-editor-multi-selection-inspector__card .block-editor-block-icon{height:24px;margin-right:-2px;padding:0 3px;width:36px}.block-editor-responsive-block-control{border-bottom:1px solid #ccc;margin-bottom:28px;padding-bottom:14px}.block-editor-responsive-block-control:last-child{border-bottom:0;padding-bottom:0}.block-editor-responsive-block-control__title{margin:0 -3px .6em 0}.block-editor-responsive-block-control__label{font-weight:600;margin-bottom:.6em;margin-right:-3px}.block-editor-responsive-block-control__inner{margin-right:-1px}.block-editor-responsive-block-control__toggle{margin-right:1px}.block-editor-responsive-block-control .components-base-control__help{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.components-popover.block-editor-rich-text__inline-format-toolbar{z-index:99998}.components-popover.block-editor-rich-text__inline-format-toolbar .components-popover__content{border-radius:2px;box-shadow:none;margin-bottom:8px;min-width:auto;outline:none;width:auto}.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar{border-radius:2px}.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar-group{background:none}.components-popover.block-editor-rich-text__inline-format-toolbar .components-dropdown-menu__toggle,.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar__control{min-height:48px;min-width:48px;padding-left:12px;padding-right:12px}.block-editor-rich-text__inline-format-toolbar-group .components-dropdown-menu__toggle{justify-content:center}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon{width:auto}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon:after{content:attr(aria-label)}.block-editor-skip-to-selected-block{position:absolute;top:-9999em}.block-editor-skip-to-selected-block:focus{background:#f1f1f1;font-size:14px;font-weight:600;z-index:100000}.block-editor-tabbed-sidebar{background-color:#fff;display:flex;flex-direction:column;flex-grow:1;height:100%;overflow:hidden}.block-editor-tabbed-sidebar__tablist-and-close-button{border-bottom:1px solid #ddd;display:flex;justify-content:space-between;padding-left:8px}.block-editor-tabbed-sidebar__close-button{align-self:center;background:#fff;order:1}.block-editor-tabbed-sidebar__tablist{margin-bottom:-1px}.block-editor-tabbed-sidebar__tabpanel{display:flex;flex-direction:column;flex-grow:1;overflow-y:auto;scrollbar-gutter:auto}.block-editor-tool-selector__help{border-top:1px solid #ddd;color:#757575;margin:8px -8px -8px;min-width:280px;padding:16px}.block-editor-tool-selector__menu .components-menu-item__info{margin-right:36px;text-align:right}.block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{flex-grow:1;padding:1px;position:relative}@media (min-width:600px){.block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{min-width:300px;width:auto}}.block-editor-block-list__block .block-editor-url-input.is-full-width,.block-editor-block-list__block .block-editor-url-input.is-full-width__suggestions,.block-editor-url-input.is-full-width,.block-editor-url-input.is-full-width__suggestions,.components-popover .block-editor-url-input.is-full-width,.components-popover .block-editor-url-input.is-full-width__suggestions{width:100%}.block-editor-block-list__block .block-editor-url-input .components-spinner,.block-editor-url-input .components-spinner,.components-popover .block-editor-url-input .components-spinner{left:8px;margin:0;position:absolute;top:calc(50% - 8px)}.block-editor-url-input__suggestions{max-height:200px;overflow-y:auto;padding:4px 0;width:302px}@media not (prefers-reduced-motion){.block-editor-url-input__suggestions{transition:all .15s ease-in-out}}.block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{display:none}@media (min-width:600px){.block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{display:grid}}.block-editor-url-input__suggestion{background:#fff;border:none;box-shadow:none;color:#757575;cursor:pointer;display:block;font-size:13px;height:auto;min-height:36px;text-align:right;width:100%}.block-editor-url-input__suggestion:hover{background:#ddd}.block-editor-url-input__suggestion.is-selected,.block-editor-url-input__suggestion:focus{background:var(--wp-admin-theme-color-darker-20);color:#fff;outline:none}.components-toolbar-group>.block-editor-url-input__button,.components-toolbar>.block-editor-url-input__button{position:inherit}.block-editor-url-input__button .block-editor-url-input__back{margin-left:4px;overflow:visible}.block-editor-url-input__button .block-editor-url-input__back:after{background:#ddd;content:"";display:block;height:24px;left:-1px;position:absolute;width:1px}.block-editor-url-input__button-modal{background:#fff;border:1px solid #ddd;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003}.block-editor-url-input__button-modal-line{align-items:flex-start;display:flex;flex-direction:row;flex-grow:1;flex-shrink:1;min-width:0}.block-editor-url-popover__additional-controls{border-top:1px solid #1e1e1e;padding:8px}.block-editor-url-popover__input-container{padding:8px}.block-editor-url-popover__row{align-items:center;display:flex;gap:4px}.block-editor-url-popover__row>:not(.block-editor-url-popover__settings-toggle){flex-grow:1;gap:8px}.block-editor-url-popover__additional-controls .components-button.has-icon{height:auto;padding-left:8px;padding-right:8px;text-align:right}.block-editor-url-popover__additional-controls .components-button.has-icon>svg{margin-left:8px}.block-editor-url-popover__settings-toggle{flex-shrink:0}.block-editor-url-popover__settings-toggle[aria-expanded=true] .dashicon{transform:rotate(-180deg)}.block-editor-url-popover__settings{border-top:1px solid #1e1e1e;display:block;padding:16px}.block-editor-url-popover__link-editor,.block-editor-url-popover__link-viewer{display:flex}.block-editor-url-popover__link-viewer-url{align-items:center;display:flex;flex-grow:1;flex-shrink:1;margin-left:8px;max-width:350px;min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-url-popover__link-viewer-url.has-invalid-link{color:#cc1818}.block-editor-url-popover__expand-on-click{align-items:center;display:flex;min-width:350px;white-space:nowrap}.block-editor-url-popover__expand-on-click .text{flex-grow:1}.block-editor-url-popover__expand-on-click .text p{line-height:16px;margin:0}.block-editor-url-popover__expand-on-click .text p.description{color:#757575;font-size:12px}.block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack{flex-direction:row}.block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext{color:#757575;font-size:12px;margin-bottom:16px}div.block-editor-bindings__panel{grid-template-columns:repeat(auto-fit,minmax(100%,1fr))}div.block-editor-bindings__panel button:hover .block-editor-bindings__item span{color:inherit}.border-block-support-panel .single-column{grid-column:span 1}.color-block-support-panel .block-editor-contrast-checker{grid-column:span 2;margin-top:16px}.color-block-support-panel .block-editor-contrast-checker .components-notice__content{margin-left:0}.color-block-support-panel.color-block-support-panel .color-block-support-panel__inner-wrapper{row-gap:0}.color-block-support-panel .block-editor-tools-panel-color-gradient-settings__item.first{margin-top:0}.dimensions-block-support-panel .single-column{grid-column:span 1}.block-editor-hooks__layout-constrained .components-base-control{margin-bottom:0}.block-editor-hooks__layout-constrained-helptext{color:#757575;font-size:12px;margin-bottom:0}.block-editor-hooks__flex-layout-justification-controls,.block-editor-hooks__flex-layout-orientation-controls{margin-bottom:12px}.block-editor-hooks__flex-layout-justification-controls legend,.block-editor-hooks__flex-layout-orientation-controls legend{margin-bottom:8px}.block-editor__spacing-visualizer{border-color:var(--wp-admin-theme-color);border-style:solid;bottom:0;box-sizing:border-box;left:0;opacity:.5;pointer-events:none;position:absolute;right:0;top:0}.typography-block-support-panel .single-column{grid-column:span 1}.block-editor-block-toolbar{display:flex;flex-grow:1;overflow-x:auto;overflow-y:hidden;position:relative;width:100%}@media not (prefers-reduced-motion){.block-editor-block-toolbar{transition:border-color .1s linear,box-shadow .1s linear}}@media (min-width:600px){.block-editor-block-toolbar{overflow:inherit}}.block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group{background:none;border:0;border-left:1px solid #ddd;margin-bottom:-1px;margin-top:-1px}.block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button:before{background:color-mix(in srgb,var(--wp-block-synced-color) 10%,#0000);border-radius:2px}.block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-connected .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors,.block-editor-block-toolbar.is-synced .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-synced .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors{color:var(--wp-block-synced-color)}.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2),.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar,.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar-group,.block-editor-block-toolbar>:last-child,.block-editor-block-toolbar>:last-child .components-toolbar,.block-editor-block-toolbar>:last-child .components-toolbar-group{border-left:none}.block-editor-block-toolbar .components-toolbar-group:empty{display:none}.block-editor-block-contextual-toolbar{background-color:#fff;display:block;flex-shrink:3;position:sticky;top:0;width:100%;z-index:31}.block-editor-block-contextual-toolbar.components-accessible-toolbar{border:none;border-radius:0}.block-editor-block-contextual-toolbar.is-unstyled{box-shadow:0 1px 0 0 rgba(0,0,0,.133)}.block-editor-block-contextual-toolbar .block-editor-block-toolbar{overflow:auto;overflow-y:hidden;scrollbar-color:#e0e0e0 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:auto;scrollbar-width:thin;will-change:transform}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar{height:12px;width:12px}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-track{background-color:initial}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:#e0e0e0;border:3px solid #0000;border-radius:8px}.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover::-webkit-scrollbar-thumb{background-color:#949494}.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover{scrollbar-color:#949494 #0000}@media (hover:none){.block-editor-block-contextual-toolbar .block-editor-block-toolbar{scrollbar-color:#949494 #0000}}.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar-group:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child:after{display:none}.block-editor-block-contextual-toolbar>.block-editor-block-toolbar{flex-grow:0;width:auto}.block-editor-block-contextual-toolbar .block-editor-block-parent-selector{margin-bottom:-1px;margin-top:-1px;position:relative}.block-editor-block-contextual-toolbar .block-editor-block-parent-selector:after{align-items:center;background-color:#1e1e1e;border-radius:100%;content:"";display:inline-flex;height:2px;left:0;position:absolute;top:15px;width:2px}.block-editor-block-toolbar__block-controls .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.block-editor-block-toolbar__block-controls .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{margin:0!important;width:24px!important}.block-editor-block-toolbar__block-controls .components-toolbar-group{padding:0}.block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar-group{display:flex;flex-wrap:nowrap}.block-editor-block-toolbar__slot{display:inline-flex}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon{width:auto}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon:after{content:attr(aria-label);font-size:12px}.show-icon-labels .components-accessible-toolbar .components-toolbar-group>div:first-child:last-child>.components-button.has-icon{padding-left:6px;padding-right:6px}.show-icon-labels .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.show-icon-labels .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{height:0!important;min-width:0!important;width:0!important}.show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button{border-bottom-left-radius:0;border-top-left-radius:0;padding-left:12px;padding-right:12px;text-wrap:nowrap}.show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button .block-editor-block-icon{width:0}.show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container{position:relative;width:auto}@media (min-width:600px){.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{background:#e0e0e0;content:"";height:1px;margin-top:-.5px;position:absolute;right:50%;top:50%;transform:translate(50%);width:100%}}@media (min-width:782px){.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button,.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{padding-left:6px;padding-right:6px}.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover-button{padding-left:8px;padding-right:8px}.show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-mover{border-right:1px solid #ddd;margin-left:-6px;margin-right:6px;white-space:nowrap}.show-icon-labels .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon{padding-left:12px;padding-right:12px}.show-icon-labels .block-editor-block-contextual-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button.block-editor-block-mover-button{width:auto}.show-icon-labels .components-toolbar,.show-icon-labels .components-toolbar-group{flex-shrink:1}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button+.components-button{margin-right:6px}.block-editor-block-toolbar-change-design-content-wrapper{padding:12px;width:320px}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr 1fr;grid-gap:12px}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{margin-bottom:0}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{min-height:100px}.block-editor-inserter{background:none;border:none;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:0;padding:0}@media (min-width:782px){.block-editor-inserter{position:relative}}.block-editor-inserter__main-area{gap:16px;height:100%;position:relative}.block-editor-inserter__main-area.show-as-tabs{gap:0}@media (min-width:782px){.block-editor-inserter__main-area .block-editor-tabbed-sidebar{width:350px}}.block-editor-inserter__popover.is-quick .components-popover__content{border:none;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;outline:none}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>*{border-left:1px solid #ccc;border-right:1px solid #ccc}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:first-child{border-radius:4px 4px 0 0;border-top:1px solid #ccc}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:last-child{border-bottom:1px solid #ccc;border-radius:0 0 4px 4px}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>.components-button{border:1px solid #1e1e1e}.block-editor-inserter__popover .block-editor-inserter__menu{margin:-12px}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__tablist{top:60px}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__main-area{height:auto;overflow:visible}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__preview-container{display:none}.block-editor-inserter__toggle.components-button{align-items:center;border:none;cursor:pointer;display:inline-flex;outline:none;padding:0}@media not (prefers-reduced-motion){.block-editor-inserter__toggle.components-button{transition:color .2s ease}}.block-editor-inserter__menu{height:100%;overflow:visible;position:relative}@media (min-width:782px){.block-editor-inserter__menu.show-panel{width:630px}}.block-editor-inserter__inline-elements{margin-top:-1px}.block-editor-inserter__menu.is-bottom:after{border-bottom-color:#fff}.components-popover.block-editor-inserter__popover{z-index:99999}.block-editor-inserter__search{padding:16px 16px 0}.block-editor-inserter__no-tab-container{flex-grow:1;overflow-y:auto;position:relative}.block-editor-inserter__panel-header{align-items:center;display:inline-flex;padding:16px 16px 0;position:relative}.block-editor-inserter__panel-content{padding:16px}.block-editor-inserter__panel-title,.block-editor-inserter__panel-title button{color:#757575;font-size:11px;font-weight:500;margin:0 0 0 12px;text-transform:uppercase}.block-editor-inserter__panel-dropdown select.components-select-control__input.components-select-control__input.components-select-control__input{height:36px;line-height:36px}.block-editor-inserter__panel-dropdown select{border:none}.block-editor-inserter__reusable-blocks-panel{position:relative;text-align:left}.block-editor-inserter__no-results,.block-editor-inserter__patterns-loading{padding:32px;text-align:center}.block-editor-inserter__child-blocks{padding:0 16px}.block-editor-inserter__parent-block-header{align-items:center;display:flex}.block-editor-inserter__parent-block-header h2{font-size:13px}.block-editor-inserter__parent-block-header .block-editor-block-icon{margin-left:8px}.block-editor-inserter__preview-container__popover{top:16px!important}.block-editor-inserter__preview-container{display:none;max-height:calc(100% - 32px);overflow-y:hidden;padding:16px;width:280px}@media (min-width:782px){.block-editor-inserter__preview-container{display:block}}.block-editor-inserter__preview-container .block-editor-inserter__media-list__list-item{height:100%}.block-editor-inserter__preview-container .block-editor-block-card{padding-bottom:4px;padding-left:0;padding-right:0}.block-editor-inserter__insertable-blocks-at-selection{border-bottom:1px solid #e0e0e0}.block-editor-inserter__block-patterns-tabs-container,.block-editor-inserter__media-tabs-container{display:flex;flex-direction:column;flex-grow:1;justify-content:space-between;padding:16px}.block-editor-inserter__category-tablist{margin-bottom:8px}.block-editor-inserter__category-panel{display:flex;flex-direction:column;outline:1px solid #0000;padding:0 16px}@media (min-width:782px){.block-editor-inserter__category-panel{background:#f0f0f0;border-right:1px solid #e0e0e0;border-top:1px solid #e0e0e0;height:calc(100% + 1px);padding:0;position:absolute;right:350px;top:-1px;width:280px}.block-editor-inserter__category-panel .block-editor-block-patterns-list,.block-editor-inserter__category-panel .block-editor-inserter__media-list{padding:0 24px 16px}}.block-editor-inserter__patterns-category-panel-header{padding:8px 0}@media (min-width:782px){.block-editor-inserter__patterns-category-panel-header{padding:8px 24px}}.block-editor-inserter__patterns-category-no-results{margin-top:24px}.block-editor-inserter__patterns-filter-help{border-top:1px solid #ddd;color:#757575;min-width:280px;padding:16px}.block-editor-block-patterns-list,.block-editor-inserter__media-list{flex-grow:1;height:100%;overflow-y:auto}.block-editor-inserter__preview-content{align-items:center;background:#f0f0f0;display:grid;flex-grow:1}.block-editor-inserter__preview-content-missing{align-items:center;background:#f0f0f0;border-radius:2px;color:#757575;display:flex;flex:1;justify-content:center;min-height:144px}.block-editor-inserter__tips{border-top:1px solid #ddd;flex-shrink:0;padding:16px;position:relative}.block-editor-inserter__quick-inserter{max-width:100%;width:100%}@media (min-width:782px){.block-editor-inserter__quick-inserter{width:350px}}.block-editor-inserter__quick-inserter-results .block-editor-inserter__panel-header{float:right;height:0;padding:0}.block-editor-inserter__quick-inserter.has-expand .block-editor-inserter__panel-content,.block-editor-inserter__quick-inserter.has-search .block-editor-inserter__panel-content{padding:16px}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr 1fr;grid-gap:8px}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{margin-bottom:0}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{min-height:100px}.block-editor-inserter__quick-inserter-separator{border-top:1px solid #ddd}.block-editor-inserter__popover.is-quick>.components-popover__content{padding:0}.block-editor-inserter__quick-inserter-expand.components-button{background:#1e1e1e;border-radius:0;color:#fff;display:block;width:100%}.block-editor-inserter__quick-inserter-expand.components-button:hover{color:#fff}.block-editor-inserter__quick-inserter-expand.components-button:active{color:#ccc}.block-editor-inserter__quick-inserter-expand.components-button.components-button:focus:not(:disabled){background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);box-shadow:none}.block-editor-block-patterns-explorer__sidebar{bottom:0;overflow-x:visible;overflow-y:scroll;padding:24px 32px 32px;position:absolute;right:0;top:72px;width:280px}.block-editor-block-patterns-explorer__sidebar__categories-list__item{display:block;height:48px;text-align:right;width:100%}.block-editor-block-patterns-explorer__search{margin-bottom:32px}.block-editor-block-patterns-explorer__search-results-count{padding-bottom:32px}.block-editor-block-patterns-explorer__list{margin-right:280px;padding:24px 0 32px}.block-editor-block-patterns-explorer__list .block-editor-patterns__sync-status-filter .components-input-control__container{width:380px}.block-editor-block-patterns-explorer .block-editor-block-patterns-list{display:grid;grid-gap:32px;grid-template-columns:repeat(1,1fr);margin-bottom:16px}@media (min-width:1080px){.block-editor-block-patterns-explorer .block-editor-block-patterns-list{grid-template-columns:repeat(2,1fr)}}@media (min-width:1440px){.block-editor-block-patterns-explorer .block-editor-block-patterns-list{grid-template-columns:repeat(3,1fr)}}.block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{min-height:240px}.block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{height:inherit;max-height:800px;min-height:100px}.components-heading.block-editor-inserter__patterns-category-panel-title{font-weight:500}.block-editor-inserter__media-library-button.components-button,.block-editor-inserter__patterns-explore-button.components-button{justify-content:center;margin-top:16px;padding:16px;width:100%}.block-editor-inserter__media-panel{display:flex;flex-direction:column;min-height:100%;padding:0 16px}@media (min-width:782px){.block-editor-inserter__media-panel{padding:0}}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-spinner{align-items:center;display:flex;flex:1;height:100%;justify-content:center}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{margin-bottom:24px}@media (min-width:782px){.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{margin-bottom:0;padding:16px 24px}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search:not(:focus-within){--wp-components-color-background:#fff}}.block-editor-inserter__media-list__list-item{cursor:pointer;margin-bottom:24px;position:relative}.block-editor-inserter__media-list__list-item.is-placeholder{min-height:100px}.block-editor-inserter__media-list__list-item[draggable=true] .block-editor-inserter__media-list__list-item{cursor:grab}.block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview>*{outline-color:#0000004d}.block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview-options>button{display:block}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options{left:8px;position:absolute;top:8px}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button{background:#fff;display:none}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button.is-opened,.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:focus{display:block}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:hover{box-shadow:inset 0 0 0 2px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-inserter__media-list__item{height:100%}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview{align-items:center;border-radius:2px;display:flex;overflow:hidden}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview>*{margin:0 auto;max-width:100%;outline:1px solid #0000001a;outline-offset:-1px}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview .block-editor-inserter__media-list__item-preview-spinner{align-items:center;background:#ffffffb3;display:flex;height:100%;justify-content:center;pointer-events:none;position:absolute;width:100%}.block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{outline-color:var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}@media not (prefers-reduced-motion){.block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{transition:outline .1s linear}}.block-editor-inserter__media-list__item-preview-options__popover .components-menu-item__button .components-menu-item__item{min-width:auto}.block-editor-inserter__mobile-tab-navigation{height:100%;padding:16px}.block-editor-inserter__mobile-tab-navigation>*{height:100%}@media (min-width:600px){.block-editor-inserter-media-tab-media-preview-inserter-external-image-modal{max-width:480px}}.block-editor-inserter-media-tab-media-preview-inserter-external-image-modal p{margin:0}.block-editor-inserter__hint{margin:16px 16px 0}.block-editor-patterns__sync-status-filter .components-input-control__container select.components-select-control__input{height:40px}.block-editor-inserter__pattern-panel-placeholder{display:none}.block-editor-inserter__menu.is-zoom-out{display:flex}@media (min-width:782px){.block-editor-inserter__menu.is-zoom-out.show-panel:after{content:"";display:block;height:100%;width:300px}}@media (max-width:959px){.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{flex-direction:column}}.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{flex-direction:column}.block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{display:none;padding:0 24px 16px}@media (min-width:480px){.block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{display:block}}.spacing-sizes-control .spacing-sizes-control__custom-value-input,.spacing-sizes-control .spacing-sizes-control__label{margin-bottom:0}.spacing-sizes-control .spacing-sizes-control__custom-value-range,.spacing-sizes-control .spacing-sizes-control__range-control{flex:1;margin-bottom:0}.spacing-sizes-control__header{height:16px;margin-bottom:12px}.spacing-sizes-control__dropdown{height:24px}.spacing-sizes-control__custom-select-control,.spacing-sizes-control__custom-value-input{flex:1}.spacing-sizes-control__custom-toggle,.spacing-sizes-control__icon{flex:0 0 auto}.spacing-sizes-control__icon{margin-right:-4px}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:18px;line-height:1.5;--wp--style--block-gap:2em}p{line-height:1.8}.editor-post-title__block{font-size:2.5em;font-weight:800;margin-bottom:1em;margin-top:2em}:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-block-icon{align-items:center;display:flex;height:24px;justify-content:center;width:24px}.block-editor-block-icon.has-colors svg{fill:currentColor}@media (forced-colors:active){.block-editor-block-icon.has-colors svg{fill:CanvasText}}.block-editor-block-icon svg{max-height:24px;max-width:24px;min-height:20px;min-width:20px}.block-editor-block-styles .block-editor-block-list__block{margin:0}@keyframes selection-overlay__fade-in-animation{0%{opacity:0}to{opacity:.4}}:root .block-editor-block-list__layout::selection,:root [data-has-multi-selection=true] .block-editor-block-list__layout::selection,_::-webkit-full-page-media,_:future{background-color:initial}.block-editor-block-list__layout{position:relative}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) ::selection,.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected)::selection{background:#0000}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{background:var(--wp-admin-theme-color);bottom:0;content:"";left:0;opacity:.4;outline:2px solid #0000;pointer-events:none;position:absolute;right:0;top:0;z-index:1}@media not (prefers-reduced-motion){.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected):after{animation:selection-overlay__fade-in-animation .1s ease-out;animation-fill-mode:forwards}}.block-editor-block-list__layout .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected).is-highlighted:after{outline-color:#0000}.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus{outline:none}.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted:after,.block-editor-block-list__layout .block-editor-block-list__block.is-highlighted~.is-multi-selected:after,.block-editor-block-list__layout .block-editor-block-list__block:not([contenteditable=true]):focus:after{bottom:0;content:"";left:0;outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);pointer-events:none;position:absolute;right:0;top:0;z-index:1}.block-editor-block-list__layout [class^=components-]{-webkit-user-select:text;user-select:text}.block-editor-block-list__layout .block-editor-block-list__block{overflow-wrap:break-word;pointer-events:auto;position:relative}.block-editor-block-list__layout .block-editor-block-list__block.is-editing-disabled{pointer-events:none}.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.has-child-selected,.block-editor-block-list__layout .block-editor-block-list__block.has-negative-margin.is-selected{z-index:20}.block-editor-block-list__layout .block-editor-block-list__block .reusable-block-edit-panel *{z-index:1}.block-editor-block-list__layout .block-editor-block-list__block .components-placeholder .components-with-notices-ui{margin:-10px 0 12px}.block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui{margin:0 0 12px;width:100%}.block-editor-block-list__layout .block-editor-block-list__block .components-with-notices-ui .components-notice .components-notice__content{font-size:13px}.block-editor-block-list__layout .block-editor-block-list__block.has-warning{min-height:48px}.block-editor-block-list__layout .block-editor-block-list__block.has-warning>*{pointer-events:none;-webkit-user-select:none;user-select:none}.block-editor-block-list__layout .block-editor-block-list__block.has-warning .block-editor-warning{pointer-events:all}.block-editor-block-list__layout .block-editor-block-list__block.has-warning:after{background-color:#fff6;bottom:0;content:"";left:0;position:absolute;right:0;top:0}.block-editor-block-list__layout .block-editor-block-list__block.has-warning.is-multi-selected:after{background-color:initial}.block-editor-block-list__layout .block-editor-block-list__block.is-reusable.has-child-selected:after{box-shadow:0 0 0 1px var(--wp-admin-theme-color)}.block-editor-block-list__layout .block-editor-block-list__block[data-clear=true]{float:none}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected{cursor:default}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered.rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected .rich-text,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-selected.rich-text{cursor:auto}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-hovered:not(.is-selected):after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline):not(.rich-text):not([contenteditable=true]).is-selected:after{bottom:0;content:"";left:0;outline-color:var(--wp-admin-theme-color);outline-offset:calc(((-1*var(--wp-admin-border-width-focus))/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);outline-style:solid;outline-width:calc((var(--wp-admin-border-width-focus)/var(--wp-block-editor-iframe-zoom-out-scale, 1))*1);pointer-events:none;position:absolute;right:0;top:0}.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).is-reusable.is-selected:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.block-editor-block-list__block:not([contenteditable]):focus:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-highlighted:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-hovered:after,.is-outline-mode .block-editor-block-list__block:not(.remove-outline).wp-block-template-part.is-selected:after{outline-color:var(--wp-block-synced-color)}@keyframes block-editor-is-editable__animation{0%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}to{background-color:rgba(var(--wp-admin-theme-color--rgb),0)}}@keyframes block-editor-is-editable__animation_reduce-motion{0%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}99%{background-color:rgba(var(--wp-admin-theme-color--rgb),.1)}to{background-color:rgba(var(--wp-admin-theme-color--rgb),0)}}.is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{animation-delay:.1s;animation-duration:.8s;animation-fill-mode:backwards;animation-name:block-editor-is-editable__animation;animation-timing-function:ease-out;bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0}@media (prefers-reduced-motion:reduce){.is-root-container:not([inert]) .block-editor-block-list__block.is-selected .block-editor-block-list__block.has-editable-outline:after{animation-delay:0s;animation-name:block-editor-is-editable__animation_reduce-motion}}.is-focus-mode .block-editor-block-list__block:not(.has-child-selected){opacity:.2}@media not (prefers-reduced-motion){.is-focus-mode .block-editor-block-list__block:not(.has-child-selected){transition:opacity .1s linear}}.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked-temporarily-editing-as-blocks.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected,.is-focus-mode .block-editor-block-list__block.is-content-locked.has-child-selected .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected) .block-editor-block-list__block,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-multi-selected,.is-focus-mode .block-editor-block-list__block:not(.has-child-selected).is-selected{opacity:1}.wp-block.alignleft,.wp-block.alignright,.wp-block[data-align=left]>*,.wp-block[data-align=right]>*{z-index:21}.wp-site-blocks>[data-align=left]{float:left;margin-right:2em}.wp-site-blocks>[data-align=right]{float:right;margin-left:2em}.wp-site-blocks>[data-align=center]{justify-content:center;margin-left:auto;margin-right:auto}.block-editor-block-list .block-editor-inserter{cursor:move;cursor:grab;margin:8px}@keyframes block-editor-inserter__toggle__fade-in-animation{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.wp-block .block-list-appender .block-editor-inserter__toggle{animation:block-editor-inserter__toggle__fade-in-animation .1s ease;animation-fill-mode:forwards}}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender{display:none}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected) .block-editor-default-block-appender .block-editor-inserter__toggle{opacity:0;transform:scale(0)}.block-editor-block-list__block .block-editor-block-list__block-html-textarea{border:none;border-radius:2px;box-shadow:inset 0 0 0 1px #1e1e1e;display:block;font-family:Menlo,Consolas,monaco,monospace;font-size:15px;line-height:1.5;margin:0;outline:none;overflow:hidden;padding:12px;resize:none;width:100%}@media not (prefers-reduced-motion){.block-editor-block-list__block .block-editor-block-list__block-html-textarea{transition:padding .2s linear}}.block-editor-block-list__block .block-editor-block-list__block-html-textarea:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-block-list__block .block-editor-warning{position:relative;z-index:5}.block-editor-block-list__block .block-editor-warning.block-editor-block-list__block-crash-warning{margin-bottom:auto}.block-editor-block-list__zoom-out-separator{align-items:center;background:#ddd;color:#000;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;font-weight:400;justify-content:center;margin-left:-1px;margin-right:-1px;overflow:hidden}@media not (prefers-reduced-motion){.block-editor-block-list__zoom-out-separator{transition:background-color .3s ease}}.is-zoomed-out .block-editor-block-list__zoom-out-separator{font-size:calc(13px/var(--wp-block-editor-iframe-zoom-out-scale))}.block-editor-block-list__zoom-out-separator.is-dragged-over{background:#ccc}.block-editor-block-list__layout.is-root-container.has-global-padding>.block-editor-block-list__zoom-out-separator,.has-global-padding>.block-editor-block-list__zoom-out-separator{margin:0 calc(var(--wp--style--root--padding-right)*-1 - 1px) 0 calc(var(--wp--style--root--padding-left)*-1 - 1px)!important;max-width:none}.is-dragging{cursor:grabbing}.is-vertical .block-list-appender{margin-left:12px;margin-right:auto;margin-top:12px;width:24px}.block-list-appender>.block-editor-inserter{display:block}.block-editor-block-list__block:not(.is-selected):not(.has-child-selected):not(.block-editor-block-list__layout) .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle{opacity:0;transform:scale(0)}.block-editor-block-list__block.has-block-overlay{cursor:default}.block-editor-block-list__block.has-block-overlay .block-editor-block-list__block{pointer-events:none}.block-editor-block-list__block.has-block-overlay .block-editor-block-list__block.has-block-overlay:before{left:0;right:0;width:auto}.block-editor-block-list__layout .is-dragging{border-radius:2px!important;opacity:.1!important}.block-editor-block-list__layout .is-dragging iframe{pointer-events:none}.block-editor-block-list__layout .is-dragging::selection{background:#0000!important}.block-editor-block-list__layout .is-dragging:after{content:none!important}.wp-block img:not([draggable]),.wp-block svg:not([draggable]){pointer-events:none}.block-editor-block-preview__content-iframe .block-list-appender{display:none}.block-editor-block-preview__live-content *{pointer-events:none}.block-editor-block-preview__live-content .block-list-appender{display:none}.block-editor-block-preview__live-content .components-button:disabled{opacity:1}.block-editor-block-preview__live-content .block-editor-block-list__block[data-empty=true],.block-editor-block-preview__live-content .components-placeholder{display:none}.block-editor-block-variation-picker__skip,.block-editor-block-variation-picker__variations,.wp-block-group-placeholder__variations{display:flex;flex-direction:row;flex-wrap:wrap;font-size:12px;gap:8px;justify-content:flex-start;list-style:none;margin:0;padding:0;width:100%}.block-editor-block-variation-picker__skip svg,.block-editor-block-variation-picker__variations svg,.wp-block-group-placeholder__variations svg{fill:#949494!important}.block-editor-block-variation-picker__skip .components-button,.block-editor-block-variation-picker__variations .components-button,.wp-block-group-placeholder__variations .components-button{padding:4px}.block-editor-block-variation-picker__skip .components-button:hover,.block-editor-block-variation-picker__variations .components-button:hover,.wp-block-group-placeholder__variations .components-button:hover{background:none!important}.block-editor-block-variation-picker__skip .components-button:hover svg,.block-editor-block-variation-picker__variations .components-button:hover svg,.wp-block-group-placeholder__variations .components-button:hover svg{fill:var(--wp-admin-theme-color)!important}.block-editor-block-variation-picker__skip>li,.block-editor-block-variation-picker__variations>li,.wp-block-group-placeholder__variations>li{align-items:center;display:flex;flex-direction:column;gap:4px;width:auto}.block-editor-button-block-appender{align-items:center;box-shadow:inset 0 0 0 1px #1e1e1e;color:#1e1e1e;display:flex;flex-direction:column;height:auto;justify-content:center;width:100%}.is-dark-theme .block-editor-button-block-appender{box-shadow:inset 0 0 0 1px #ffffffa6;color:#ffffffa6}.block-editor-button-block-appender:hover{box-shadow:inset 0 0 0 1px var(--wp-admin-theme-color);color:var(--wp-admin-theme-color)}.block-editor-button-block-appender:focus{box-shadow:inset 0 0 0 2px var(--wp-admin-theme-color)}.block-editor-button-block-appender:active{color:#000}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child{pointer-events:none}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child:after{border:1px dashed;bottom:0;content:"";left:0;pointer-events:none;position:absolute;right:0;top:0}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter{opacity:0}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child .block-editor-inserter:focus-within{opacity:1}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over:after,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over:after{border:none}.block-editor-block-list__block:not(.is-selected)>.is-layout-constrained.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.block-editor-block-list__block:not(.is-selected)>.is-layout-flow.wp-block-group__inner-container>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-constrained.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter,.is-layout-flow.block-editor-block-list__block:not(.is-selected)>.block-list-appender:only-child.is-drag-over .block-editor-inserter{visibility:visible}.block-editor-block-list__block:not(.is-selected)>.block-editor-block-list__block>.block-list-appender:only-child:after{border:none}.block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{background-color:var(--wp-admin-theme-color);box-shadow:inset 0 0 0 1px #ffffffa6;color:#ffffffa6}@media not (prefers-reduced-motion){.block-list-appender:only-child.is-drag-over .block-editor-button-block-appender{transition:background-color .2s ease-in-out}}.block-editor-default-block-appender{clear:both;margin-left:auto;margin-right:auto;position:relative}.block-editor-default-block-appender[data-root-client-id=""] .block-editor-default-block-appender__content:hover{outline:1px solid #0000}.block-editor-default-block-appender .block-editor-default-block-appender__content{margin-block-end:0;margin-block-start:0;opacity:.62}.block-editor-default-block-appender .components-drop-zone__content-icon{display:none}.block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon{background:#1e1e1e;color:#fff;height:24px;min-width:24px;padding:0}.block-editor-default-block-appender .block-editor-inserter__toggle.components-button.has-icon:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-default-block-appender .block-editor-inserter{line-height:0;position:absolute;right:0;top:0}.block-editor-default-block-appender .block-editor-inserter:disabled{display:none}.block-editor-block-list__block .block-list-appender{bottom:0;list-style:none;padding:0;position:absolute;right:0;z-index:2}.block-editor-block-list__block .block-list-appender.block-list-appender{line-height:0;margin:0}.block-editor-block-list__block .block-list-appender .block-editor-inserter:disabled{display:none}.block-editor-block-list__block .block-list-appender .block-editor-default-block-appender{height:24px}.block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle{background:#1e1e1e;box-shadow:none;color:#fff;display:none;flex-direction:row;height:24px;min-width:24px;padding:0!important;width:24px}.block-editor-block-list__block .block-list-appender .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__block .block-list-appender .block-list-appender__toggle:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-block-list__block .block-list-appender .block-editor-default-block-appender__content{display:none}.block-editor-block-list__block .block-list-appender:only-child{align-self:center;line-height:inherit;list-style:none;position:relative;right:auto}.block-editor-block-list__block .block-list-appender:only-child .block-editor-default-block-appender__content{display:block}.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected .block-editor-block-list__layout>.block-list-appender .block-list-appender__toggle,.block-editor-block-list__block.is-selected>.block-list-appender .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__block.is-selected>.block-list-appender .block-list-appender__toggle{display:flex}.block-editor-default-block-appender__content{cursor:text}.block-editor-iframe__body{position:relative}.block-editor-iframe__html{transform-origin:top center}@media not (prefers-reduced-motion){.block-editor-iframe__html{transition:background-color .4s}}.block-editor-iframe__html.zoom-out-animation{bottom:0;left:0;overflow-y:var(--wp-block-editor-iframe-zoom-out-overflow-behavior,scroll);position:fixed;right:0;top:calc(var(--wp-block-editor-iframe-zoom-out-scroll-top, 0)*-1)}.block-editor-iframe__html.is-zoomed-out{background-color:#ddd;margin-bottom:calc(var(--wp-block-editor-iframe-zoom-out-content-height)*(1 - var(--wp-block-editor-iframe-zoom-out-scale, 1))*-1 + var(--wp-block-editor-iframe-zoom-out-frame-size, 0)*2/var(--wp-block-editor-iframe-zoom-out-scale, 1)*-1 + -2px);padding-bottom:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1));padding-top:calc(var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1));scale:var(--wp-block-editor-iframe-zoom-out-scale,1);transform:translateX(calc((var(--wp-block-editor-iframe-zoom-out-scale-container-width) - var(--wp-block-editor-iframe-zoom-out-container-width, 100vw))/2/var(--wp-block-editor-iframe-zoom-out-scale, 1)))}.block-editor-iframe__html.is-zoomed-out body{min-height:calc((var(--wp-block-editor-iframe-zoom-out-inner-height) - 2*var(--wp-block-editor-iframe-zoom-out-frame-size, 0)/var(--wp-block-editor-iframe-zoom-out-scale, 1))/var(--wp-block-editor-iframe-zoom-out-scale, 1))}.block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content){display:flex;flex:1;flex-direction:column;height:100%}.block-editor-iframe__html.is-zoomed-out body>.is-root-container:not(.wp-block-post-content)>main{flex:1}.block-editor-iframe__html.is-zoomed-out .wp-block[draggable]{cursor:grab}.block-editor-media-placeholder__cancel-button.is-link{display:block;margin:1em}.block-editor-media-placeholder.is-appender{min-height:0}.block-editor-media-placeholder.is-appender:hover{box-shadow:0 0 0 1px var(--wp-admin-theme-color);cursor:pointer}.block-editor-plain-text{border:none;box-shadow:none;color:inherit;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;padding:0;width:100%}.rich-text [data-rich-text-placeholder]{pointer-events:none}.rich-text [data-rich-text-placeholder]:after{content:attr(data-rich-text-placeholder);opacity:.62}.rich-text:focus{outline:none}figcaption.block-editor-rich-text__editable [data-rich-text-placeholder]:before{opacity:.8}[data-rich-text-script]{display:inline}[data-rich-text-script]:before{background:#ff0;content:"</>"}[data-rich-text-comment],[data-rich-text-format-boundary]{border-radius:2px}[data-rich-text-comment]{background-color:currentColor}[data-rich-text-comment] span{color:currentColor;filter:invert(100%);padding:0 2px}.block-editor-warning{align-items:center;background-color:#fff;border:1px solid #1e1e1e;border-radius:2px;display:flex;flex-wrap:wrap;padding:1em}.block-editor-warning,.block-editor-warning .block-editor-warning__message{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.block-editor-warning .block-editor-warning__message{color:#1e1e1e;font-size:13px;line-height:1.4;margin:0}.block-editor-warning p.block-editor-warning__message.block-editor-warning__message{min-height:auto}.block-editor-warning .block-editor-warning__contents{align-items:baseline;display:flex;flex-direction:row;flex-wrap:wrap;gap:12px;justify-content:space-between;width:100%}.block-editor-warning .block-editor-warning__actions{align-items:center;display:flex;gap:8px}.components-popover.block-editor-warning__dropdown{z-index:99998}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } body{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:18px; line-height:1.5; --wp--style--block-gap:2em; } p{ line-height:1.8; } .editor-post-title__block{ font-size:2.5em; font-weight:800; margin-bottom:1em; margin-top:2em; }:root{--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,161;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px;--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color)}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.block-editor-autocompleters__block{white-space:nowrap}.block-editor-autocompleters__block .block-editor-block-icon{margin-right:8px}.block-editor-autocompleters__block[aria-selected=true] .block-editor-block-icon{color:inherit!important}.block-editor-autocompleters__link{white-space:nowrap}.block-editor-autocompleters__link .block-editor-block-icon{margin-right:8px}.block-editor-global-styles-background-panel__inspector-media-replace-container{border:1px solid #ddd;border-radius:2px;grid-column:1/-1}.block-editor-global-styles-background-panel__inspector-media-replace-container.is-open{background-color:#f0f0f0}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item{border:0;flex-grow:1}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{display:block}.block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__inspector-preview-inner{height:100%}.block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown{display:block}.block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown .block-editor-global-styles-background-panel__dropdown-toggle{height:40px}.block-editor-global-styles-background-panel__image-tools-panel-item{border:1px solid #ddd;grid-column:1/-1;position:relative}.block-editor-global-styles-background-panel__image-tools-panel-item .components-drop-zone__content-icon{display:none}.block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{display:block}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button{color:#1e1e1e;display:block;width:100%}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:hover{color:var(--wp-admin-theme-color)}.block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading{height:100%;padding:10px 0 0;position:absolute;width:100%;z-index:1}.block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading svg{margin:0}.block-editor-global-styles-background-panel__dropdown-toggle,.block-editor-global-styles-background-panel__image-preview-content{height:100%;padding-left:12px;width:100%}.block-editor-global-styles-background-panel__dropdown-toggle{background:#0000;border:none;cursor:pointer}.block-editor-global-styles-background-panel__inspector-media-replace-title{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-editor-global-styles-background-panel__inspector-preview-inner .block-editor-global-styles-background-panel__inspector-image-indicator-wrapper{height:20px;min-width:auto;width:20px}.block-editor-global-styles-background-panel__inspector-image-indicator{background-size:cover;border-radius:50%;display:block;height:20px;position:relative;width:20px}.block-editor-global-styles-background-panel__inspector-image-indicator:after{border:1px solid #0000;border-radius:50%;bottom:-1px;box-shadow:inset 0 0 0 1px #0003;box-sizing:inherit;content:"";left:-1px;position:absolute;right:-1px;top:-1px}.block-editor-global-styles-background-panel__dropdown-content-wrapper{min-width:260px;overflow-x:hidden}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker-wrapper{background-color:#f0f0f0;border:1px solid #ddd;border-radius:2px;width:100%}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker__media--image{max-height:180px}.block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker:after{content:none}.modal-open .block-editor-global-styles-background-panel__popover{z-index:159890}.block-editor-global-styles-background-panel__media-replace-popover .components-popover__content{width:226px}.block-editor-global-styles-background-panel__media-replace-popover .components-button{padding:0 8px}.block-editor-global-styles-background-panel__media-replace-popover .components-button .components-menu-items__item-icon.has-icon-right{margin-left:16px}.block-editor-block-alignment-control__menu-group .components-menu-item__info{margin-top:0}iframe[name=editor-canvas]{background-color:#ddd;box-sizing:border-box;display:block;height:100%;width:100%}@media not (prefers-reduced-motion){iframe[name=editor-canvas]{transition:all .4s cubic-bezier(.46,.03,.52,.96)}}.block-editor-block-icon{align-items:center;display:flex;height:24px;justify-content:center;width:24px}.block-editor-block-icon.has-colors svg{fill:currentColor}@media (forced-colors:active){.block-editor-block-icon.has-colors svg{fill:CanvasText}}.block-editor-block-icon svg{max-height:24px;max-width:24px;min-height:20px;min-width:20px}.block-editor-block-inspector p:not(.components-base-control__help){margin-top:0}.block-editor-block-inspector h2,.block-editor-block-inspector h3{color:#1e1e1e;font-size:13px;margin-bottom:1.5em}.block-editor-block-inspector .components-base-control:where(:not(:last-child)),.block-editor-block-inspector .components-radio-control:where(:not(:last-child)){margin-bottom:16px}.block-editor-block-inspector .components-focal-point-picker-control .components-base-control,.block-editor-block-inspector .components-query-controls .components-base-control,.block-editor-block-inspector .components-range-control .components-base-control{margin-bottom:0}.block-editor-block-inspector .components-panel__body{border:none;border-top:1px solid #e0e0e0;margin-top:-1px}.block-editor-block-inspector__no-block-tools,.block-editor-block-inspector__no-blocks{background:#fff;display:block;font-size:13px;padding:32px 16px;text-align:center}.block-editor-block-inspector__no-block-tools{border-top:1px solid #ddd}.block-editor-block-list__insertion-point{bottom:0;left:0;position:absolute;right:0;top:0}.block-editor-block-list__insertion-point-indicator{background:var(--wp-admin-theme-color);border-radius:2px;opacity:0;position:absolute;transform-origin:center;will-change:transform,opacity}.block-editor-block-list__insertion-point.is-vertical>.block-editor-block-list__insertion-point-indicator{height:4px;top:calc(50% - 2px);width:100%}.block-editor-block-list__insertion-point.is-horizontal>.block-editor-block-list__insertion-point-indicator{bottom:0;left:calc(50% - 2px);top:0;width:4px}.block-editor-block-list__insertion-point-inserter{display:none;justify-content:center;left:calc(50% - 12px);position:absolute;top:calc(50% - 12px);will-change:transform}@media (min-width:480px){.block-editor-block-list__insertion-point-inserter{display:flex}}.block-editor-block-list__block-side-inserter-popover .components-popover__content>div{pointer-events:none}.block-editor-block-list__block-side-inserter-popover .components-popover__content>div>*{pointer-events:all}.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter{line-height:0;position:absolute;right:0;top:0}.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter:disabled{display:none}.block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{background:#1e1e1e;color:#fff;height:24px;min-width:24px;padding:0}.block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{background:var(--wp-admin-theme-color);color:#fff}.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{background:var(--wp-admin-theme-color)}.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{background:#1e1e1e}@keyframes hide-during-dragging{to{position:fixed;transform:translate(9999px,9999px)}}.components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar{border:1px solid #1e1e1e;border-radius:2px;margin-bottom:8px;margin-top:8px;overflow:visible;pointer-events:all;position:static;width:auto}.components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{margin-left:56px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{margin-left:0}.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar{overflow:visible}.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar-group{border-right-color:#1e1e1e}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar{background-color:#1e1e1e;color:#f0f0f0}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar.block-editor-block-contextual-toolbar{border-color:#2f2f2f}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button{color:#ddd}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:hover{color:#fff}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:focus:before{box-shadow:inset 0 0 0 1px #1e1e1e,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:disabled,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button[aria-disabled=true]{color:#757575}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-parent-selector .block-editor-block-parent-selector__button{background-color:#1e1e1e;border-color:#2f2f2f}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-switcher__toggle{color:#f0f0f0}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar-group{border-right-color:#2f2f2f!important}.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .is-pressed{color:var(--wp-admin-theme-color)}.components-popover.block-editor-block-list__block-popover.is-insertion-point-visible{visibility:hidden}.is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{opacity:0}@media not (prefers-reduced-motion){.is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{animation:hide-during-dragging 1ms linear forwards}}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{left:-57px;position:absolute}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector:before{content:""}.components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{background-color:#fff;border:1px solid #1e1e1e;padding-left:6px;padding-right:6px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{padding-left:12px;padding-right:12px}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{left:auto;margin-left:-1px;position:relative}.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-mover__move-button-container,.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar__block-controls .block-editor-block-mover{border-left:1px solid #1e1e1e}.is-dragging-components-draggable .components-tooltip{display:none}.components-popover.block-editor-block-popover__inbetween .block-editor-button-pattern-inserter__button{left:50%;pointer-events:all;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%)}.block-editor-block-lock-modal{z-index:1000001}@media (min-width:600px){.block-editor-block-lock-modal .components-modal__frame{max-width:480px}}.block-editor-block-lock-modal__options legend{margin-bottom:16px;padding:0}.block-editor-block-lock-modal__checklist{margin:0}.block-editor-block-lock-modal__options-all{padding:12px 0}.block-editor-block-lock-modal__options-all .components-checkbox-control__label{font-weight:600}.block-editor-block-lock-modal__checklist-item{align-items:center;display:flex;gap:12px;justify-content:space-between;margin-bottom:0;padding:12px 0 12px 32px}.block-editor-block-lock-modal__checklist-item .block-editor-block-lock-modal__lock-icon{flex-shrink:0;margin-right:12px;fill:#1e1e1e}.block-editor-block-lock-modal__checklist-item:hover{background-color:#f0f0f0;border-radius:2px}.block-editor-block-lock-modal__template-lock{border-top:1px solid #ddd;margin-top:16px;padding-top:16px}.block-editor-block-lock-modal__actions{margin-top:24px}.block-editor-block-lock-toolbar .components-button.has-icon{min-width:36px!important}.block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{margin-left:-6px!important}.show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{border-left:1px solid #1e1e1e;margin-left:6px!important;margin-right:-6px}.block-editor-block-breadcrumb{list-style:none;margin:0;padding:0}.block-editor-block-breadcrumb li{display:inline-flex;margin:0}.block-editor-block-breadcrumb li .block-editor-block-breadcrumb__separator{fill:currentColor;margin-left:-4px;margin-right:-4px;transform:scaleX(1)}.block-editor-block-breadcrumb li:last-child .block-editor-block-breadcrumb__separator{display:none}.block-editor-block-breadcrumb__current{cursor:default}.block-editor-block-breadcrumb__button.block-editor-block-breadcrumb__button,.block-editor-block-breadcrumb__current{color:#1e1e1e;font-size:inherit;padding:0 8px}.block-editor-block-card{align-items:flex-start;color:#1e1e1e;display:flex;padding:16px}.block-editor-block-card__title{align-items:center;display:flex;flex-wrap:wrap;font-weight:500;gap:4px 8px}.block-editor-block-card__title.block-editor-block-card__title{font-size:13px;line-height:1.4;margin:0}.block-editor-block-card__name{padding:3px 0}.block-editor-block-card .block-editor-block-icon{flex:0 0 24px;height:24px;margin-left:0;margin-right:12px;width:24px}.block-editor-block-card.is-synced .block-editor-block-icon{color:var(--wp-block-synced-color)}.block-editor-block-compare{height:auto}.block-editor-block-compare__wrapper{display:flex;padding-bottom:16px}.block-editor-block-compare__wrapper>div{display:flex;flex-direction:column;justify-content:space-between;max-width:600px;min-width:200px;padding:0 16px 0 0;width:50%}.block-editor-block-compare__wrapper>div button{float:right}.block-editor-block-compare__wrapper .block-editor-block-compare__converted{border-left:1px solid #ddd;padding-left:15px;padding-right:0}.block-editor-block-compare__wrapper .block-editor-block-compare__html{border-bottom:1px solid #ddd;color:#1e1e1e;font-family:Menlo,Consolas,monaco,monospace;font-size:12px;line-height:1.7;padding-bottom:15px}.block-editor-block-compare__wrapper .block-editor-block-compare__html span{background-color:#e6ffed;padding-bottom:3px;padding-top:3px}.block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__added{background-color:#acf2bd}.block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__removed{background-color:#cc1818}.block-editor-block-compare__wrapper .block-editor-block-compare__preview{padding:16px 0 0}.block-editor-block-compare__wrapper .block-editor-block-compare__preview p{font-size:12px;margin-top:0}.block-editor-block-compare__wrapper .block-editor-block-compare__action{margin-top:16px}.block-editor-block-compare__wrapper .block-editor-block-compare__heading{font-size:1em;font-weight:400;margin:.67em 0}.block-editor-block-draggable-chip-wrapper{left:0;position:absolute;top:-24px}.block-editor-block-draggable-chip{background-color:#1e1e1e;border-radius:2px;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;color:#fff;cursor:grabbing;display:inline-flex;height:48px;padding:0 13px;position:relative;-webkit-user-select:none;user-select:none;width:max-content}.block-editor-block-draggable-chip svg{fill:currentColor}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content{justify-content:flex-start;margin:auto}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item{margin-right:6px}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item:last-child{margin-right:0}.block-editor-block-draggable-chip .block-editor-block-draggable-chip__content .block-editor-block-icon svg{min-height:18px;min-width:18px}.block-editor-block-draggable-chip .components-flex__item{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{align-items:center;background-color:initial;bottom:0;display:flex;justify-content:center;left:0;opacity:0;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{transition:all .1s linear .1s}}.block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled .block-editor-block-draggable-chip__disabled-icon{background:#0000 linear-gradient(-45deg,#0000 47.5%,#fff 0,#fff 52.5%,#0000 0);border-radius:50%;box-shadow:inset 0 0 0 1.5px #fff;display:inline-block;height:20px;padding:0;width:20px}.block-draggable-invalid-drag-token .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{background-color:#757575;box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005;opacity:1}.block-editor-block-manager__no-results{font-style:italic;padding:24px 0;text-align:center}.block-editor-block-manager__search{margin:16px 0}.block-editor-block-manager__disabled-blocks-count{background-color:#fff;border:1px solid #ddd;border-width:1px 0;box-shadow:-32px 0 0 0 #fff,32px 0 0 0 #fff;padding:8px;position:sticky;text-align:center;top:-5px;z-index:2}.block-editor-block-manager__disabled-blocks-count~.block-editor-block-manager__results .block-editor-block-manager__category-title{top:31px}.block-editor-block-manager__disabled-blocks-count .is-link{margin-left:12px}.block-editor-block-manager__category{margin:0 0 24px}.block-editor-block-manager__category-title{background-color:#fff;padding:16px 0;position:sticky;top:-4px;z-index:1}.block-editor-block-manager__category-title .components-checkbox-control__label{font-weight:600}.block-editor-block-manager__checklist{margin-top:0}.block-editor-block-manager__category-title,.block-editor-block-manager__checklist-item{border-bottom:1px solid #ddd}.block-editor-block-manager__checklist-item{align-items:center;display:flex;justify-content:space-between;margin-bottom:0;padding:8px 0 8px 16px}.components-modal__content .block-editor-block-manager__checklist-item.components-checkbox-control__input-container{margin:0 8px}.block-editor-block-manager__checklist-item .block-editor-block-icon{margin-right:10px;fill:#1e1e1e}.block-editor-block-manager__results{border-top:1px solid #ddd}.block-editor-block-manager__disabled-blocks-count+.block-editor-block-manager__results{border-top-width:0}.block-editor-block-mover__move-button-container{border:none;display:flex;justify-content:center;padding:0}@media (min-width:600px){.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{flex-direction:column}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>*{height:20px;min-width:0!important;width:100%}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>:before{height:calc(100% - 4px)}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{flex-shrink:0;top:3px}.block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{bottom:3px;flex-shrink:0}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{width:48px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container>*{min-width:0!important;overflow:hidden;width:24px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button{padding-left:0;padding-right:0}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{left:5px}.block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{right:5px}}.block-editor-block-mover__drag-handle{cursor:grab}@media (min-width:600px){.block-editor-block-mover__drag-handle{min-width:0!important;overflow:hidden;width:24px}.block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon.has-icon{padding-left:0;padding-right:0}}.components-button.block-editor-block-mover-button{overflow:hidden}.components-button.block-editor-block-mover-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.components-button.block-editor-block-mover-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.components-button.block-editor-block-mover-button:focus,.components-button.block-editor-block-mover-button:focus:before,.components-button.block-editor-block-mover-button:focus:enabled{box-shadow:none;outline:none}.components-button.block-editor-block-mover-button:focus-visible:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-navigation__container{min-width:280px}.block-editor-block-navigation__label{color:#757575;font-size:11px;font-weight:500;margin:0 0 12px;text-transform:uppercase}.block-editor-block-patterns-list__list-item{cursor:pointer;margin-bottom:16px;position:relative}.block-editor-block-patterns-list__list-item.is-placeholder{min-height:100px}.block-editor-block-patterns-list__list-item[draggable=true]{cursor:grab}.block-editor-block-patterns-list__item{height:100%;outline:0;scroll-margin-bottom:56px;scroll-margin-top:24px}.block-editor-block-patterns-list__item .block-editor-block-patterns-list__item-title{flex-grow:1;font-size:12px;text-align:left}.block-editor-block-patterns-list__item .block-editor-block-preview__container{align-items:center;border-radius:4px;display:flex;overflow:hidden}.block-editor-block-patterns-list__item .block-editor-block-preview__container:after{border-radius:4px;outline:1px solid #0000001a;outline-offset:-1px}@media not (prefers-reduced-motion){.block-editor-block-patterns-list__item .block-editor-block-preview__container:after{transition:outline .1s linear}}.block-editor-block-patterns-list__item.is-selected .block-editor-block-preview__container:after{outline-color:#1e1e1e;outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}.block-editor-block-patterns-list__item:hover .block-editor-block-preview__container:after{outline-color:#0000004d}.block-editor-block-patterns-list__item[data-focus-visible] .block-editor-block-preview__container:after{outline-color:var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-details:not(:empty){align-items:center;margin-top:8px;padding-bottom:4px}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper{height:24px;min-width:24px}.block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper .block-editor-patterns__pattern-icon{fill:var(--wp-block-synced-color)}.block-editor-patterns__grid-pagination-wrapper .block-editor-patterns__grid-pagination{border-top:1px solid #2f2f2f;justify-content:center;padding:4px}.show-icon-labels .block-editor-patterns__grid-pagination-button{width:auto}.show-icon-labels .block-editor-patterns__grid-pagination-button span{display:none}.show-icon-labels .block-editor-patterns__grid-pagination-button:before{content:attr(aria-label)}.components-popover.block-editor-block-popover{margin:0!important;pointer-events:none;position:absolute;z-index:31}.components-popover.block-editor-block-popover .components-popover__content{margin:0!important;min-width:auto;overflow-y:visible;width:max-content}.components-popover.block-editor-block-popover:not(.block-editor-block-popover__inbetween,.block-editor-block-popover__drop-zone,.block-editor-block-list__block-side-inserter-popover) .components-popover__content *{pointer-events:all}.components-popover.block-editor-block-popover__inbetween,.components-popover.block-editor-block-popover__inbetween *{pointer-events:none}.components-popover.block-editor-block-popover__inbetween .is-with-inserter,.components-popover.block-editor-block-popover__inbetween .is-with-inserter *{pointer-events:all}.components-popover.block-editor-block-popover__drop-zone *{pointer-events:none}.components-popover.block-editor-block-popover__drop-zone .block-editor-block-popover__drop-zone-foreground{background-color:var(--wp-admin-theme-color);border-radius:2px;inset:0;position:absolute}.block-editor-block-preview__container{overflow:hidden;position:relative;width:100%}.block-editor-block-preview__container .block-editor-block-preview__content{left:0;margin:0;min-height:auto;overflow:visible;text-align:initial;top:0;transform-origin:top left;width:100%}.block-editor-block-preview__container .block-editor-block-preview__content .block-editor-block-list__insertion-point,.block-editor-block-preview__container .block-editor-block-preview__content .block-list-appender{display:none}.block-editor-block-preview__container:after{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:1}.block-editor-block-rename-modal{z-index:1000001}.block-editor-block-styles__preview-panel{display:none;z-index:90}@media (min-width:782px){.block-editor-block-styles__preview-panel{display:block}}.block-editor-block-styles__preview-panel .block-editor-block-icon{display:none}.block-editor-block-styles__variants{display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item{box-shadow:inset 0 0 0 1px #ddd;color:#1e1e1e;display:inline-block;width:calc(50% - 4px)}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:hover{box-shadow:inset 0 0 0 1px #ddd;color:var(--wp-admin-theme-color)}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover{background-color:#1e1e1e;box-shadow:none}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active .block-editor-block-styles__item-text,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover .block-editor-block-styles__item-text{color:#fff}.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:focus,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:focus{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-styles__variants .block-editor-block-styles__item-text{text-align:start;text-align-last:center;white-space:normal;word-break:break-all}.block-editor-block-styles__block-preview-container,.block-editor-block-styles__block-preview-container *{box-sizing:border-box!important}.block-editor-block-switcher{position:relative}.block-editor-block-switcher .components-button.components-dropdown-menu__toggle.has-icon.has-icon{min-width:36px}.block-editor-block-switcher__no-switcher-icon,.block-editor-block-switcher__toggle{position:relative}.components-button.block-editor-block-switcher__no-switcher-icon,.components-button.block-editor-block-switcher__toggle{display:block;height:48px;margin:0}.components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.components-button.block-editor-block-switcher__toggle .block-editor-block-icon{margin:auto}.components-button.block-editor-block-switcher__no-switcher-icon{display:flex}.components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{margin-left:auto;margin-right:auto;min-width:24px!important}.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true],.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true]:hover{color:#1e1e1e}.components-popover.block-editor-block-switcher__popover .components-popover__content{min-width:300px}.block-editor-block-switcher__popover-preview-container{bottom:0;left:0;pointer-events:none;position:absolute;top:-1px;width:100%}.block-editor-block-switcher__popover-preview{overflow:hidden}.block-editor-block-switcher__popover-preview .components-popover__content{background:#fff;border:1px solid #1e1e1e;border-radius:4px;box-shadow:none;outline:none;overflow:auto;width:300px}.block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview{margin:16px 0;max-height:468px;overflow:hidden;padding:0 16px}.block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview.is-pattern-list-preview{overflow:unset}.block-editor-block-switcher__preview-title{color:#757575;font-size:11px;font-weight:500;margin-bottom:12px;text-transform:uppercase}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon{min-width:36px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle{height:48px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{height:48px;width:48px}.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{padding:12px}.block-editor-block-switcher__preview-patterns-container{padding-bottom:16px}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item{margin-top:16px}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-preview__container{cursor:pointer}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{border:1px solid #0000;border-radius:2px;height:100%;position:relative}@media not (prefers-reduced-motion){.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{transition:all .05s ease-in-out}}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:focus,.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) #1e1e1e}.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item .block-editor-block-switcher__preview-patterns-container-list__item-title{cursor:pointer;font-size:12px;padding:4px;text-align:center}.block-editor-block-switcher__no-transforms{color:#757575;margin:0;padding:6px 8px}.block-editor-block-switcher__binding-indicator{display:block;padding:8px}.block-editor-block-types-list>[role=presentation]{display:flex;flex-wrap:wrap;overflow:hidden}.block-editor-block-pattern-setup{align-items:flex-start;border-radius:2px;display:flex;flex-direction:column;justify-content:center;width:100%}.block-editor-block-pattern-setup.view-mode-grid{padding-top:4px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar{justify-content:center}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{column-count:2;column-gap:24px;display:block;padding:0 32px;width:100%}@media (min-width:1440px){.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{column-count:3}}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button]{cursor:pointer}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item{scroll-margin:5px 0}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-preview__container{box-shadow:0 0 0 2px var(--wp-admin-theme-color)}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-preview__container{box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff,0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color);outline:2px solid #0000;outline-offset:2px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-pattern-setup-list__item-title,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-pattern-setup-list__item-title{color:var(--wp-admin-theme-color)}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item{break-inside:avoid-column;margin-bottom:24px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-pattern-setup-list__item-title{cursor:pointer;font-size:12px;padding-top:8px;text-align:center}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container{border:1px solid #ddd;border-radius:4px;min-height:100px}.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content{width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar{align-items:center;align-self:stretch;background-color:#fff;border-top:1px solid #ddd;bottom:0;box-sizing:border-box;color:#1e1e1e;display:flex;flex-direction:row;height:60px;justify-content:space-between;margin:0;padding:16px;position:absolute;text-align:left;width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls{display:flex}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions,.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__navigation{display:flex;width:calc(50% - 36px)}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions{justify-content:flex-end}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container{box-sizing:border-box;display:flex;flex-direction:column;height:100%;width:100%}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container{height:100%;list-style:none;margin:0;overflow:hidden;padding:0;position:relative;transform-style:preserve-3d}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container *{box-sizing:border-box}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{background-color:#fff;height:100%;margin:auto;padding:0;position:absolute;top:0;width:100%;z-index:100}@media not (prefers-reduced-motion){.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{transition:transform .5s,z-index .5s}}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide{opacity:1;position:relative;z-index:102}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.previous-slide{transform:translateX(-100%);z-index:101}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.next-slide{transform:translateX(100%);z-index:101}.block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .block-list-appender{display:none}.block-editor-block-pattern-setup__carousel,.block-editor-block-pattern-setup__grid{width:100%}.block-editor-block-variation-transforms{padding:0 16px 16px 52px;width:100%}.block-editor-block-variation-transforms .components-dropdown-menu__toggle{border:1px solid #757575;border-radius:2px;justify-content:left;min-height:30px;padding:6px 12px;position:relative;text-align:left;width:100%}.block-editor-block-variation-transforms .components-dropdown-menu__toggle.components-dropdown-menu__toggle{padding-right:24px}.block-editor-block-variation-transforms .components-dropdown-menu__toggle:focus:not(:disabled){border-color:var(--wp-admin-theme-color);box-shadow:0 0 0 calc(var(--wp-admin-border-width-focus) - 1px) var(--wp-admin-theme-color)}.block-editor-block-variation-transforms .components-dropdown-menu__toggle svg{height:100%;padding:0;position:absolute;right:0;top:0}.block-editor-block-variation-transforms__popover .components-popover__content{min-width:230px}.components-border-radius-control{margin-bottom:12px}.components-border-radius-control legend{margin-bottom:8px}.components-border-radius-control .components-border-radius-control__wrapper{align-items:flex-start;display:flex;justify-content:space-between}.components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__unit-control{flex-shrink:0;margin-bottom:0;margin-right:16px;width:calc(50% - 8px)}.components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__range-control{flex:1;margin-right:12px}.components-border-radius-control .components-border-radius-control__input-controls-wrapper{display:grid;gap:16px;grid-template-columns:repeat(2,minmax(0,1fr));margin-right:12px}.components-border-radius-control .component-border-radius-control__linked-button{display:flex;justify-content:center;margin-top:8px}.components-border-radius-control .component-border-radius-control__linked-button svg{margin-right:0}.block-editor-color-gradient-control .block-editor-color-gradient-control__color-indicator{margin-bottom:12px}.block-editor-color-gradient-control__fieldset{min-width:0}.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings,.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings>div:not(:first-of-type){display:block}@media screen and (min-width:782px){.block-editor-panel-color-gradient-settings .components-circular-option-picker__swatches{display:grid;grid-template-columns:repeat(6,28px)}}.block-editor-block-inspector .block-editor-panel-color-gradient-settings .components-base-control{margin-bottom:inherit}.block-editor-panel-color-gradient-settings__dropdown-content .block-editor-color-gradient-control__panel{padding:16px;width:260px}.block-editor-panel-color-gradient-settings__color-indicator{background:linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.block-editor-tools-panel-color-gradient-settings__item{border-bottom:1px solid #ddd;border-left:1px solid #ddd;border-right:1px solid #ddd;max-width:100%;padding:0;position:relative}.block-editor-tools-panel-color-gradient-settings__item:nth-child(1 of .block-editor-tools-panel-color-gradient-settings__item){border-top:1px solid #ddd;border-top-left-radius:2px;border-top-right-radius:2px;margin-top:24px}.block-editor-tools-panel-color-gradient-settings__item:nth-last-child(1 of .block-editor-tools-panel-color-gradient-settings__item){border-bottom-left-radius:2px;border-bottom-right-radius:2px}.block-editor-tools-panel-color-gradient-settings__item>div,.block-editor-tools-panel-color-gradient-settings__item>div>button{border-radius:inherit}.block-editor-tools-panel-color-gradient-settings__dropdown{display:block;padding:0}.block-editor-tools-panel-color-gradient-settings__dropdown>button{height:auto;padding-bottom:10px;padding-top:10px;text-align:left}.block-editor-tools-panel-color-gradient-settings__dropdown>button.is-open{background:#f0f0f0;color:var(--wp-admin-theme-color)}.block-editor-tools-panel-color-gradient-settings__dropdown .block-editor-panel-color-gradient-settings__color-name{max-width:calc(100% - 44px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-panel-color-gradient-settings__dropdown{width:100%}.block-editor-panel-color-gradient-settings__dropdown .component-color-indicator{flex-shrink:0}.block-editor-panel-color-gradient-settings__reset{margin:auto 8px;opacity:0;position:absolute;right:0;top:8px}@media not (prefers-reduced-motion){.block-editor-panel-color-gradient-settings__reset{transition:opacity .1s ease-in-out}}.block-editor-panel-color-gradient-settings__reset.block-editor-panel-color-gradient-settings__reset{border-radius:2px}.block-editor-panel-color-gradient-settings__dropdown:hover+.block-editor-panel-color-gradient-settings__reset,.block-editor-panel-color-gradient-settings__reset:focus,.block-editor-panel-color-gradient-settings__reset:hover{opacity:1}@media (hover:none){.block-editor-panel-color-gradient-settings__reset{opacity:1}}.block-editor-date-format-picker{border:none;margin:0 0 16px;padding:0}.block-editor-date-format-picker__custom-format-select-control__custom-option{border-top:1px solid #ddd}.block-editor-duotone-control__popover.components-popover>.components-popover__content{padding:8px;width:260px}.block-editor-duotone-control__popover.components-popover .components-menu-group__label{padding:0}.block-editor-duotone-control__popover.components-popover .components-circular-option-picker__swatches{display:grid;gap:12px;grid-template-columns:repeat(6,28px);justify-content:space-between}.block-editor-duotone-control__unset-indicator{background:linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.components-font-appearance-control [role=option]{color:#1e1e1e;text-transform:capitalize}.block-editor-font-family-control:not(.is-next-has-no-margin-bottom){margin-bottom:8px}.block-editor-global-styles__toggle-icon{fill:currentColor}.block-editor-global-styles__shadow-popover-container{width:230px}.block-editor-global-styles__shadow__list{display:flex;flex-wrap:wrap;gap:12px;padding-bottom:8px}.block-editor-global-styles__clear-shadow{text-align:right}.block-editor-global-styles-filters-panel__dropdown,.block-editor-global-styles__shadow-dropdown{display:block;padding:0;position:relative}.block-editor-global-styles-filters-panel__dropdown button,.block-editor-global-styles__shadow-dropdown button{padding:8px;width:100%}.block-editor-global-styles-filters-panel__dropdown button.is-open,.block-editor-global-styles__shadow-dropdown button.is-open{background-color:#f0f0f0}.block-editor-global-styles__shadow-editor__remove-button{margin:auto 8px;opacity:0;position:absolute;right:0;top:8px}@media not (prefers-reduced-motion){.block-editor-global-styles__shadow-editor__remove-button{transition:opacity .1s ease-in-out}}.block-editor-global-styles__shadow-dropdown:hover .block-editor-global-styles__shadow-editor__remove-button,.block-editor-global-styles__shadow-editor__remove-button:focus,.block-editor-global-styles__shadow-editor__remove-button:hover{opacity:1}@media (hover:none){.block-editor-global-styles__shadow-editor__remove-button{opacity:1}}.block-editor-global-styles-filters-panel__dropdown{border:1px solid #ddd;border-radius:2px}.block-editor-global-styles__shadow-indicator{align-items:center;appearance:none;background:none;border:1px solid #e0e0e0;border-radius:2px;box-sizing:border-box;color:#2f2f2f;cursor:pointer;display:inline-flex;height:26px;padding:0;transform:scale(1);width:26px;will-change:transform}@media not (prefers-reduced-motion){.block-editor-global-styles__shadow-indicator{transition:transform .1s ease}}.block-editor-global-styles__shadow-indicator:focus{border:2px solid #757575}.block-editor-global-styles__shadow-indicator:hover{transform:scale(1.2)}.block-editor-global-styles__shadow-indicator.unset{background:linear-gradient(-45deg,#0000 48%,#ddd 0,#ddd 52%,#0000 0)}.block-editor-global-styles-advanced-panel__custom-css-input textarea{direction:ltr;font-family:Menlo,Consolas,monaco,monospace}.block-editor-panel-duotone-settings__reset{margin:auto 8px;opacity:0;position:absolute;right:0;top:8px}@media not (prefers-reduced-motion){.block-editor-panel-duotone-settings__reset{transition:opacity .1s ease-in-out}}.block-editor-global-styles-filters-panel__dropdown:hover .block-editor-panel-duotone-settings__reset,.block-editor-panel-duotone-settings__reset:focus,.block-editor-panel-duotone-settings__reset:hover{opacity:1}@media (hover:none){.block-editor-panel-duotone-settings__reset{opacity:1}}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer{z-index:30}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .components-popover__content *{pointer-events:none}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer.is-dropping-allowed .block-editor-grid-visualizer__drop-zone{pointer-events:all}.block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .block-editor-inserter *{pointer-events:auto}.block-editor-grid-visualizer__grid{display:grid;position:absolute}.block-editor-grid-visualizer__cell{display:grid;position:relative}.block-editor-grid-visualizer__cell .block-editor-inserter{bottom:0;color:inherit;left:0;overflow:hidden;position:absolute;right:0;top:0;z-index:32}.block-editor-grid-visualizer__cell .block-editor-inserter .block-editor-grid-visualizer__appender{box-shadow:inset 0 0 0 1px color-mix(in srgb,currentColor 20%,#0000);color:inherit;height:100%;opacity:0;overflow:hidden;padding:0!important;width:100%}.block-editor-grid-visualizer__cell.is-highlighted .block-editor-grid-visualizer__drop-zone,.block-editor-grid-visualizer__cell.is-highlighted .block-editor-inserter{background:var(--wp-admin-theme-color)}.block-editor-grid-visualizer__cell .block-editor-grid-visualizer__appender:focus,.block-editor-grid-visualizer__cell:hover .block-editor-grid-visualizer__appender{background-color:color-mix(in srgb,currentColor 20%,#0000);opacity:1}.block-editor-grid-visualizer__drop-zone{background:#cccccc1a;grid-column:1;grid-row:1;height:100%;min-height:8px;min-width:8px;width:100%}.block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer{z-index:30}.block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer .components-popover__content *{pointer-events:none}.block-editor-grid-item-resizer__box{border:1px solid var(--wp-admin-theme-color)}.block-editor-grid-item-resizer__box .components-resizable-box__handle.components-resizable-box__handle.components-resizable-box__handle{pointer-events:all}.block-editor-grid-item-mover__move-button-container{border:none;display:flex;justify-content:center;padding:0}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button{min-width:0!important;padding-left:0;padding-right:0;width:24px}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button svg{min-width:24px}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{border-radius:2px;content:"";display:block;height:32px;left:8px;position:absolute;right:8px;z-index:-1}@media not (prefers-reduced-motion){.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{animation:components-button__appear-animation .1s ease;animation-fill-mode:forwards}}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:before,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:enabled{box-shadow:none;outline:none}.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus-visible:before{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-grid-item-mover__move-vertical-button-container{display:flex;position:relative}@media (min-width:600px){.block-editor-grid-item-mover__move-vertical-button-container{flex-direction:column;justify-content:space-around}.block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button{height:20px!important;min-width:0!important;width:100%}.block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button:before{height:calc(100% - 4px)}.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-down-button svg,.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-up-button svg{flex-shrink:0;height:20px}.editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container{height:40px;position:relative;top:-5px}}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container{position:relative}@media (min-width:600px){.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#e0e0e0;content:"";height:100%;position:absolute;top:0;width:1px}}@media (min-width:782px){.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left{padding-right:6px}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left:before{right:0}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right{padding-left:6px}.show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right:before{left:0}@media (min-width:600px){.show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{background:#e0e0e0;content:"";height:1px;left:50%;margin-top:-.5px;position:absolute;top:50%;transform:translate(-50%);width:100%}}@media (min-width:782px){.show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-grid-item-mover-button{white-space:nowrap}.show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-horizontal-button-container:before{background:#ddd;height:24px;top:4px}.show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container:before{background:#ddd;width:calc(100% - 24px)}.block-editor-height-control{border:0;margin:0;padding:0}.block-editor-iframe__container{height:100%;width:100%}.block-editor-iframe__scale-container{height:100%}.block-editor-iframe__scale-container.is-zoomed-out{position:absolute;right:0;width:var(--wp-block-editor-iframe-zoom-out-scale-container-width,100vw)}.block-editor-image-size-control{margin-bottom:1em}.block-editor-image-size-control .block-editor-image-size-control__height,.block-editor-image-size-control .block-editor-image-size-control__width{margin-bottom:1.115em}.block-editor-block-types-list__list-item{display:block;margin:0;padding:0;width:33.33%}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled) .block-editor-block-icon.has-colors{color:var(--wp-block-synced-color)}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{color:var(--wp-block-synced-color)!important;filter:brightness(.95)}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{color:var(--wp-block-synced-color)!important}.block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):after{background:var(--wp-block-synced-color)}.components-button.block-editor-block-types-list__item{align-items:stretch;background:#0000;color:#1e1e1e;cursor:pointer;display:flex;flex-direction:column;font-size:13px;height:auto;justify-content:center;padding:8px;position:relative;width:100%;word-break:break-word}@media not (prefers-reduced-motion){.components-button.block-editor-block-types-list__item{transition:all .05s ease-in-out}}.components-button.block-editor-block-types-list__item:disabled{cursor:default;opacity:.6}.components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{color:var(--wp-admin-theme-color)!important;filter:brightness(.95)}.components-button.block-editor-block-types-list__item:not(:disabled):hover svg{color:var(--wp-admin-theme-color)!important}.components-button.block-editor-block-types-list__item:not(:disabled):hover:after{background:var(--wp-admin-theme-color);border-radius:2px;bottom:0;content:"";left:0;opacity:.04;pointer-events:none;position:absolute;right:0;top:0}.components-button.block-editor-block-types-list__item:not(:disabled):focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.components-button.block-editor-block-types-list__item:not(:disabled).is-active{background:#1e1e1e;color:#fff;outline:2px solid #0000;outline-offset:-2px}.block-editor-block-types-list__item-icon{color:#1e1e1e;padding:12px 20px}@media not (prefers-reduced-motion){.block-editor-block-types-list__item-icon{transition:all .05s ease-in-out}}.block-editor-block-types-list__item-icon .block-editor-block-icon{margin-left:auto;margin-right:auto}@media not (prefers-reduced-motion){.block-editor-block-types-list__item-icon svg{transition:all .15s ease-out}}.block-editor-block-types-list__list-item[draggable=true] .block-editor-block-types-list__item-icon{cursor:grab}.block-editor-block-types-list__item-title{font-size:12px;hyphens:auto;padding:4px 2px 8px}.block-editor-block-inspector__tabs [role=tablist]{width:100%}.block-editor-inspector-popover-header{margin-bottom:16px}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}@keyframes loadingpulse{0%{opacity:1}50%{opacity:0}to{opacity:1}}.block-editor-link-control{min-width:350px;position:relative}.components-popover__content .block-editor-link-control{max-width:350px;min-width:auto;width:90vw}.show-icon-labels .block-editor-link-control .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-link-control .components-button.has-icon:before{content:attr(aria-label)}.show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top{flex-wrap:wrap;gap:4px}.show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon{padding:4px;width:auto}.show-icon-labels .block-editor-link-control .is-preview .block-editor-link-control__search-item-header{margin-right:0;min-width:100%}.block-editor-link-control__search-input-wrapper{margin-bottom:8px;position:relative}.block-editor-link-control__search-input-container,.block-editor-link-control__search-input-wrapper{position:relative}.block-editor-link-control__field{margin:16px}.block-editor-link-control__field .components-base-control__label{color:#1e1e1e}.block-editor-link-control__search-error{margin:-8px 16px 16px}.block-editor-link-control__search-actions{padding:8px 16px 16px}.block-editor-link-control__search-results-wrapper{position:relative}.block-editor-link-control__search-results-wrapper:after,.block-editor-link-control__search-results-wrapper:before{content:"";display:block;left:-1px;pointer-events:none;position:absolute;right:16px;z-index:100}.block-editor-link-control__search-results-wrapper:before{bottom:auto;height:8px;top:0}.block-editor-link-control__search-results-wrapper:after{bottom:0;height:16px;top:auto}.block-editor-link-control__search-results{margin-top:-16px;max-height:200px;overflow-y:auto;padding:8px}.block-editor-link-control__search-results.is-loading{opacity:.2}.block-editor-link-control__search-item.components-button.components-menu-item__button{height:auto;text-align:left}.block-editor-link-control__search-item .components-menu-item__item{display:inline-block;overflow:hidden;text-overflow:ellipsis;width:100%}.block-editor-link-control__search-item .components-menu-item__item mark{background-color:initial;color:inherit;font-weight:600}.block-editor-link-control__search-item .components-menu-item__shortcut{color:#757575;text-transform:capitalize;white-space:nowrap}.block-editor-link-control__search-item[aria-selected]{background:#f0f0f0}.block-editor-link-control__search-item.is-current{background:#0000;border:0;cursor:default;flex-direction:column;padding:16px;width:100%}.block-editor-link-control__search-item .block-editor-link-control__search-item-header{align-items:center;display:block;flex-direction:row;gap:8px;margin-right:8px;overflow-wrap:break-word;white-space:pre-wrap}.block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-info{color:#757575;font-size:12px;line-height:1.1;word-break:break-all}.block-editor-link-control__search-item.is-preview .block-editor-link-control__search-item-header{display:flex;flex:1}.block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-header{align-items:center}.block-editor-link-control__search-item.is-url-title .block-editor-link-control__search-item-title{word-break:break-all}.block-editor-link-control__search-item .block-editor-link-control__search-item-details{display:flex;flex-direction:column;gap:4px;justify-content:space-between}.block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-icon{background-color:#f0f0f0;border-radius:2px;height:32px;width:32px}.block-editor-link-control__search-item .block-editor-link-control__search-item-icon{align-items:center;display:flex;flex-shrink:0;justify-content:center;position:relative}.block-editor-link-control__search-item .block-editor-link-control__search-item-icon img{width:16px}.block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-icon{max-height:32px;top:0;width:32px}.block-editor-link-control__search-item .block-editor-link-control__search-item-title{line-height:1.1}.block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus{box-shadow:none}.block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus-visible{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000;text-decoration:none}.block-editor-link-control__search-item .block-editor-link-control__search-item-title mark{background-color:initial;color:inherit;font-weight:600}.block-editor-link-control__search-item .block-editor-link-control__search-item-title span{font-weight:400}.block-editor-link-control__search-item .block-editor-link-control__search-item-title .components-external-link__icon{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border:0}.block-editor-link-control__search-item-top{align-items:center;display:flex;flex-direction:row;width:100%}.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon img,.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon svg{opacity:0}.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{background-color:#f0f0f0;border-radius:100%;bottom:0;content:"";display:block;left:0;position:absolute;right:0;top:0}@media not (prefers-reduced-motion){.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{animation:loadingpulse 1s linear infinite;animation-delay:.5s}}.block-editor-link-control__loading{align-items:center;display:flex;margin:16px}.block-editor-link-control__loading .components-spinner{margin-top:0}.components-button+.block-editor-link-control__search-create{overflow:visible;padding:12px 16px}.components-button+.block-editor-link-control__search-create:before{content:"";display:block;left:0;position:absolute;top:-10px;width:100%}.block-editor-link-control__search-create{align-items:center}.block-editor-link-control__search-create .block-editor-link-control__search-item-title{margin-bottom:0}.block-editor-link-control__search-create .block-editor-link-control__search-item-icon{top:0}.block-editor-link-control__drawer-inner{display:flex;flex-basis:100%;flex-direction:column;position:relative}.block-editor-link-control__setting{flex:1;margin-bottom:0;padding:8px 0 8px 24px}.block-editor-link-control__setting .components-base-control__field{display:flex}.block-editor-link-control__setting .components-base-control__field .components-checkbox-control__label{color:#1e1e1e}.block-editor-link-control__setting input{margin-left:0}.is-preview .block-editor-link-control__setting{padding:20px 8px 8px 0}.block-editor-link-control__tools{margin-top:-16px;padding:8px 8px 0}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle{gap:0;padding-left:0}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true]{color:#1e1e1e}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{transform:rotate(90deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{transition:transform .1s ease}}.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{transform:rotate(0deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{transition:transform .1s ease}}.block-editor-link-control .block-editor-link-control__search-input .components-spinner{display:block}.block-editor-link-control .block-editor-link-control__search-input .components-spinner.components-spinner{bottom:auto;left:auto;position:absolute;right:40px;top:calc(50% - 8px)}.block-editor-link-control .block-editor-link-control__search-input-wrapper.has-actions .components-spinner{right:12px;top:calc(50% + 4px)}.block-editor-list-view-tree{border-collapse:collapse;margin:0;padding:0;width:100%}.components-modal__content .block-editor-list-view-tree{margin:-12px -6px 0;width:calc(100% + 12px)}.block-editor-list-view-tree.is-dragging tbody{pointer-events:none}.block-editor-list-view-leaf{position:relative;transform:translateY(0)}.block-editor-list-view-leaf.is-draggable,.block-editor-list-view-leaf.is-draggable .block-editor-list-view-block-contents{cursor:grab}.block-editor-list-view-leaf .block-editor-list-view-block-select-button[aria-expanded=true]{color:inherit}.block-editor-list-view-leaf .block-editor-list-view-block-select-button:hover{color:var(--wp-admin-theme-color)}.block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{fill:currentColor}@media (forced-colors:active){.block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{fill:CanvasText}}.is-dragging-components-draggable .block-editor-list-view-leaf:not(.is-selected) .block-editor-list-view-block-select-button:hover{color:inherit}.block-editor-list-view-leaf.is-selected td{background:var(--wp-admin-theme-color)}.block-editor-list-view-leaf.is-selected.is-synced td{background:var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents .block-editor-block-icon,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:hover{color:var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents,.block-editor-list-view-leaf.is-selected .components-button.has-icon{color:#fff}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color)}.block-editor-list-view-leaf.is-selected.is-synced .block-editor-list-view-block-contents:focus:after{box-shadow:inset 0 0 0 1px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block__menu:focus{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff}.block-editor-list-view-leaf.is-first-selected td:first-child{border-top-left-radius:2px}.block-editor-list-view-leaf.is-first-selected td:last-child{border-top-right-radius:2px}.block-editor-list-view-leaf.is-last-selected td:first-child{border-bottom-left-radius:2px}.block-editor-list-view-leaf.is-last-selected td:last-child{border-bottom-right-radius:2px}.block-editor-list-view-leaf.is-branch-selected:not(.is-selected):not(.is-synced-branch){background:rgba(var(--wp-admin-theme-color--rgb),.04)}.block-editor-list-view-leaf.is-synced-branch.is-branch-selected{background:rgba(var(--wp-block-synced-color--rgb),.04)}.block-editor-list-view-leaf.is-branch-selected.is-first-selected td:first-child{border-top-left-radius:2px}.block-editor-list-view-leaf.is-branch-selected.is-first-selected td:last-child{border-top-right-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:first-child{border-top-left-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:last-child{border-top-right-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:first-child{border-bottom-left-radius:2px}.block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:last-child{border-bottom-right-radius:2px}.block-editor-list-view-leaf.is-branch-selected:not(.is-selected) td{border-radius:0}.block-editor-list-view-leaf.is-displacement-normal{transform:translateY(0)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-normal{transition:transform .2s}}.block-editor-list-view-leaf.is-displacement-up{transform:translateY(-32px)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-up{transition:transform .2s}}.block-editor-list-view-leaf.is-displacement-down{transform:translateY(32px)}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-displacement-down{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks{transform:translateY(calc(var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{transform:translateY(calc(-32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{transition:transform .2s}}.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{transform:translateY(calc(32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1))}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{transition:transform .2s}}.block-editor-list-view-leaf.is-dragging{left:0;opacity:0;pointer-events:none;z-index:-9999}.block-editor-list-view-leaf .block-editor-list-view-block-contents{align-items:center;border-radius:2px;box-sizing:border-box;color:inherit;display:flex;font-family:inherit;font-size:13px;font-weight:400;height:32px;margin:0;padding:6px 4px 6px 0;position:relative;text-align:left;text-decoration:none;white-space:nowrap;width:100%}@media not (prefers-reduced-motion){.block-editor-list-view-leaf .block-editor-list-view-block-contents{transition:box-shadow .1s linear}}.components-modal__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{padding-left:0;padding-right:0}.block-editor-list-view-leaf .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents{box-shadow:none}.block-editor-list-view-leaf .block-editor-list-view-block-contents:focus:after,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents:after{border-radius:inherit;bottom:0;box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);content:"";left:0;pointer-events:none;position:absolute;right:-29px;top:0;z-index:2}.block-editor-list-view-leaf.has-single-cell .block-editor-list-view-block-contents:focus:after{right:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view__menu{box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);z-index:1}.block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{opacity:1}@keyframes __wp-base-styles-fade-in{0%{opacity:0}to{opacity:1}}@media not (prefers-reduced-motion){.block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{animation:__wp-base-styles-fade-in .08s linear 0s;animation-fill-mode:forwards}}.block-editor-list-view-leaf .block-editor-block-icon{flex:0 0 24px;margin-right:4px}.block-editor-list-view-leaf .block-editor-list-view-block__contents-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{padding:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{line-height:0;vertical-align:middle;width:36px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell>*{opacity:0}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:hover>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:hover>*{opacity:1}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell .components-button.has-icon{min-width:24px;padding:0;width:24px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell{padding-right:4px}.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon{height:24px}.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell-alignment-wrapper{align-items:center;display:flex;flex-direction:column;height:100%}.block-editor-list-view-leaf .block-editor-block-mover-button{height:24px;position:relative;width:36px}.block-editor-list-view-leaf .block-editor-block-mover-button svg{height:24px;position:relative}.block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button{align-items:flex-end;margin-top:-6px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button svg{bottom:-4px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button{align-items:flex-start;margin-bottom:-6px}.block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button svg{top:-4px}.block-editor-list-view-leaf .block-editor-block-mover-button:before{height:16px;left:0;min-width:100%;right:0}.block-editor-list-view-leaf .block-editor-inserter__toggle{background:#1e1e1e;color:#fff;height:24px;margin:6px 6px 6px 1px;min-width:24px}.block-editor-list-view-leaf .block-editor-inserter__toggle:active{color:#fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__label-wrapper svg{left:2px;position:relative}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__title{flex:1;position:relative}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__title .components-truncate{position:absolute;transform:translateY(-50%);width:100%}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor-wrapper{max-width:min(110px,40%);position:relative;width:100%}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor{position:absolute;right:0;transform:translateY(-50%)}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__anchor{background:#0000004d;color:#fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,.block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky{line-height:0}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__images{display:flex}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image{background-size:cover;border-radius:1px;height:18px;width:18px}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:only-child){box-shadow:0 0 0 2px #fff}.block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:first-child){margin-left:-6px}.block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__image:not(:only-child){box-shadow:0 0 0 2px var(--wp-admin-theme-color)}.block-editor-list-view-draggable-chip{opacity:.8}.block-editor-list-view-appender__cell .block-editor-list-view-appender__container,.block-editor-list-view-appender__cell .block-editor-list-view-block__contents-container,.block-editor-list-view-block__contents-cell .block-editor-list-view-appender__container,.block-editor-list-view-block__contents-cell .block-editor-list-view-block__contents-container{display:flex}.block-editor-list-view__expander{cursor:pointer;height:24px;width:24px}.block-editor-list-view-leaf[aria-level] .block-editor-list-view__expander{margin-left:192px}.block-editor-list-view-leaf[aria-level="1"] .block-editor-list-view__expander{margin-left:0}.block-editor-list-view-leaf[aria-level="2"] .block-editor-list-view__expander{margin-left:24px}.block-editor-list-view-leaf[aria-level="3"] .block-editor-list-view__expander{margin-left:48px}.block-editor-list-view-leaf[aria-level="4"] .block-editor-list-view__expander{margin-left:72px}.block-editor-list-view-leaf[aria-level="5"] .block-editor-list-view__expander{margin-left:96px}.block-editor-list-view-leaf[aria-level="6"] .block-editor-list-view__expander{margin-left:120px}.block-editor-list-view-leaf[aria-level="7"] .block-editor-list-view__expander{margin-left:144px}.block-editor-list-view-leaf[aria-level="8"] .block-editor-list-view__expander{margin-left:168px}.block-editor-list-view-leaf .block-editor-list-view__expander{visibility:hidden}.block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{transform:rotate(90deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{transition:transform .2s ease}}.block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{transform:rotate(0deg);visibility:visible}@media not (prefers-reduced-motion){.block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{transition:transform .2s ease}}.block-editor-list-view-drop-indicator{pointer-events:none}.block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line{background:var(--wp-admin-theme-color);border-radius:4px;height:4px}.block-editor-list-view-drop-indicator--preview{pointer-events:none}.block-editor-list-view-drop-indicator--preview .components-popover__content{overflow:hidden!important}.block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line{background:rgba(var(--wp-admin-theme-color--rgb),.04);border-radius:4px;height:32px;overflow:hidden}.block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line--darker{background:rgba(var(--wp-admin-theme-color--rgb),.09)}.block-editor-list-view-placeholder{height:32px;margin:0;padding:0}.list-view-appender .block-editor-inserter__toggle{background-color:#1e1e1e;color:#fff;height:24px;margin:8px 0 0 24px;padding:0}.list-view-appender .block-editor-inserter__toggle.has-icon.is-next-40px-default-size{min-width:24px}.list-view-appender .block-editor-inserter__toggle:focus,.list-view-appender .block-editor-inserter__toggle:hover{background:var(--wp-admin-theme-color);color:#fff}.list-view-appender__description{display:none}.block-editor-media-placeholder__url-input-form{min-width:260px}@media (min-width:600px){.block-editor-media-placeholder__url-input-form{width:300px}}.block-editor-media-placeholder__url-input-form input{direction:ltr}.modal-open .block-editor-media-replace-flow__options{display:none}.block-editor-media-replace-flow__indicator{margin-left:4px}.block-editor-media-replace-flow__media-upload-menu:not(:empty)+.block-editor-media-flow__url-input{border-top:1px solid #1e1e1e;margin-top:8px;padding-bottom:8px}.block-editor-media-flow__url-input{margin-left:-8px;margin-right:-8px;padding:16px}.block-editor-media-flow__url-input .block-editor-media-replace-flow__image-url-label{display:block;margin-bottom:8px;top:16px}.block-editor-media-flow__url-input .block-editor-link-control{width:300px}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-url-input{margin:0;padding:0}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-info,.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-title{max-width:200px;white-space:nowrap}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__tools{justify-content:flex-end;padding:16px var(--wp-admin-border-width-focus) var(--wp-admin-border-width-focus)}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item.is-current{padding:0;width:auto}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-input.block-editor-link-control__search-input input[type=text]{margin:0;width:100%}.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-actions{padding:8px 0 0}.block-editor-media-flow__error{max-width:255px;padding:0 20px 20px}.block-editor-media-flow__error .components-with-notices-ui{max-width:255px}.block-editor-media-flow__error .components-with-notices-ui .components-notice__content{overflow:hidden;word-wrap:break-word}.block-editor-media-flow__error .components-with-notices-ui .components-notice__dismiss{position:absolute;right:10px}.block-editor-multi-selection-inspector__card{padding:16px}.block-editor-multi-selection-inspector__card-title{font-weight:500}.block-editor-multi-selection-inspector__card .block-editor-block-icon{height:24px;margin-left:-2px;padding:0 3px;width:36px}.block-editor-responsive-block-control{border-bottom:1px solid #ccc;margin-bottom:28px;padding-bottom:14px}.block-editor-responsive-block-control:last-child{border-bottom:0;padding-bottom:0}.block-editor-responsive-block-control__title{margin:0 0 .6em -3px}.block-editor-responsive-block-control__label{font-weight:600;margin-bottom:.6em;margin-left:-3px}.block-editor-responsive-block-control__inner{margin-left:-1px}.block-editor-responsive-block-control__toggle{margin-left:1px}.block-editor-responsive-block-control .components-base-control__help{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.components-popover.block-editor-rich-text__inline-format-toolbar{z-index:99998}.components-popover.block-editor-rich-text__inline-format-toolbar .components-popover__content{border-radius:2px;box-shadow:none;margin-bottom:8px;min-width:auto;outline:none;width:auto}.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar{border-radius:2px}.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar-group{background:none}.components-popover.block-editor-rich-text__inline-format-toolbar .components-dropdown-menu__toggle,.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar__control{min-height:48px;min-width:48px;padding-left:12px;padding-right:12px}.block-editor-rich-text__inline-format-toolbar-group .components-dropdown-menu__toggle{justify-content:center}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon{width:auto}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon:after{content:attr(aria-label)}.block-editor-skip-to-selected-block{position:absolute;top:-9999em}.block-editor-skip-to-selected-block:focus{background:#f1f1f1;font-size:14px;font-weight:600;z-index:100000}.block-editor-tabbed-sidebar{background-color:#fff;display:flex;flex-direction:column;flex-grow:1;height:100%;overflow:hidden}.block-editor-tabbed-sidebar__tablist-and-close-button{border-bottom:1px solid #ddd;display:flex;justify-content:space-between;padding-right:8px}.block-editor-tabbed-sidebar__close-button{align-self:center;background:#fff;order:1}.block-editor-tabbed-sidebar__tablist{margin-bottom:-1px}.block-editor-tabbed-sidebar__tabpanel{display:flex;flex-direction:column;flex-grow:1;overflow-y:auto;scrollbar-gutter:auto}.block-editor-tool-selector__help{border-top:1px solid #ddd;color:#757575;margin:8px -8px -8px;min-width:280px;padding:16px}.block-editor-tool-selector__menu .components-menu-item__info{margin-left:36px;text-align:left}.block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{flex-grow:1;padding:1px;position:relative}@media (min-width:600px){.block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{min-width:300px;width:auto}}.block-editor-block-list__block .block-editor-url-input.is-full-width,.block-editor-block-list__block .block-editor-url-input.is-full-width__suggestions,.block-editor-url-input.is-full-width,.block-editor-url-input.is-full-width__suggestions,.components-popover .block-editor-url-input.is-full-width,.components-popover .block-editor-url-input.is-full-width__suggestions{width:100%}.block-editor-block-list__block .block-editor-url-input .components-spinner,.block-editor-url-input .components-spinner,.components-popover .block-editor-url-input .components-spinner{margin:0;position:absolute;right:8px;top:calc(50% - 8px)}.block-editor-url-input__suggestions{max-height:200px;overflow-y:auto;padding:4px 0;width:302px}@media not (prefers-reduced-motion){.block-editor-url-input__suggestions{transition:all .15s ease-in-out}}.block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{display:none}@media (min-width:600px){.block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{display:grid}}.block-editor-url-input__suggestion{background:#fff;border:none;box-shadow:none;color:#757575;cursor:pointer;display:block;font-size:13px;height:auto;min-height:36px;text-align:left;width:100%}.block-editor-url-input__suggestion:hover{background:#ddd}.block-editor-url-input__suggestion.is-selected,.block-editor-url-input__suggestion:focus{background:var(--wp-admin-theme-color-darker-20);color:#fff;outline:none}.components-toolbar-group>.block-editor-url-input__button,.components-toolbar>.block-editor-url-input__button{position:inherit}.block-editor-url-input__button .block-editor-url-input__back{margin-right:4px;overflow:visible}.block-editor-url-input__button .block-editor-url-input__back:after{background:#ddd;content:"";display:block;height:24px;position:absolute;right:-1px;width:1px}.block-editor-url-input__button-modal{background:#fff;border:1px solid #ddd;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003}.block-editor-url-input__button-modal-line{align-items:flex-start;display:flex;flex-direction:row;flex-grow:1;flex-shrink:1;min-width:0}.block-editor-url-popover__additional-controls{border-top:1px solid #1e1e1e;padding:8px}.block-editor-url-popover__input-container{padding:8px}.block-editor-url-popover__row{align-items:center;display:flex;gap:4px}.block-editor-url-popover__row>:not(.block-editor-url-popover__settings-toggle){flex-grow:1;gap:8px}.block-editor-url-popover__additional-controls .components-button.has-icon{height:auto;padding-left:8px;padding-right:8px;text-align:left}.block-editor-url-popover__additional-controls .components-button.has-icon>svg{margin-right:8px}.block-editor-url-popover__settings-toggle{flex-shrink:0}.block-editor-url-popover__settings-toggle[aria-expanded=true] .dashicon{transform:rotate(180deg)}.block-editor-url-popover__settings{border-top:1px solid #1e1e1e;display:block;padding:16px}.block-editor-url-popover__link-editor,.block-editor-url-popover__link-viewer{display:flex}.block-editor-url-popover__link-viewer-url{align-items:center;display:flex;flex-grow:1;flex-shrink:1;margin-right:8px;max-width:350px;min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.block-editor-url-popover__link-viewer-url.has-invalid-link{color:#cc1818}.block-editor-url-popover__expand-on-click{align-items:center;display:flex;min-width:350px;white-space:nowrap}.block-editor-url-popover__expand-on-click .text{flex-grow:1}.block-editor-url-popover__expand-on-click .text p{line-height:16px;margin:0}.block-editor-url-popover__expand-on-click .text p.description{color:#757575;font-size:12px}.block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack{flex-direction:row}.block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext{color:#757575;font-size:12px;margin-bottom:16px}div.block-editor-bindings__panel{grid-template-columns:repeat(auto-fit,minmax(100%,1fr))}div.block-editor-bindings__panel button:hover .block-editor-bindings__item span{color:inherit}.border-block-support-panel .single-column{grid-column:span 1}.color-block-support-panel .block-editor-contrast-checker{grid-column:span 2;margin-top:16px}.color-block-support-panel .block-editor-contrast-checker .components-notice__content{margin-right:0}.color-block-support-panel.color-block-support-panel .color-block-support-panel__inner-wrapper{row-gap:0}.color-block-support-panel .block-editor-tools-panel-color-gradient-settings__item.first{margin-top:0}.dimensions-block-support-panel .single-column{grid-column:span 1}.block-editor-hooks__layout-constrained .components-base-control{margin-bottom:0}.block-editor-hooks__layout-constrained-helptext{color:#757575;font-size:12px;margin-bottom:0}.block-editor-hooks__flex-layout-justification-controls,.block-editor-hooks__flex-layout-orientation-controls{margin-bottom:12px}.block-editor-hooks__flex-layout-justification-controls legend,.block-editor-hooks__flex-layout-orientation-controls legend{margin-bottom:8px}.block-editor__spacing-visualizer{border-color:var(--wp-admin-theme-color);border-style:solid;bottom:0;box-sizing:border-box;left:0;opacity:.5;pointer-events:none;position:absolute;right:0;top:0}.typography-block-support-panel .single-column{grid-column:span 1}.block-editor-block-toolbar{display:flex;flex-grow:1;overflow-x:auto;overflow-y:hidden;position:relative;width:100%}@media not (prefers-reduced-motion){.block-editor-block-toolbar{transition:border-color .1s linear,box-shadow .1s linear}}@media (min-width:600px){.block-editor-block-toolbar{overflow:inherit}}.block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group{background:none;border:0;border-right:1px solid #ddd;margin-bottom:-1px;margin-top:-1px}.block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button:before{background:color-mix(in srgb,var(--wp-block-synced-color) 10%,#0000);border-radius:2px}.block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-connected .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors,.block-editor-block-toolbar.is-synced .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-synced .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors{color:var(--wp-block-synced-color)}.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2),.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar,.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar-group,.block-editor-block-toolbar>:last-child,.block-editor-block-toolbar>:last-child .components-toolbar,.block-editor-block-toolbar>:last-child .components-toolbar-group{border-right:none}.block-editor-block-toolbar .components-toolbar-group:empty{display:none}.block-editor-block-contextual-toolbar{background-color:#fff;display:block;flex-shrink:3;position:sticky;top:0;width:100%;z-index:31}.block-editor-block-contextual-toolbar.components-accessible-toolbar{border:none;border-radius:0}.block-editor-block-contextual-toolbar.is-unstyled{box-shadow:0 1px 0 0 rgba(0,0,0,.133)}.block-editor-block-contextual-toolbar .block-editor-block-toolbar{overflow:auto;overflow-y:hidden;scrollbar-color:#e0e0e0 #0000;scrollbar-gutter:stable both-edges;scrollbar-gutter:auto;scrollbar-width:thin;will-change:transform}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar{height:12px;width:12px}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-track{background-color:initial}.block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:#e0e0e0;border:3px solid #0000;border-radius:8px}.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover::-webkit-scrollbar-thumb{background-color:#949494}.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover{scrollbar-color:#949494 #0000}@media (hover:none){.block-editor-block-contextual-toolbar .block-editor-block-toolbar{scrollbar-color:#949494 #0000}}.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar-group:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child:after{display:none}.block-editor-block-contextual-toolbar>.block-editor-block-toolbar{flex-grow:0;width:auto}.block-editor-block-contextual-toolbar .block-editor-block-parent-selector{margin-bottom:-1px;margin-top:-1px;position:relative}.block-editor-block-contextual-toolbar .block-editor-block-parent-selector:after{align-items:center;background-color:#1e1e1e;border-radius:100%;content:"";display:inline-flex;height:2px;position:absolute;right:0;top:15px;width:2px}.block-editor-block-toolbar__block-controls .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.block-editor-block-toolbar__block-controls .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{margin:0!important;width:24px!important}.block-editor-block-toolbar__block-controls .components-toolbar-group{padding:0}.block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar-group{display:flex;flex-wrap:nowrap}.block-editor-block-toolbar__slot{display:inline-flex}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon{width:auto}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon svg{display:none}.show-icon-labels .block-editor-block-toolbar .components-button.has-icon:after{content:attr(aria-label);font-size:12px}.show-icon-labels .components-accessible-toolbar .components-toolbar-group>div:first-child:last-child>.components-button.has-icon{padding-left:6px;padding-right:6px}.show-icon-labels .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.show-icon-labels .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{height:0!important;min-width:0!important;width:0!important}.show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button{border-bottom-right-radius:0;border-top-right-radius:0;padding-left:12px;padding-right:12px;text-wrap:nowrap}.show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button .block-editor-block-icon{width:0}.show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container{position:relative;width:auto}@media (min-width:600px){.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{background:#e0e0e0;content:"";height:1px;left:50%;margin-top:-.5px;position:absolute;top:50%;transform:translate(-50%);width:100%}}@media (min-width:782px){.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{background:#1e1e1e}}.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button,.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{padding-left:6px;padding-right:6px}.show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover-button{padding-left:8px;padding-right:8px}.show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-mover{border-left:1px solid #ddd;margin-left:6px;margin-right:-6px;white-space:nowrap}.show-icon-labels .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon{padding-left:12px;padding-right:12px}.show-icon-labels .block-editor-block-contextual-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button.block-editor-block-mover-button{width:auto}.show-icon-labels .components-toolbar,.show-icon-labels .components-toolbar-group{flex-shrink:1}.show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button+.components-button{margin-left:6px}.block-editor-block-toolbar-change-design-content-wrapper{padding:12px;width:320px}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr 1fr;grid-gap:12px}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{margin-bottom:0}.block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{min-height:100px}.block-editor-inserter{background:none;border:none;display:inline-block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px;line-height:0;padding:0}@media (min-width:782px){.block-editor-inserter{position:relative}}.block-editor-inserter__main-area{gap:16px;height:100%;position:relative}.block-editor-inserter__main-area.show-as-tabs{gap:0}@media (min-width:782px){.block-editor-inserter__main-area .block-editor-tabbed-sidebar{width:350px}}.block-editor-inserter__popover.is-quick .components-popover__content{border:none;box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003;outline:none}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>*{border-left:1px solid #ccc;border-right:1px solid #ccc}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:first-child{border-radius:4px 4px 0 0;border-top:1px solid #ccc}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:last-child{border-bottom:1px solid #ccc;border-radius:0 0 4px 4px}.block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>.components-button{border:1px solid #1e1e1e}.block-editor-inserter__popover .block-editor-inserter__menu{margin:-12px}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__tablist{top:60px}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__main-area{height:auto;overflow:visible}.block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__preview-container{display:none}.block-editor-inserter__toggle.components-button{align-items:center;border:none;cursor:pointer;display:inline-flex;outline:none;padding:0}@media not (prefers-reduced-motion){.block-editor-inserter__toggle.components-button{transition:color .2s ease}}.block-editor-inserter__menu{height:100%;overflow:visible;position:relative}@media (min-width:782px){.block-editor-inserter__menu.show-panel{width:630px}}.block-editor-inserter__inline-elements{margin-top:-1px}.block-editor-inserter__menu.is-bottom:after{border-bottom-color:#fff}.components-popover.block-editor-inserter__popover{z-index:99999}.block-editor-inserter__search{padding:16px 16px 0}.block-editor-inserter__no-tab-container{flex-grow:1;overflow-y:auto;position:relative}.block-editor-inserter__panel-header{align-items:center;display:inline-flex;padding:16px 16px 0;position:relative}.block-editor-inserter__panel-content{padding:16px}.block-editor-inserter__panel-title,.block-editor-inserter__panel-title button{color:#757575;font-size:11px;font-weight:500;margin:0 12px 0 0;text-transform:uppercase}.block-editor-inserter__panel-dropdown select.components-select-control__input.components-select-control__input.components-select-control__input{height:36px;line-height:36px}.block-editor-inserter__panel-dropdown select{border:none}.block-editor-inserter__reusable-blocks-panel{position:relative;text-align:right}.block-editor-inserter__no-results,.block-editor-inserter__patterns-loading{padding:32px;text-align:center}.block-editor-inserter__child-blocks{padding:0 16px}.block-editor-inserter__parent-block-header{align-items:center;display:flex}.block-editor-inserter__parent-block-header h2{font-size:13px}.block-editor-inserter__parent-block-header .block-editor-block-icon{margin-right:8px}.block-editor-inserter__preview-container__popover{top:16px!important}.block-editor-inserter__preview-container{display:none;max-height:calc(100% - 32px);overflow-y:hidden;padding:16px;width:280px}@media (min-width:782px){.block-editor-inserter__preview-container{display:block}}.block-editor-inserter__preview-container .block-editor-inserter__media-list__list-item{height:100%}.block-editor-inserter__preview-container .block-editor-block-card{padding-bottom:4px;padding-left:0;padding-right:0}.block-editor-inserter__insertable-blocks-at-selection{border-bottom:1px solid #e0e0e0}.block-editor-inserter__block-patterns-tabs-container,.block-editor-inserter__media-tabs-container{display:flex;flex-direction:column;flex-grow:1;justify-content:space-between;padding:16px}.block-editor-inserter__category-tablist{margin-bottom:8px}.block-editor-inserter__category-panel{display:flex;flex-direction:column;outline:1px solid #0000;padding:0 16px}@media (min-width:782px){.block-editor-inserter__category-panel{background:#f0f0f0;border-left:1px solid #e0e0e0;border-top:1px solid #e0e0e0;height:calc(100% + 1px);left:350px;padding:0;position:absolute;top:-1px;width:280px}.block-editor-inserter__category-panel .block-editor-block-patterns-list,.block-editor-inserter__category-panel .block-editor-inserter__media-list{padding:0 24px 16px}}.block-editor-inserter__patterns-category-panel-header{padding:8px 0}@media (min-width:782px){.block-editor-inserter__patterns-category-panel-header{padding:8px 24px}}.block-editor-inserter__patterns-category-no-results{margin-top:24px}.block-editor-inserter__patterns-filter-help{border-top:1px solid #ddd;color:#757575;min-width:280px;padding:16px}.block-editor-block-patterns-list,.block-editor-inserter__media-list{flex-grow:1;height:100%;overflow-y:auto}.block-editor-inserter__preview-content{align-items:center;background:#f0f0f0;display:grid;flex-grow:1}.block-editor-inserter__preview-content-missing{align-items:center;background:#f0f0f0;border-radius:2px;color:#757575;display:flex;flex:1;justify-content:center;min-height:144px}.block-editor-inserter__tips{border-top:1px solid #ddd;flex-shrink:0;padding:16px;position:relative}.block-editor-inserter__quick-inserter{max-width:100%;width:100%}@media (min-width:782px){.block-editor-inserter__quick-inserter{width:350px}}.block-editor-inserter__quick-inserter-results .block-editor-inserter__panel-header{float:left;height:0;padding:0}.block-editor-inserter__quick-inserter.has-expand .block-editor-inserter__panel-content,.block-editor-inserter__quick-inserter.has-search .block-editor-inserter__panel-content{padding:16px}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list{display:grid;grid-template-columns:1fr 1fr;grid-gap:8px}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{margin-bottom:0}.block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{min-height:100px}.block-editor-inserter__quick-inserter-separator{border-top:1px solid #ddd}.block-editor-inserter__popover.is-quick>.components-popover__content{padding:0}.block-editor-inserter__quick-inserter-expand.components-button{background:#1e1e1e;border-radius:0;color:#fff;display:block;width:100%}.block-editor-inserter__quick-inserter-expand.components-button:hover{color:#fff}.block-editor-inserter__quick-inserter-expand.components-button:active{color:#ccc}.block-editor-inserter__quick-inserter-expand.components-button.components-button:focus:not(:disabled){background:var(--wp-admin-theme-color);border-color:var(--wp-admin-theme-color);box-shadow:none}.block-editor-block-patterns-explorer__sidebar{bottom:0;left:0;overflow-x:visible;overflow-y:scroll;padding:24px 32px 32px;position:absolute;top:72px;width:280px}.block-editor-block-patterns-explorer__sidebar__categories-list__item{display:block;height:48px;text-align:left;width:100%}.block-editor-block-patterns-explorer__search{margin-bottom:32px}.block-editor-block-patterns-explorer__search-results-count{padding-bottom:32px}.block-editor-block-patterns-explorer__list{margin-left:280px;padding:24px 0 32px}.block-editor-block-patterns-explorer__list .block-editor-patterns__sync-status-filter .components-input-control__container{width:380px}.block-editor-block-patterns-explorer .block-editor-block-patterns-list{display:grid;grid-gap:32px;grid-template-columns:repeat(1,1fr);margin-bottom:16px}@media (min-width:1080px){.block-editor-block-patterns-explorer .block-editor-block-patterns-list{grid-template-columns:repeat(2,1fr)}}@media (min-width:1440px){.block-editor-block-patterns-explorer .block-editor-block-patterns-list{grid-template-columns:repeat(3,1fr)}}.block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{min-height:240px}.block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{height:inherit;max-height:800px;min-height:100px}.components-heading.block-editor-inserter__patterns-category-panel-title{font-weight:500}.block-editor-inserter__media-library-button.components-button,.block-editor-inserter__patterns-explore-button.components-button{justify-content:center;margin-top:16px;padding:16px;width:100%}.block-editor-inserter__media-panel{display:flex;flex-direction:column;min-height:100%;padding:0 16px}@media (min-width:782px){.block-editor-inserter__media-panel{padding:0}}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-spinner{align-items:center;display:flex;flex:1;height:100%;justify-content:center}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{margin-bottom:24px}@media (min-width:782px){.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{margin-bottom:0;padding:16px 24px}.block-editor-inserter__media-panel .block-editor-inserter__media-panel-search:not(:focus-within){--wp-components-color-background:#fff}}.block-editor-inserter__media-list__list-item{cursor:pointer;margin-bottom:24px;position:relative}.block-editor-inserter__media-list__list-item.is-placeholder{min-height:100px}.block-editor-inserter__media-list__list-item[draggable=true] .block-editor-inserter__media-list__list-item{cursor:grab}.block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview>*{outline-color:#0000004d}.block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview-options>button{display:block}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options{position:absolute;right:8px;top:8px}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button{background:#fff;display:none}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button.is-opened,.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:focus{display:block}.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:hover{box-shadow:inset 0 0 0 2px #fff,0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);outline:2px solid #0000}.block-editor-inserter__media-list__item{height:100%}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview{align-items:center;border-radius:2px;display:flex;overflow:hidden}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview>*{margin:0 auto;max-width:100%;outline:1px solid #0000001a;outline-offset:-1px}.block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview .block-editor-inserter__media-list__item-preview-spinner{align-items:center;background:#ffffffb3;display:flex;height:100%;justify-content:center;pointer-events:none;position:absolute;width:100%}.block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{outline-color:var(--wp-admin-theme-color);outline-offset:calc(var(--wp-admin-border-width-focus)*-1);outline-width:var(--wp-admin-border-width-focus)}@media not (prefers-reduced-motion){.block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{transition:outline .1s linear}}.block-editor-inserter__media-list__item-preview-options__popover .components-menu-item__button .components-menu-item__item{min-width:auto}.block-editor-inserter__mobile-tab-navigation{height:100%;padding:16px}.block-editor-inserter__mobile-tab-navigation>*{height:100%}@media (min-width:600px){.block-editor-inserter-media-tab-media-preview-inserter-external-image-modal{max-width:480px}}.block-editor-inserter-media-tab-media-preview-inserter-external-image-modal p{margin:0}.block-editor-inserter__hint{margin:16px 16px 0}.block-editor-patterns__sync-status-filter .components-input-control__container select.components-select-control__input{height:40px}.block-editor-inserter__pattern-panel-placeholder{display:none}.block-editor-inserter__menu.is-zoom-out{display:flex}@media (min-width:782px){.block-editor-inserter__menu.is-zoom-out.show-panel:after{content:"";display:block;height:100%;width:300px}}@media (max-width:959px){.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{flex-direction:column}}.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{flex-direction:column}.block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{display:none;padding:0 24px 16px}@media (min-width:480px){.block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{display:block}}.spacing-sizes-control .spacing-sizes-control__custom-value-input,.spacing-sizes-control .spacing-sizes-control__label{margin-bottom:0}.spacing-sizes-control .spacing-sizes-control__custom-value-range,.spacing-sizes-control .spacing-sizes-control__range-control{flex:1;margin-bottom:0}.spacing-sizes-control__header{height:16px;margin-bottom:12px}.spacing-sizes-control__dropdown{height:24px}.spacing-sizes-control__custom-select-control,.spacing-sizes-control__custom-value-input{flex:1}.spacing-sizes-control__custom-toggle,.spacing-sizes-control__icon{flex:0 0 auto}.spacing-sizes-control__icon{margin-left:-4px}body.admin-color-light{--wp-admin-theme-color:#0085ba;--wp-admin-theme-color--rgb:0,133,186;--wp-admin-theme-color-darker-10:#0073a1;--wp-admin-theme-color-darker-10--rgb:0,115,161;--wp-admin-theme-color-darker-20:#006187;--wp-admin-theme-color-darker-20--rgb:0,97,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-light{--wp-admin-border-width-focus:1.5px}}body.admin-color-modern{--wp-admin-theme-color:#3858e9;--wp-admin-theme-color--rgb:56,88,233;--wp-admin-theme-color-darker-10:#2145e6;--wp-admin-theme-color-darker-10--rgb:33,69,230;--wp-admin-theme-color-darker-20:#183ad6;--wp-admin-theme-color-darker-20--rgb:24,58,214;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-modern{--wp-admin-border-width-focus:1.5px}}body.admin-color-blue{--wp-admin-theme-color:#096484;--wp-admin-theme-color--rgb:9,100,132;--wp-admin-theme-color-darker-10:#07526c;--wp-admin-theme-color-darker-10--rgb:7,82,108;--wp-admin-theme-color-darker-20:#064054;--wp-admin-theme-color-darker-20--rgb:6,64,84;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-blue{--wp-admin-border-width-focus:1.5px}}body.admin-color-coffee{--wp-admin-theme-color:#46403c;--wp-admin-theme-color--rgb:70,64,60;--wp-admin-theme-color-darker-10:#383330;--wp-admin-theme-color-darker-10--rgb:56,51,48;--wp-admin-theme-color-darker-20:#2b2724;--wp-admin-theme-color-darker-20--rgb:43,39,36;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-coffee{--wp-admin-border-width-focus:1.5px}}body.admin-color-ectoplasm{--wp-admin-theme-color:#523f6d;--wp-admin-theme-color--rgb:82,63,109;--wp-admin-theme-color-darker-10:#46365d;--wp-admin-theme-color-darker-10--rgb:70,54,93;--wp-admin-theme-color-darker-20:#3a2c4d;--wp-admin-theme-color-darker-20--rgb:58,44,77;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ectoplasm{--wp-admin-border-width-focus:1.5px}}body.admin-color-midnight{--wp-admin-theme-color:#e14d43;--wp-admin-theme-color--rgb:225,77,67;--wp-admin-theme-color-darker-10:#dd382d;--wp-admin-theme-color-darker-10--rgb:221,56,45;--wp-admin-theme-color-darker-20:#d02c21;--wp-admin-theme-color-darker-20--rgb:208,44,33;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-midnight{--wp-admin-border-width-focus:1.5px}}body.admin-color-ocean{--wp-admin-theme-color:#627c83;--wp-admin-theme-color--rgb:98,124,131;--wp-admin-theme-color-darker-10:#576e74;--wp-admin-theme-color-darker-10--rgb:87,110,116;--wp-admin-theme-color-darker-20:#4c6066;--wp-admin-theme-color-darker-20--rgb:76,96,102;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-ocean{--wp-admin-border-width-focus:1.5px}}body.admin-color-sunrise{--wp-admin-theme-color:#dd823b;--wp-admin-theme-color--rgb:221,130,59;--wp-admin-theme-color-darker-10:#d97426;--wp-admin-theme-color-darker-10--rgb:217,116,38;--wp-admin-theme-color-darker-20:#c36922;--wp-admin-theme-color-darker-20--rgb:195,105,34;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){body.admin-color-sunrise{--wp-admin-border-width-focus:1.5px}}:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } body{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:18px; line-height:1.5; --wp--style--block-gap:2em; } p{ line-height:1.8; } .editor-post-title__block{ font-size:2.5em; font-weight:800; margin-bottom:1em; margin-top:2em; }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-autocompleters__block{ white-space:nowrap; } .block-editor-autocompleters__block .block-editor-block-icon{ margin-left:8px; } .block-editor-autocompleters__block[aria-selected=true] .block-editor-block-icon{ color:inherit !important; } .block-editor-autocompleters__link{ white-space:nowrap; } .block-editor-autocompleters__link .block-editor-block-icon{ margin-left:8px; } .block-editor-global-styles-background-panel__inspector-media-replace-container{ border:1px solid #ddd; border-radius:2px; grid-column:1 / -1; } .block-editor-global-styles-background-panel__inspector-media-replace-container.is-open{ background-color:#f0f0f0; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item{ border:0; flex-grow:1; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__inspector-preview-inner{ height:100%; } .block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown .block-editor-global-styles-background-panel__dropdown-toggle{ height:40px; } .block-editor-global-styles-background-panel__image-tools-panel-item{ border:1px solid #ddd; grid-column:1 / -1; position:relative; } .block-editor-global-styles-background-panel__image-tools-panel-item .components-drop-zone__content-icon{ display:none; } .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button{ color:#1e1e1e; display:block; width:100%; } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:hover{ color:var(--wp-admin-theme-color); } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading{ height:100%; padding:10px 0 0; position:absolute; width:100%; z-index:1; } .block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading svg{ margin:0; } .block-editor-global-styles-background-panel__dropdown-toggle,.block-editor-global-styles-background-panel__image-preview-content{ height:100%; padding-right:12px; width:100%; } .block-editor-global-styles-background-panel__dropdown-toggle{ background:#0000; border:none; cursor:pointer; } .block-editor-global-styles-background-panel__inspector-media-replace-title{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-editor-global-styles-background-panel__inspector-preview-inner .block-editor-global-styles-background-panel__inspector-image-indicator-wrapper{ height:20px; min-width:auto; width:20px; } .block-editor-global-styles-background-panel__inspector-image-indicator{ background-size:cover; border-radius:50%; display:block; height:20px; position:relative; width:20px; } .block-editor-global-styles-background-panel__inspector-image-indicator:after{ border:1px solid #0000; border-radius:50%; bottom:-1px; box-shadow:inset 0 0 0 1px #0003; box-sizing:inherit; content:""; left:-1px; position:absolute; right:-1px; top:-1px; } .block-editor-global-styles-background-panel__dropdown-content-wrapper{ min-width:260px; overflow-x:hidden; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker-wrapper{ background-color:#f0f0f0; border:1px solid #ddd; border-radius:2px; width:100%; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker__media--image{ max-height:180px; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker:after{ content:none; } .modal-open .block-editor-global-styles-background-panel__popover{ z-index:159890; } .block-editor-global-styles-background-panel__media-replace-popover .components-popover__content{ width:226px; } .block-editor-global-styles-background-panel__media-replace-popover .components-button{ padding:0 8px; } .block-editor-global-styles-background-panel__media-replace-popover .components-button .components-menu-items__item-icon.has-icon-right{ margin-right:16px; } .block-editor-block-alignment-control__menu-group .components-menu-item__info{ margin-top:0; } iframe[name=editor-canvas]{ background-color:#ddd; box-sizing:border-box; display:block; height:100%; width:100%; } @media not (prefers-reduced-motion){ iframe[name=editor-canvas]{ transition:all .4s cubic-bezier(.46, .03, .52, .96); } } .block-editor-block-icon{ align-items:center; display:flex; height:24px; justify-content:center; width:24px; } .block-editor-block-icon.has-colors svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-block-icon.has-colors svg{ fill:CanvasText; } } .block-editor-block-icon svg{ max-height:24px; max-width:24px; min-height:20px; min-width:20px; } .block-editor-block-inspector p:not(.components-base-control__help){ margin-top:0; } .block-editor-block-inspector h2,.block-editor-block-inspector h3{ color:#1e1e1e; font-size:13px; margin-bottom:1.5em; } .block-editor-block-inspector .components-base-control:where(:not(:last-child)),.block-editor-block-inspector .components-radio-control:where(:not(:last-child)){ margin-bottom:16px; } .block-editor-block-inspector .components-focal-point-picker-control .components-base-control,.block-editor-block-inspector .components-query-controls .components-base-control,.block-editor-block-inspector .components-range-control .components-base-control{ margin-bottom:0; } .block-editor-block-inspector .components-panel__body{ border:none; border-top:1px solid #e0e0e0; margin-top:-1px; } .block-editor-block-inspector__no-block-tools,.block-editor-block-inspector__no-blocks{ background:#fff; display:block; font-size:13px; padding:32px 16px; text-align:center; } .block-editor-block-inspector__no-block-tools{ border-top:1px solid #ddd; } .block-editor-block-list__insertion-point{ bottom:0; left:0; position:absolute; right:0; top:0; } .block-editor-block-list__insertion-point-indicator{ background:var(--wp-admin-theme-color); border-radius:2px; opacity:0; position:absolute; transform-origin:center; will-change:transform, opacity; } .block-editor-block-list__insertion-point.is-vertical>.block-editor-block-list__insertion-point-indicator{ height:4px; top:calc(50% - 2px); width:100%; } .block-editor-block-list__insertion-point.is-horizontal>.block-editor-block-list__insertion-point-indicator{ bottom:0; right:calc(50% - 2px); top:0; width:4px; } .block-editor-block-list__insertion-point-inserter{ display:none; justify-content:center; position:absolute; right:calc(50% - 12px); top:calc(50% - 12px); will-change:transform; } @media (min-width:480px){ .block-editor-block-list__insertion-point-inserter{ display:flex; } } .block-editor-block-list__block-side-inserter-popover .components-popover__content>div{ pointer-events:none; } .block-editor-block-list__block-side-inserter-popover .components-popover__content>div>*{ pointer-events:all; } .block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter{ left:0; line-height:0; position:absolute; top:0; } .block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter:disabled{ display:none; } .block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{ background:#1e1e1e; color:#fff; height:24px; min-width:24px; padding:0; } .block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{ background:var(--wp-admin-theme-color); } .block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{ background:#1e1e1e; } @keyframes hide-during-dragging{ to{ position:fixed; transform:translate(-9999px, 9999px); } } .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar{ border:1px solid #1e1e1e; border-radius:2px; margin-bottom:8px; margin-top:8px; overflow:visible; pointer-events:all; position:static; width:auto; } .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{ margin-right:56px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{ margin-right:0; } .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar{ overflow:visible; } .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar-group{ border-left-color:#1e1e1e; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar{ background-color:#1e1e1e; color:#f0f0f0; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar.block-editor-block-contextual-toolbar{ border-color:#2f2f2f; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button{ color:#ddd; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:hover{ color:#fff; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:focus:before{ box-shadow:inset 0 0 0 1px #1e1e1e, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:disabled,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button[aria-disabled=true]{ color:#757575; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ background-color:#1e1e1e; border-color:#2f2f2f; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-switcher__toggle{ color:#f0f0f0; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar-group{ border-left-color:#2f2f2f !important; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .is-pressed{ color:var(--wp-admin-theme-color); } .components-popover.block-editor-block-list__block-popover.is-insertion-point-visible{ visibility:hidden; } .is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{ opacity:0; } @media not (prefers-reduced-motion){ .is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{ animation:hide-during-dragging 1ms linear forwards; } } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{ position:absolute; right:-57px; } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector:before{ content:""; } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ background-color:#fff; border:1px solid #1e1e1e; padding-left:6px; padding-right:6px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ padding-left:12px; padding-right:12px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{ margin-right:-1px; position:relative; right:auto; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-mover__move-button-container,.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar__block-controls .block-editor-block-mover{ border-right:1px solid #1e1e1e; } .is-dragging-components-draggable .components-tooltip{ display:none; } .components-popover.block-editor-block-popover__inbetween .block-editor-button-pattern-inserter__button{ pointer-events:all; position:absolute; right:50%; top:50%; transform:translateX(50%) translateY(-50%); } .block-editor-block-lock-modal{ z-index:1000001; } @media (min-width:600px){ .block-editor-block-lock-modal .components-modal__frame{ max-width:480px; } } .block-editor-block-lock-modal__options legend{ margin-bottom:16px; padding:0; } .block-editor-block-lock-modal__checklist{ margin:0; } .block-editor-block-lock-modal__options-all{ padding:12px 0; } .block-editor-block-lock-modal__options-all .components-checkbox-control__label{ font-weight:600; } .block-editor-block-lock-modal__checklist-item{ align-items:center; display:flex; gap:12px; justify-content:space-between; margin-bottom:0; padding:12px 32px 12px 0; } .block-editor-block-lock-modal__checklist-item .block-editor-block-lock-modal__lock-icon{ flex-shrink:0; margin-left:12px; fill:#1e1e1e; } .block-editor-block-lock-modal__checklist-item:hover{ background-color:#f0f0f0; border-radius:2px; } .block-editor-block-lock-modal__template-lock{ border-top:1px solid #ddd; margin-top:16px; padding-top:16px; } .block-editor-block-lock-modal__actions{ margin-top:24px; } .block-editor-block-lock-toolbar .components-button.has-icon{ min-width:36px !important; } .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{ margin-right:-6px !important; } .show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{ border-right:1px solid #1e1e1e; margin-left:-6px; margin-right:6px !important; } .block-editor-block-breadcrumb{ list-style:none; margin:0; padding:0; } .block-editor-block-breadcrumb li{ display:inline-flex; margin:0; } .block-editor-block-breadcrumb li .block-editor-block-breadcrumb__separator{ fill:currentColor; margin-left:-4px; margin-right:-4px; transform:scaleX(-1);; } .block-editor-block-breadcrumb li:last-child .block-editor-block-breadcrumb__separator{ display:none; } .block-editor-block-breadcrumb__current{ cursor:default; } .block-editor-block-breadcrumb__button.block-editor-block-breadcrumb__button,.block-editor-block-breadcrumb__current{ color:#1e1e1e; font-size:inherit; padding:0 8px; } .block-editor-block-card{ align-items:flex-start; color:#1e1e1e; display:flex; padding:16px; } .block-editor-block-card__title{ align-items:center; display:flex; flex-wrap:wrap; font-weight:500; gap:4px 8px; } .block-editor-block-card__title.block-editor-block-card__title{ font-size:13px; line-height:1.4; margin:0; } .block-editor-block-card__name{ padding:3px 0; } .block-editor-block-card .block-editor-block-icon{ flex:0 0 24px; height:24px; margin-left:12px; margin-right:0; width:24px; } .block-editor-block-card.is-synced .block-editor-block-icon{ color:var(--wp-block-synced-color); } .block-editor-block-compare{ height:auto; } .block-editor-block-compare__wrapper{ display:flex; padding-bottom:16px; } .block-editor-block-compare__wrapper>div{ display:flex; flex-direction:column; justify-content:space-between; max-width:600px; min-width:200px; padding:0 0 0 16px; width:50%; } .block-editor-block-compare__wrapper>div button{ float:left; } .block-editor-block-compare__wrapper .block-editor-block-compare__converted{ border-right:1px solid #ddd; padding-left:0; padding-right:15px; } .block-editor-block-compare__wrapper .block-editor-block-compare__html{ border-bottom:1px solid #ddd; color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:12px; line-height:1.7; padding-bottom:15px; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span{ background-color:#e6ffed; padding-bottom:3px; padding-top:3px; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__added{ background-color:#acf2bd; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__removed{ background-color:#cc1818; } .block-editor-block-compare__wrapper .block-editor-block-compare__preview{ padding:16px 0 0; } .block-editor-block-compare__wrapper .block-editor-block-compare__preview p{ font-size:12px; margin-top:0; } .block-editor-block-compare__wrapper .block-editor-block-compare__action{ margin-top:16px; } .block-editor-block-compare__wrapper .block-editor-block-compare__heading{ font-size:1em; font-weight:400; margin:.67em 0; } .block-editor-block-draggable-chip-wrapper{ position:absolute; right:0; top:-24px; } .block-editor-block-draggable-chip{ background-color:#1e1e1e; border-radius:2px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; color:#fff; cursor:grabbing; display:inline-flex; height:48px; padding:0 13px; position:relative; -webkit-user-select:none; user-select:none; width:max-content; } .block-editor-block-draggable-chip svg{ fill:currentColor; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content{ justify-content:flex-start; margin:auto; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item{ margin-left:6px; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item:last-child{ margin-left:0; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content .block-editor-block-icon svg{ min-height:18px; min-width:18px; } .block-editor-block-draggable-chip .components-flex__item{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ align-items:center; background-color:initial; bottom:0; display:flex; justify-content:center; left:0; opacity:0; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ transition:all .1s linear .1s; } } .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled .block-editor-block-draggable-chip__disabled-icon{ background:#0000 linear-gradient(45deg, #0000 47.5%, #fff 0, #fff 52.5%, #0000 0); border-radius:50%; box-shadow:inset 0 0 0 1.5px #fff; display:inline-block; height:20px; padding:0; width:20px; } .block-draggable-invalid-drag-token .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ background-color:#757575; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; opacity:1; } .block-editor-block-manager__no-results{ font-style:italic; padding:24px 0; text-align:center; } .block-editor-block-manager__search{ margin:16px 0; } .block-editor-block-manager__disabled-blocks-count{ background-color:#fff; border:1px solid #ddd; border-width:1px 0; box-shadow:32px 0 0 0 #fff,-32px 0 0 0 #fff; padding:8px; position:sticky; text-align:center; top:-5px; z-index:2; } .block-editor-block-manager__disabled-blocks-count~.block-editor-block-manager__results .block-editor-block-manager__category-title{ top:31px; } .block-editor-block-manager__disabled-blocks-count .is-link{ margin-right:12px; } .block-editor-block-manager__category{ margin:0 0 24px; } .block-editor-block-manager__category-title{ background-color:#fff; padding:16px 0; position:sticky; top:-4px; z-index:1; } .block-editor-block-manager__category-title .components-checkbox-control__label{ font-weight:600; } .block-editor-block-manager__checklist{ margin-top:0; } .block-editor-block-manager__category-title,.block-editor-block-manager__checklist-item{ border-bottom:1px solid #ddd; } .block-editor-block-manager__checklist-item{ align-items:center; display:flex; justify-content:space-between; margin-bottom:0; padding:8px 16px 8px 0; } .components-modal__content .block-editor-block-manager__checklist-item.components-checkbox-control__input-container{ margin:0 8px; } .block-editor-block-manager__checklist-item .block-editor-block-icon{ margin-left:10px; fill:#1e1e1e; } .block-editor-block-manager__results{ border-top:1px solid #ddd; } .block-editor-block-manager__disabled-blocks-count+.block-editor-block-manager__results{ border-top-width:0; } .block-editor-block-mover__move-button-container{ border:none; display:flex; justify-content:center; padding:0; } @media (min-width:600px){ .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ flex-direction:column; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>*{ height:20px; min-width:0 !important; width:100%; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>:before{ height:calc(100% - 4px); } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{ flex-shrink:0; top:3px; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{ bottom:3px; flex-shrink:0; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{ width:48px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container>*{ min-width:0 !important; overflow:hidden; width:24px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button{ padding-left:0; padding-right:0; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{ right:5px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{ left:5px; } } .block-editor-block-mover__drag-handle{ cursor:grab; } @media (min-width:600px){ .block-editor-block-mover__drag-handle{ min-width:0 !important; overflow:hidden; width:24px; } .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon.has-icon{ padding-left:0; padding-right:0; } } .components-button.block-editor-block-mover-button{ overflow:hidden; } .components-button.block-editor-block-mover-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .components-button.block-editor-block-mover-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .components-button.block-editor-block-mover-button:focus,.components-button.block-editor-block-mover-button:focus:before,.components-button.block-editor-block-mover-button:focus:enabled{ box-shadow:none; outline:none; } .components-button.block-editor-block-mover-button:focus-visible:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-navigation__container{ min-width:280px; } .block-editor-block-navigation__label{ color:#757575; font-size:11px; font-weight:500; margin:0 0 12px; text-transform:uppercase; } .block-editor-block-patterns-list__list-item{ cursor:pointer; margin-bottom:16px; position:relative; } .block-editor-block-patterns-list__list-item.is-placeholder{ min-height:100px; } .block-editor-block-patterns-list__list-item[draggable=true]{ cursor:grab; } .block-editor-block-patterns-list__item{ height:100%; outline:0; scroll-margin-bottom:56px; scroll-margin-top:24px; } .block-editor-block-patterns-list__item .block-editor-block-patterns-list__item-title{ flex-grow:1; font-size:12px; text-align:right; } .block-editor-block-patterns-list__item .block-editor-block-preview__container{ align-items:center; border-radius:4px; display:flex; overflow:hidden; } .block-editor-block-patterns-list__item .block-editor-block-preview__container:after{ border-radius:4px; outline:1px solid #0000001a; outline-offset:-1px; } @media not (prefers-reduced-motion){ .block-editor-block-patterns-list__item .block-editor-block-preview__container:after{ transition:outline .1s linear; } } .block-editor-block-patterns-list__item.is-selected .block-editor-block-preview__container:after{ outline-color:#1e1e1e; outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } .block-editor-block-patterns-list__item:hover .block-editor-block-preview__container:after{ outline-color:#0000004d; } .block-editor-block-patterns-list__item[data-focus-visible] .block-editor-block-preview__container:after{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-details:not(:empty){ align-items:center; margin-top:8px; padding-bottom:4px; } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper{ height:24px; min-width:24px; } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper .block-editor-patterns__pattern-icon{ fill:var(--wp-block-synced-color); } .block-editor-patterns__grid-pagination-wrapper .block-editor-patterns__grid-pagination{ border-top:1px solid #2f2f2f; justify-content:center; padding:4px; } .show-icon-labels .block-editor-patterns__grid-pagination-button{ width:auto; } .show-icon-labels .block-editor-patterns__grid-pagination-button span{ display:none; } .show-icon-labels .block-editor-patterns__grid-pagination-button:before{ content:attr(aria-label); } .components-popover.block-editor-block-popover{ margin:0 !important; pointer-events:none; position:absolute; z-index:31; } .components-popover.block-editor-block-popover .components-popover__content{ margin:0 !important; min-width:auto; overflow-y:visible; width:max-content; } .components-popover.block-editor-block-popover:not(.block-editor-block-popover__inbetween,.block-editor-block-popover__drop-zone,.block-editor-block-list__block-side-inserter-popover) .components-popover__content *{ pointer-events:all; } .components-popover.block-editor-block-popover__inbetween,.components-popover.block-editor-block-popover__inbetween *{ pointer-events:none; } .components-popover.block-editor-block-popover__inbetween .is-with-inserter,.components-popover.block-editor-block-popover__inbetween .is-with-inserter *{ pointer-events:all; } .components-popover.block-editor-block-popover__drop-zone *{ pointer-events:none; } .components-popover.block-editor-block-popover__drop-zone .block-editor-block-popover__drop-zone-foreground{ background-color:var(--wp-admin-theme-color); border-radius:2px; inset:0; position:absolute; } .block-editor-block-preview__container{ overflow:hidden; position:relative; width:100%; } .block-editor-block-preview__container .block-editor-block-preview__content{ margin:0; min-height:auto; overflow:visible; right:0; text-align:initial; top:0; transform-origin:top right; width:100%; } .block-editor-block-preview__container .block-editor-block-preview__content .block-editor-block-list__insertion-point,.block-editor-block-preview__container .block-editor-block-preview__content .block-list-appender{ display:none; } .block-editor-block-preview__container:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:1; } .block-editor-block-rename-modal{ z-index:1000001; } .block-editor-block-styles__preview-panel{ display:none; z-index:90; } @media (min-width:782px){ .block-editor-block-styles__preview-panel{ display:block; } } .block-editor-block-styles__preview-panel .block-editor-block-icon{ display:none; } .block-editor-block-styles__variants{ display:flex; flex-wrap:wrap; gap:8px; justify-content:space-between; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item{ box-shadow:inset 0 0 0 1px #ddd; color:#1e1e1e; display:inline-block; width:calc(50% - 4px); } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:hover{ box-shadow:inset 0 0 0 1px #ddd; color:var(--wp-admin-theme-color); } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover{ background-color:#1e1e1e; box-shadow:none; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active .block-editor-block-styles__item-text,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover .block-editor-block-styles__item-text{ color:#fff; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:focus,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:focus{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-styles__variants .block-editor-block-styles__item-text{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-editor-block-styles__block-preview-container,.block-editor-block-styles__block-preview-container *{ box-sizing:border-box !important; } .block-editor-block-switcher{ position:relative; } .block-editor-block-switcher .components-button.components-dropdown-menu__toggle.has-icon.has-icon{ min-width:36px; } .block-editor-block-switcher__no-switcher-icon,.block-editor-block-switcher__toggle{ position:relative; } .components-button.block-editor-block-switcher__no-switcher-icon,.components-button.block-editor-block-switcher__toggle{ display:block; height:48px; margin:0; } .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.components-button.block-editor-block-switcher__toggle .block-editor-block-icon{ margin:auto; } .components-button.block-editor-block-switcher__no-switcher-icon{ display:flex; } .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ margin-left:auto; margin-right:auto; min-width:24px !important; } .components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true],.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true]:hover{ color:#1e1e1e; } .components-popover.block-editor-block-switcher__popover .components-popover__content{ min-width:300px; } .block-editor-block-switcher__popover-preview-container{ bottom:0; pointer-events:none; position:absolute; right:0; top:-1px; width:100%; } .block-editor-block-switcher__popover-preview{ overflow:hidden; } .block-editor-block-switcher__popover-preview .components-popover__content{ background:#fff; border:1px solid #1e1e1e; border-radius:4px; box-shadow:none; outline:none; overflow:auto; width:300px; } .block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview{ margin:16px 0; max-height:468px; overflow:hidden; padding:0 16px; } .block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview.is-pattern-list-preview{ overflow:unset; } .block-editor-block-switcher__preview-title{ color:#757575; font-size:11px; font-weight:500; margin-bottom:12px; text-transform:uppercase; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon{ min-width:36px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle{ height:48px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{ height:48px; width:48px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{ padding:12px; } .block-editor-block-switcher__preview-patterns-container{ padding-bottom:16px; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item{ margin-top:16px; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-preview__container{ cursor:pointer; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{ border:1px solid #0000; border-radius:2px; height:100%; position:relative; } @media not (prefers-reduced-motion){ .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{ transition:all .05s ease-in-out; } } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:focus,.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item .block-editor-block-switcher__preview-patterns-container-list__item-title{ cursor:pointer; font-size:12px; padding:4px; text-align:center; } .block-editor-block-switcher__no-transforms{ color:#757575; margin:0; padding:6px 8px; } .block-editor-block-switcher__binding-indicator{ display:block; padding:8px; } .block-editor-block-types-list>[role=presentation]{ display:flex; flex-wrap:wrap; overflow:hidden; } .block-editor-block-pattern-setup{ align-items:flex-start; border-radius:2px; display:flex; flex-direction:column; justify-content:center; width:100%; } .block-editor-block-pattern-setup.view-mode-grid{ padding-top:4px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar{ justify-content:center; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{ column-count:2; column-gap:24px; display:block; padding:0 32px; width:100%; } @media (min-width:1440px){ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{ column-count:3; } } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button]{ cursor:pointer; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item{ scroll-margin:5px 0; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-preview__container{ box-shadow:0 0 0 2px var(--wp-admin-theme-color); } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-preview__container{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-pattern-setup-list__item-title,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-pattern-setup-list__item-title{ color:var(--wp-admin-theme-color); } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item{ break-inside:avoid-column; margin-bottom:24px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-pattern-setup-list__item-title{ cursor:pointer; font-size:12px; padding-top:8px; text-align:center; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container{ border:1px solid #ddd; border-radius:4px; min-height:100px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content{ width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar{ align-items:center; align-self:stretch; background-color:#fff; border-top:1px solid #ddd; bottom:0; box-sizing:border-box; color:#1e1e1e; display:flex; flex-direction:row; height:60px; justify-content:space-between; margin:0; padding:16px; position:absolute; text-align:right; width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls{ display:flex; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions,.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__navigation{ display:flex; width:calc(50% - 36px); } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions{ justify-content:flex-end; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container{ box-sizing:border-box; display:flex; flex-direction:column; height:100%; width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container{ height:100%; list-style:none; margin:0; overflow:hidden; padding:0; position:relative; transform-style:preserve-3d; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container *{ box-sizing:border-box; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{ background-color:#fff; height:100%; margin:auto; padding:0; position:absolute; top:0; width:100%; z-index:100; } @media not (prefers-reduced-motion){ .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{ transition:transform .5s,z-index .5s; } } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide{ opacity:1; position:relative; z-index:102; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.previous-slide{ transform:translateX(100%); z-index:101; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.next-slide{ transform:translateX(-100%); z-index:101; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .block-list-appender{ display:none; } .block-editor-block-pattern-setup__carousel,.block-editor-block-pattern-setup__grid{ width:100%; } .block-editor-block-variation-transforms{ padding:0 52px 16px 16px; width:100%; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle{ border:1px solid #757575; border-radius:2px; justify-content:right; min-height:30px; padding:6px 12px; position:relative; text-align:right; width:100%; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle.components-dropdown-menu__toggle{ padding-left:24px; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle:focus:not(:disabled){ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 calc(var(--wp-admin-border-width-focus) - 1px) var(--wp-admin-theme-color); } .block-editor-block-variation-transforms .components-dropdown-menu__toggle svg{ height:100%; left:0; padding:0; position:absolute; top:0; } .block-editor-block-variation-transforms__popover .components-popover__content{ min-width:230px; } .components-border-radius-control{ margin-bottom:12px; } .components-border-radius-control legend{ margin-bottom:8px; } .components-border-radius-control .components-border-radius-control__wrapper{ align-items:flex-start; display:flex; justify-content:space-between; } .components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__unit-control{ flex-shrink:0; margin-bottom:0; margin-left:16px; width:calc(50% - 8px); } .components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__range-control{ flex:1; margin-left:12px; } .components-border-radius-control .components-border-radius-control__input-controls-wrapper{ display:grid; gap:16px; grid-template-columns:repeat(2, minmax(0, 1fr)); margin-left:12px; } .components-border-radius-control .component-border-radius-control__linked-button{ display:flex; justify-content:center; margin-top:8px; } .components-border-radius-control .component-border-radius-control__linked-button svg{ margin-left:0; } .block-editor-color-gradient-control .block-editor-color-gradient-control__color-indicator{ margin-bottom:12px; } .block-editor-color-gradient-control__fieldset{ min-width:0; } .block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings,.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings>div:not(:first-of-type){ display:block; } @media screen and (min-width:782px){ .block-editor-panel-color-gradient-settings .components-circular-option-picker__swatches{ display:grid; grid-template-columns:repeat(6, 28px); } } .block-editor-block-inspector .block-editor-panel-color-gradient-settings .components-base-control{ margin-bottom:inherit; } .block-editor-panel-color-gradient-settings__dropdown-content .block-editor-color-gradient-control__panel{ padding:16px; width:260px; } .block-editor-panel-color-gradient-settings__color-indicator{ background:linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .block-editor-tools-panel-color-gradient-settings__item{ border-bottom:1px solid #ddd; border-left:1px solid #ddd; border-right:1px solid #ddd; max-width:100%; padding:0; position:relative; } .block-editor-tools-panel-color-gradient-settings__item:nth-child(1 of .block-editor-tools-panel-color-gradient-settings__item){ border-top:1px solid #ddd; border-top-left-radius:2px; border-top-right-radius:2px; margin-top:24px; } .block-editor-tools-panel-color-gradient-settings__item:nth-last-child(1 of .block-editor-tools-panel-color-gradient-settings__item){ border-bottom-left-radius:2px; border-bottom-right-radius:2px; } .block-editor-tools-panel-color-gradient-settings__item>div,.block-editor-tools-panel-color-gradient-settings__item>div>button{ border-radius:inherit; } .block-editor-tools-panel-color-gradient-settings__dropdown{ display:block; padding:0; } .block-editor-tools-panel-color-gradient-settings__dropdown>button{ height:auto; padding-bottom:10px; padding-top:10px; text-align:right; } .block-editor-tools-panel-color-gradient-settings__dropdown>button.is-open{ background:#f0f0f0; color:var(--wp-admin-theme-color); } .block-editor-tools-panel-color-gradient-settings__dropdown .block-editor-panel-color-gradient-settings__color-name{ max-width:calc(100% - 44px); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-panel-color-gradient-settings__dropdown{ width:100%; } .block-editor-panel-color-gradient-settings__dropdown .component-color-indicator{ flex-shrink:0; } .block-editor-panel-color-gradient-settings__reset{ left:0; margin:auto 8px; opacity:0; position:absolute; top:8px; } @media not (prefers-reduced-motion){ .block-editor-panel-color-gradient-settings__reset{ transition:opacity .1s ease-in-out; } } .block-editor-panel-color-gradient-settings__reset.block-editor-panel-color-gradient-settings__reset{ border-radius:2px; } .block-editor-panel-color-gradient-settings__dropdown:hover+.block-editor-panel-color-gradient-settings__reset,.block-editor-panel-color-gradient-settings__reset:focus,.block-editor-panel-color-gradient-settings__reset:hover{ opacity:1; } @media (hover:none){ .block-editor-panel-color-gradient-settings__reset{ opacity:1; } } .block-editor-date-format-picker{ border:none; margin:0 0 16px; padding:0; } .block-editor-date-format-picker__custom-format-select-control__custom-option{ border-top:1px solid #ddd; } .block-editor-duotone-control__popover.components-popover>.components-popover__content{ padding:8px; width:260px; } .block-editor-duotone-control__popover.components-popover .components-menu-group__label{ padding:0; } .block-editor-duotone-control__popover.components-popover .components-circular-option-picker__swatches{ display:grid; gap:12px; grid-template-columns:repeat(6, 28px); justify-content:space-between; } .block-editor-duotone-control__unset-indicator{ background:linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .components-font-appearance-control [role=option]{ color:#1e1e1e; text-transform:capitalize; } .block-editor-font-family-control:not(.is-next-has-no-margin-bottom){ margin-bottom:8px; } .block-editor-global-styles__toggle-icon{ fill:currentColor; } .block-editor-global-styles__shadow-popover-container{ width:230px; } .block-editor-global-styles__shadow__list{ display:flex; flex-wrap:wrap; gap:12px; padding-bottom:8px; } .block-editor-global-styles__clear-shadow{ text-align:left; } .block-editor-global-styles-filters-panel__dropdown,.block-editor-global-styles__shadow-dropdown{ display:block; padding:0; position:relative; } .block-editor-global-styles-filters-panel__dropdown button,.block-editor-global-styles__shadow-dropdown button{ padding:8px; width:100%; } .block-editor-global-styles-filters-panel__dropdown button.is-open,.block-editor-global-styles__shadow-dropdown button.is-open{ background-color:#f0f0f0; } .block-editor-global-styles__shadow-editor__remove-button{ left:0; margin:auto 8px; opacity:0; position:absolute; top:8px; } @media not (prefers-reduced-motion){ .block-editor-global-styles__shadow-editor__remove-button{ transition:opacity .1s ease-in-out; } } .block-editor-global-styles__shadow-dropdown:hover .block-editor-global-styles__shadow-editor__remove-button,.block-editor-global-styles__shadow-editor__remove-button:focus,.block-editor-global-styles__shadow-editor__remove-button:hover{ opacity:1; } @media (hover:none){ .block-editor-global-styles__shadow-editor__remove-button{ opacity:1; } } .block-editor-global-styles-filters-panel__dropdown{ border:1px solid #ddd; border-radius:2px; } .block-editor-global-styles__shadow-indicator{ align-items:center; appearance:none; background:none; border:1px solid #e0e0e0; border-radius:2px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:inline-flex; height:26px; padding:0; transform:scale(1); width:26px; will-change:transform; } @media not (prefers-reduced-motion){ .block-editor-global-styles__shadow-indicator{ transition:transform .1s ease; } } .block-editor-global-styles__shadow-indicator:focus{ border:2px solid #757575; } .block-editor-global-styles__shadow-indicator:hover{ transform:scale(1.2); } .block-editor-global-styles__shadow-indicator.unset{ background:linear-gradient(45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .block-editor-global-styles-advanced-panel__custom-css-input textarea{ direction:ltr; font-family:Menlo,Consolas,monaco,monospace; } .block-editor-panel-duotone-settings__reset{ left:0; margin:auto 8px; opacity:0; position:absolute; top:8px; } @media not (prefers-reduced-motion){ .block-editor-panel-duotone-settings__reset{ transition:opacity .1s ease-in-out; } } .block-editor-global-styles-filters-panel__dropdown:hover .block-editor-panel-duotone-settings__reset,.block-editor-panel-duotone-settings__reset:focus,.block-editor-panel-duotone-settings__reset:hover{ opacity:1; } @media (hover:none){ .block-editor-panel-duotone-settings__reset{ opacity:1; } } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer{ z-index:30; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .components-popover__content *{ pointer-events:none; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer.is-dropping-allowed .block-editor-grid-visualizer__drop-zone{ pointer-events:all; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .block-editor-inserter *{ pointer-events:auto; } .block-editor-grid-visualizer__grid{ display:grid; position:absolute; } .block-editor-grid-visualizer__cell{ display:grid; position:relative; } .block-editor-grid-visualizer__cell .block-editor-inserter{ bottom:0; color:inherit; left:0; overflow:hidden; position:absolute; right:0; top:0; z-index:32; } .block-editor-grid-visualizer__cell .block-editor-inserter .block-editor-grid-visualizer__appender{ box-shadow:inset 0 0 0 1px color-mix(in srgb, currentColor 20%, #0000); color:inherit; height:100%; opacity:0; overflow:hidden; padding:0 !important; width:100%; } .block-editor-grid-visualizer__cell.is-highlighted .block-editor-grid-visualizer__drop-zone,.block-editor-grid-visualizer__cell.is-highlighted .block-editor-inserter{ background:var(--wp-admin-theme-color); } .block-editor-grid-visualizer__cell .block-editor-grid-visualizer__appender:focus,.block-editor-grid-visualizer__cell:hover .block-editor-grid-visualizer__appender{ background-color:color-mix(in srgb, currentColor 20%, #0000); opacity:1; } .block-editor-grid-visualizer__drop-zone{ background:#cccccc1a; grid-column:1; grid-row:1; height:100%; min-height:8px; min-width:8px; width:100%; } .block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer{ z-index:30; } .block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer .components-popover__content *{ pointer-events:none; } .block-editor-grid-item-resizer__box{ border:1px solid var(--wp-admin-theme-color); } .block-editor-grid-item-resizer__box .components-resizable-box__handle.components-resizable-box__handle.components-resizable-box__handle{ pointer-events:all; } .block-editor-grid-item-mover__move-button-container{ border:none; display:flex; justify-content:center; padding:0; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button{ min-width:0 !important; padding-left:0; padding-right:0; width:24px; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button svg{ min-width:24px; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:before,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:enabled{ box-shadow:none; outline:none; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus-visible:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-grid-item-mover__move-vertical-button-container{ display:flex; position:relative; } @media (min-width:600px){ .block-editor-grid-item-mover__move-vertical-button-container{ flex-direction:column; justify-content:space-around; } .block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button{ height:20px !important; min-width:0 !important; width:100%; } .block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button:before{ height:calc(100% - 4px); } .block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-down-button svg,.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-up-button svg{ flex-shrink:0; height:20px; } .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container{ height:40px; position:relative; top:-5px; } } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container{ position:relative; } @media (min-width:600px){ .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#e0e0e0; content:""; height:100%; position:absolute; top:0; width:1px; } } @media (min-width:782px){ .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left{ padding-left:6px; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left:before{ left:0; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right{ padding-right:6px; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right:before{ right:0; } @media (min-width:600px){ .show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#e0e0e0; content:""; height:1px; margin-top:-.5px; position:absolute; right:50%; top:50%; transform:translate(50%); width:100%; } } @media (min-width:782px){ .show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-grid-item-mover-button{ white-space:nowrap; } .show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#ddd; height:24px; top:4px; } .show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#ddd; width:calc(100% - 24px); } .block-editor-height-control{ border:0; margin:0; padding:0; } .block-editor-iframe__container{ height:100%; width:100%; } .block-editor-iframe__scale-container{ height:100%; } .block-editor-iframe__scale-container.is-zoomed-out{ left:0; position:absolute; width:var(--wp-block-editor-iframe-zoom-out-scale-container-width, 100vw); } .block-editor-image-size-control{ margin-bottom:1em; } .block-editor-image-size-control .block-editor-image-size-control__height,.block-editor-image-size-control .block-editor-image-size-control__width{ margin-bottom:1.115em; } .block-editor-block-types-list__list-item{ display:block; margin:0; padding:0; width:33.33%; } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled) .block-editor-block-icon.has-colors{ color:var(--wp-block-synced-color); } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{ color:var(--wp-block-synced-color) !important; filter:brightness(.95); } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{ color:var(--wp-block-synced-color) !important; } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):after{ background:var(--wp-block-synced-color); } .components-button.block-editor-block-types-list__item{ align-items:stretch; background:#0000; color:#1e1e1e; cursor:pointer; display:flex; flex-direction:column; font-size:13px; height:auto; justify-content:center; padding:8px; position:relative; width:100%; word-break:break-word; } @media not (prefers-reduced-motion){ .components-button.block-editor-block-types-list__item{ transition:all .05s ease-in-out; } } .components-button.block-editor-block-types-list__item:disabled{ cursor:default; opacity:.6; } .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{ color:var(--wp-admin-theme-color) !important; filter:brightness(.95); } .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{ color:var(--wp-admin-theme-color) !important; } .components-button.block-editor-block-types-list__item:not(:disabled):hover:after{ background:var(--wp-admin-theme-color); border-radius:2px; bottom:0; content:""; left:0; opacity:.04; pointer-events:none; position:absolute; right:0; top:0; } .components-button.block-editor-block-types-list__item:not(:disabled):focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-button.block-editor-block-types-list__item:not(:disabled).is-active{ background:#1e1e1e; color:#fff; outline:2px solid #0000; outline-offset:-2px; } .block-editor-block-types-list__item-icon{ color:#1e1e1e; padding:12px 20px; } @media not (prefers-reduced-motion){ .block-editor-block-types-list__item-icon{ transition:all .05s ease-in-out; } } .block-editor-block-types-list__item-icon .block-editor-block-icon{ margin-left:auto; margin-right:auto; } @media not (prefers-reduced-motion){ .block-editor-block-types-list__item-icon svg{ transition:all .15s ease-out; } } .block-editor-block-types-list__list-item[draggable=true] .block-editor-block-types-list__item-icon{ cursor:grab; } .block-editor-block-types-list__item-title{ font-size:12px; hyphens:auto; padding:4px 2px 8px; } .block-editor-block-inspector__tabs [role=tablist]{ width:100%; } .block-editor-inspector-popover-header{ margin-bottom:16px; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } @keyframes loadingpulse{ 0%{ opacity:1; } 50%{ opacity:0; } to{ opacity:1; } } .block-editor-link-control{ min-width:350px; position:relative; } .components-popover__content .block-editor-link-control{ max-width:350px; min-width:auto; width:90vw; } .show-icon-labels .block-editor-link-control .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-link-control .components-button.has-icon:before{ content:attr(aria-label); } .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top{ flex-wrap:wrap; gap:4px; } .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon{ padding:4px; width:auto; } .show-icon-labels .block-editor-link-control .is-preview .block-editor-link-control__search-item-header{ margin-left:0; min-width:100%; } .block-editor-link-control__search-input-wrapper{ margin-bottom:8px; position:relative; } .block-editor-link-control__search-input-container,.block-editor-link-control__search-input-wrapper{ position:relative; } .block-editor-link-control__field{ margin:16px; } .block-editor-link-control__field .components-base-control__label{ color:#1e1e1e; } .block-editor-link-control__search-error{ margin:-8px 16px 16px; } .block-editor-link-control__search-actions{ padding:8px 16px 16px; } .block-editor-link-control__search-results-wrapper{ position:relative; } .block-editor-link-control__search-results-wrapper:after,.block-editor-link-control__search-results-wrapper:before{ content:""; display:block; left:16px; pointer-events:none; position:absolute; right:-1px; z-index:100; } .block-editor-link-control__search-results-wrapper:before{ bottom:auto; height:8px; top:0; } .block-editor-link-control__search-results-wrapper:after{ bottom:0; height:16px; top:auto; } .block-editor-link-control__search-results{ margin-top:-16px; max-height:200px; overflow-y:auto; padding:8px; } .block-editor-link-control__search-results.is-loading{ opacity:.2; } .block-editor-link-control__search-item.components-button.components-menu-item__button{ height:auto; text-align:right; } .block-editor-link-control__search-item .components-menu-item__item{ display:inline-block; overflow:hidden; text-overflow:ellipsis; width:100%; } .block-editor-link-control__search-item .components-menu-item__item mark{ background-color:initial; color:inherit; font-weight:600; } .block-editor-link-control__search-item .components-menu-item__shortcut{ color:#757575; text-transform:capitalize; white-space:nowrap; } .block-editor-link-control__search-item[aria-selected]{ background:#f0f0f0; } .block-editor-link-control__search-item.is-current{ background:#0000; border:0; cursor:default; flex-direction:column; padding:16px; width:100%; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header{ align-items:center; display:block; flex-direction:row; gap:8px; margin-left:8px; overflow-wrap:break-word; white-space:pre-wrap; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-info{ color:#757575; font-size:12px; line-height:1.1; word-break:break-all; } .block-editor-link-control__search-item.is-preview .block-editor-link-control__search-item-header{ display:flex; flex:1; } .block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-header{ align-items:center; } .block-editor-link-control__search-item.is-url-title .block-editor-link-control__search-item-title{ word-break:break-all; } .block-editor-link-control__search-item .block-editor-link-control__search-item-details{ display:flex; flex-direction:column; gap:4px; justify-content:space-between; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-icon{ background-color:#f0f0f0; border-radius:2px; height:32px; width:32px; } .block-editor-link-control__search-item .block-editor-link-control__search-item-icon{ align-items:center; display:flex; flex-shrink:0; justify-content:center; position:relative; } .block-editor-link-control__search-item .block-editor-link-control__search-item-icon img{ width:16px; } .block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-icon{ max-height:32px; top:0; width:32px; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title{ line-height:1.1; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus{ box-shadow:none; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus-visible{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; text-decoration:none; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title mark{ background-color:initial; color:inherit; font-weight:600; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title span{ font-weight:400; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title .components-external-link__icon{ height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; clip:rect(0, 0, 0, 0); border:0; } .block-editor-link-control__search-item-top{ align-items:center; display:flex; flex-direction:row; width:100%; } .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon img,.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon svg{ opacity:0; } .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{ background-color:#f0f0f0; border-radius:100%; bottom:0; content:""; display:block; left:0; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{ animation:loadingpulse 1s linear infinite; animation-delay:.5s; } } .block-editor-link-control__loading{ align-items:center; display:flex; margin:16px; } .block-editor-link-control__loading .components-spinner{ margin-top:0; } .components-button+.block-editor-link-control__search-create{ overflow:visible; padding:12px 16px; } .components-button+.block-editor-link-control__search-create:before{ content:""; display:block; position:absolute; right:0; top:-10px; width:100%; } .block-editor-link-control__search-create{ align-items:center; } .block-editor-link-control__search-create .block-editor-link-control__search-item-title{ margin-bottom:0; } .block-editor-link-control__search-create .block-editor-link-control__search-item-icon{ top:0; } .block-editor-link-control__drawer-inner{ display:flex; flex-basis:100%; flex-direction:column; position:relative; } .block-editor-link-control__setting{ flex:1; margin-bottom:0; padding:8px 24px 8px 0; } .block-editor-link-control__setting .components-base-control__field{ display:flex; } .block-editor-link-control__setting .components-base-control__field .components-checkbox-control__label{ color:#1e1e1e; } .block-editor-link-control__setting input{ margin-right:0; } .is-preview .block-editor-link-control__setting{ padding:20px 0 8px 8px; } .block-editor-link-control__tools{ margin-top:-16px; padding:8px 8px 0; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle{ gap:0; padding-right:0; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true]{ color:#1e1e1e; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{ transform:rotate(-90deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{ transition:transform .1s ease; } } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{ transform:rotate(0deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{ transition:transform .1s ease; } } .block-editor-link-control .block-editor-link-control__search-input .components-spinner{ display:block; } .block-editor-link-control .block-editor-link-control__search-input .components-spinner.components-spinner{ bottom:auto; left:40px; position:absolute; right:auto; top:calc(50% - 8px); } .block-editor-link-control .block-editor-link-control__search-input-wrapper.has-actions .components-spinner{ left:12px; top:calc(50% + 4px); } .block-editor-list-view-tree{ border-collapse:collapse; margin:0; padding:0; width:100%; } .components-modal__content .block-editor-list-view-tree{ margin:-12px -6px 0; width:calc(100% + 12px); } .block-editor-list-view-tree.is-dragging tbody{ pointer-events:none; } .block-editor-list-view-leaf{ position:relative; transform:translateY(0); } .block-editor-list-view-leaf.is-draggable,.block-editor-list-view-leaf.is-draggable .block-editor-list-view-block-contents{ cursor:grab; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button[aria-expanded=true]{ color:inherit; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button:hover{ color:var(--wp-admin-theme-color); } .block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{ fill:CanvasText; } } .is-dragging-components-draggable .block-editor-list-view-leaf:not(.is-selected) .block-editor-list-view-block-select-button:hover{ color:inherit; } .block-editor-list-view-leaf.is-selected td{ background:var(--wp-admin-theme-color); } .block-editor-list-view-leaf.is-selected.is-synced td{ background:var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents .block-editor-block-icon,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:hover{ color:var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents,.block-editor-list-view-leaf.is-selected .components-button.has-icon{ color:#fff; } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-list-view-leaf.is-selected.is-synced .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block__menu:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff; } .block-editor-list-view-leaf.is-first-selected td:first-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf.is-first-selected td:last-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf.is-last-selected td:first-child{ border-bottom-right-radius:2px; } .block-editor-list-view-leaf.is-last-selected td:last-child{ border-bottom-left-radius:2px; } .block-editor-list-view-leaf.is-branch-selected:not(.is-selected):not(.is-synced-branch){ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .block-editor-list-view-leaf.is-synced-branch.is-branch-selected{ background:rgba(var(--wp-block-synced-color--rgb), .04); } .block-editor-list-view-leaf.is-branch-selected.is-first-selected td:first-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf.is-branch-selected.is-first-selected td:last-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:first-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:last-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:first-child{ border-bottom-right-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:last-child{ border-bottom-left-radius:2px; } .block-editor-list-view-leaf.is-branch-selected:not(.is-selected) td{ border-radius:0; } .block-editor-list-view-leaf.is-displacement-normal{ transform:translateY(0); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-normal{ transition:transform .2s; } } .block-editor-list-view-leaf.is-displacement-up{ transform:translateY(-32px); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-up{ transition:transform .2s; } } .block-editor-list-view-leaf.is-displacement-down{ transform:translateY(32px); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-down{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks{ transform:translateY(calc(var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{ transform:translateY(calc(-32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{ transform:translateY(calc(32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{ transition:transform .2s; } } .block-editor-list-view-leaf.is-dragging{ opacity:0; pointer-events:none; right:0; z-index:-9999; } .block-editor-list-view-leaf .block-editor-list-view-block-contents{ align-items:center; border-radius:2px; box-sizing:border-box; color:inherit; display:flex; font-family:inherit; font-size:13px; font-weight:400; height:32px; margin:0; padding:6px 0 6px 4px; position:relative; text-align:right; text-decoration:none; white-space:nowrap; width:100%; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf .block-editor-list-view-block-contents{ transition:box-shadow .1s linear; } } .components-modal__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{ padding-left:0; padding-right:0; } .block-editor-list-view-leaf .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents{ box-shadow:none; } .block-editor-list-view-leaf .block-editor-list-view-block-contents:focus:after,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents:after{ border-radius:inherit; bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; left:-29px; pointer-events:none; position:absolute; right:0; top:0; z-index:2; } .block-editor-list-view-leaf.has-single-cell .block-editor-list-view-block-contents:focus:after{ left:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view__menu{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); z-index:1; } .block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{ opacity:1; } @keyframes __wp-base-styles-fade-in{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{ animation:__wp-base-styles-fade-in .08s linear 0s; animation-fill-mode:forwards; } } .block-editor-list-view-leaf .block-editor-block-icon{ flex:0 0 24px; margin-left:4px; } .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{ padding:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{ line-height:0; vertical-align:middle; width:36px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell>*{ opacity:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:hover>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:hover>*{ opacity:1; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell .components-button.has-icon{ min-width:24px; padding:0; width:24px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell{ padding-left:4px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon{ height:24px; } .block-editor-list-view-leaf .block-editor-list-view-block__mover-cell-alignment-wrapper{ align-items:center; display:flex; flex-direction:column; height:100%; } .block-editor-list-view-leaf .block-editor-block-mover-button{ height:24px; position:relative; width:36px; } .block-editor-list-view-leaf .block-editor-block-mover-button svg{ height:24px; position:relative; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button{ align-items:flex-end; margin-top:-6px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button svg{ bottom:-4px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button{ align-items:flex-start; margin-bottom:-6px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button svg{ top:-4px; } .block-editor-list-view-leaf .block-editor-block-mover-button:before{ height:16px; left:0; min-width:100%; right:0; } .block-editor-list-view-leaf .block-editor-inserter__toggle{ background:#1e1e1e; color:#fff; height:24px; margin:6px 1px 6px 6px; min-width:24px; } .block-editor-list-view-leaf .block-editor-inserter__toggle:active{ color:#fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__label-wrapper svg{ position:relative; right:2px; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__title{ flex:1; position:relative; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__title .components-truncate{ position:absolute; transform:translateY(-50%); width:100%; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor-wrapper{ max-width:min(110px, 40%); position:relative; width:100%; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor{ left:0; position:absolute; transform:translateY(-50%); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__anchor{ background:#0000004d; color:#fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,.block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky{ line-height:0; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__images{ display:flex; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image{ background-size:cover; border-radius:1px; height:18px; width:18px; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:only-child){ box-shadow:0 0 0 2px #fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:first-child){ margin-right:-6px; } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__image:not(:only-child){ box-shadow:0 0 0 2px var(--wp-admin-theme-color); } .block-editor-list-view-draggable-chip{ opacity:.8; } .block-editor-list-view-appender__cell .block-editor-list-view-appender__container,.block-editor-list-view-appender__cell .block-editor-list-view-block__contents-container,.block-editor-list-view-block__contents-cell .block-editor-list-view-appender__container,.block-editor-list-view-block__contents-cell .block-editor-list-view-block__contents-container{ display:flex; } .block-editor-list-view__expander{ cursor:pointer; height:24px; width:24px; } .block-editor-list-view-leaf[aria-level] .block-editor-list-view__expander{ margin-right:192px; } .block-editor-list-view-leaf[aria-level="1"] .block-editor-list-view__expander{ margin-right:0; } .block-editor-list-view-leaf[aria-level="2"] .block-editor-list-view__expander{ margin-right:24px; } .block-editor-list-view-leaf[aria-level="3"] .block-editor-list-view__expander{ margin-right:48px; } .block-editor-list-view-leaf[aria-level="4"] .block-editor-list-view__expander{ margin-right:72px; } .block-editor-list-view-leaf[aria-level="5"] .block-editor-list-view__expander{ margin-right:96px; } .block-editor-list-view-leaf[aria-level="6"] .block-editor-list-view__expander{ margin-right:120px; } .block-editor-list-view-leaf[aria-level="7"] .block-editor-list-view__expander{ margin-right:144px; } .block-editor-list-view-leaf[aria-level="8"] .block-editor-list-view__expander{ margin-right:168px; } .block-editor-list-view-leaf .block-editor-list-view__expander{ visibility:hidden; } .block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{ transform:rotate(-90deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{ transition:transform .2s ease; } } .block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{ transform:rotate(0deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{ transition:transform .2s ease; } } .block-editor-list-view-drop-indicator{ pointer-events:none; } .block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line{ background:var(--wp-admin-theme-color); border-radius:4px; height:4px; } .block-editor-list-view-drop-indicator--preview{ pointer-events:none; } .block-editor-list-view-drop-indicator--preview .components-popover__content{ overflow:hidden !important; } .block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-radius:4px; height:32px; overflow:hidden; } .block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line--darker{ background:rgba(var(--wp-admin-theme-color--rgb), .09); } .block-editor-list-view-placeholder{ height:32px; margin:0; padding:0; } .list-view-appender .block-editor-inserter__toggle{ background-color:#1e1e1e; color:#fff; height:24px; margin:8px 24px 0 0; padding:0; } .list-view-appender .block-editor-inserter__toggle.has-icon.is-next-40px-default-size{ min-width:24px; } .list-view-appender .block-editor-inserter__toggle:focus,.list-view-appender .block-editor-inserter__toggle:hover{ background:var(--wp-admin-theme-color); color:#fff; } .list-view-appender__description{ display:none; } .block-editor-media-placeholder__url-input-form{ min-width:260px; } @media (min-width:600px){ .block-editor-media-placeholder__url-input-form{ width:300px; } } .block-editor-media-placeholder__url-input-form input{ direction:ltr; } .modal-open .block-editor-media-replace-flow__options{ display:none; } .block-editor-media-replace-flow__indicator{ margin-right:4px; } .block-editor-media-replace-flow__media-upload-menu:not(:empty)+.block-editor-media-flow__url-input{ border-top:1px solid #1e1e1e; margin-top:8px; padding-bottom:8px; } .block-editor-media-flow__url-input{ margin-left:-8px; margin-right:-8px; padding:16px; } .block-editor-media-flow__url-input .block-editor-media-replace-flow__image-url-label{ display:block; margin-bottom:8px; top:16px; } .block-editor-media-flow__url-input .block-editor-link-control{ width:300px; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-url-input{ margin:0; padding:0; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-info,.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-title{ max-width:200px; white-space:nowrap; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__tools{ justify-content:flex-end; padding:16px var(--wp-admin-border-width-focus) var(--wp-admin-border-width-focus); } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item.is-current{ padding:0; width:auto; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-input.block-editor-link-control__search-input input[type=text]{ margin:0; width:100%; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-actions{ padding:8px 0 0; } .block-editor-media-flow__error{ max-width:255px; padding:0 20px 20px; } .block-editor-media-flow__error .components-with-notices-ui{ max-width:255px; } .block-editor-media-flow__error .components-with-notices-ui .components-notice__content{ overflow:hidden; word-wrap:break-word; } .block-editor-media-flow__error .components-with-notices-ui .components-notice__dismiss{ left:10px; position:absolute; } .block-editor-multi-selection-inspector__card{ padding:16px; } .block-editor-multi-selection-inspector__card-title{ font-weight:500; } .block-editor-multi-selection-inspector__card .block-editor-block-icon{ height:24px; margin-right:-2px; padding:0 3px; width:36px; } .block-editor-responsive-block-control{ border-bottom:1px solid #ccc; margin-bottom:28px; padding-bottom:14px; } .block-editor-responsive-block-control:last-child{ border-bottom:0; padding-bottom:0; } .block-editor-responsive-block-control__title{ margin:0 -3px .6em 0; } .block-editor-responsive-block-control__label{ font-weight:600; margin-bottom:.6em; margin-right:-3px; } .block-editor-responsive-block-control__inner{ margin-right:-1px; } .block-editor-responsive-block-control__toggle{ margin-right:1px; } .block-editor-responsive-block-control .components-base-control__help{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .components-popover.block-editor-rich-text__inline-format-toolbar{ z-index:99998; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-popover__content{ border-radius:2px; box-shadow:none; margin-bottom:8px; min-width:auto; outline:none; width:auto; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar{ border-radius:2px; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar-group{ background:none; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-dropdown-menu__toggle,.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar__control{ min-height:48px; min-width:48px; padding-left:12px; padding-right:12px; } .block-editor-rich-text__inline-format-toolbar-group .components-dropdown-menu__toggle{ justify-content:center; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon{ width:auto; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon:after{ content:attr(aria-label); } .block-editor-skip-to-selected-block{ position:absolute; top:-9999em; } .block-editor-skip-to-selected-block:focus{ background:#f1f1f1; font-size:14px; font-weight:600; z-index:100000; } .block-editor-tabbed-sidebar{ background-color:#fff; display:flex; flex-direction:column; flex-grow:1; height:100%; overflow:hidden; } .block-editor-tabbed-sidebar__tablist-and-close-button{ border-bottom:1px solid #ddd; display:flex; justify-content:space-between; padding-left:8px; } .block-editor-tabbed-sidebar__close-button{ align-self:center; background:#fff; order:1; } .block-editor-tabbed-sidebar__tablist{ margin-bottom:-1px; } .block-editor-tabbed-sidebar__tabpanel{ display:flex; flex-direction:column; flex-grow:1; overflow-y:auto; scrollbar-gutter:auto; } .block-editor-tool-selector__help{ border-top:1px solid #ddd; color:#757575; margin:8px -8px -8px; min-width:280px; padding:16px; } .block-editor-tool-selector__menu .components-menu-item__info{ margin-right:36px; text-align:right; } .block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{ flex-grow:1; padding:1px; position:relative; } @media (min-width:600px){ .block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{ min-width:300px; width:auto; } } .block-editor-block-list__block .block-editor-url-input.is-full-width,.block-editor-block-list__block .block-editor-url-input.is-full-width__suggestions,.block-editor-url-input.is-full-width,.block-editor-url-input.is-full-width__suggestions,.components-popover .block-editor-url-input.is-full-width,.components-popover .block-editor-url-input.is-full-width__suggestions{ width:100%; } .block-editor-block-list__block .block-editor-url-input .components-spinner,.block-editor-url-input .components-spinner,.components-popover .block-editor-url-input .components-spinner{ left:8px; margin:0; position:absolute; top:calc(50% - 8px); } .block-editor-url-input__suggestions{ max-height:200px; overflow-y:auto; padding:4px 0; width:302px; } @media not (prefers-reduced-motion){ .block-editor-url-input__suggestions{ transition:all .15s ease-in-out; } } .block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{ display:none; } @media (min-width:600px){ .block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{ display:grid; } } .block-editor-url-input__suggestion{ background:#fff; border:none; box-shadow:none; color:#757575; cursor:pointer; display:block; font-size:13px; height:auto; min-height:36px; text-align:right; width:100%; } .block-editor-url-input__suggestion:hover{ background:#ddd; } .block-editor-url-input__suggestion.is-selected,.block-editor-url-input__suggestion:focus{ background:var(--wp-admin-theme-color-darker-20); color:#fff; outline:none; } .components-toolbar-group>.block-editor-url-input__button,.components-toolbar>.block-editor-url-input__button{ position:inherit; } .block-editor-url-input__button .block-editor-url-input__back{ margin-left:4px; overflow:visible; } .block-editor-url-input__button .block-editor-url-input__back:after{ background:#ddd; content:""; display:block; height:24px; left:-1px; position:absolute; width:1px; } .block-editor-url-input__button-modal{ background:#fff; border:1px solid #ddd; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; } .block-editor-url-input__button-modal-line{ align-items:flex-start; display:flex; flex-direction:row; flex-grow:1; flex-shrink:1; min-width:0; } .block-editor-url-popover__additional-controls{ border-top:1px solid #1e1e1e; padding:8px; } .block-editor-url-popover__input-container{ padding:8px; } .block-editor-url-popover__row{ align-items:center; display:flex; gap:4px; } .block-editor-url-popover__row>:not(.block-editor-url-popover__settings-toggle){ flex-grow:1; gap:8px; } .block-editor-url-popover__additional-controls .components-button.has-icon{ height:auto; padding-left:8px; padding-right:8px; text-align:right; } .block-editor-url-popover__additional-controls .components-button.has-icon>svg{ margin-left:8px; } .block-editor-url-popover__settings-toggle{ flex-shrink:0; } .block-editor-url-popover__settings-toggle[aria-expanded=true] .dashicon{ transform:rotate(-180deg); } .block-editor-url-popover__settings{ border-top:1px solid #1e1e1e; display:block; padding:16px; } .block-editor-url-popover__link-editor,.block-editor-url-popover__link-viewer{ display:flex; } .block-editor-url-popover__link-viewer-url{ align-items:center; display:flex; flex-grow:1; flex-shrink:1; margin-left:8px; max-width:350px; min-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-url-popover__link-viewer-url.has-invalid-link{ color:#cc1818; } .block-editor-url-popover__expand-on-click{ align-items:center; display:flex; min-width:350px; white-space:nowrap; } .block-editor-url-popover__expand-on-click .text{ flex-grow:1; } .block-editor-url-popover__expand-on-click .text p{ line-height:16px; margin:0; } .block-editor-url-popover__expand-on-click .text p.description{ color:#757575; font-size:12px; } .block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack{ flex-direction:row; } .block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext{ color:#757575; font-size:12px; margin-bottom:16px; } div.block-editor-bindings__panel{ grid-template-columns:repeat(auto-fit, minmax(100%, 1fr)); } div.block-editor-bindings__panel button:hover .block-editor-bindings__item span{ color:inherit; } .border-block-support-panel .single-column{ grid-column:span 1; } .color-block-support-panel .block-editor-contrast-checker{ grid-column:span 2; margin-top:16px; } .color-block-support-panel .block-editor-contrast-checker .components-notice__content{ margin-left:0; } .color-block-support-panel.color-block-support-panel .color-block-support-panel__inner-wrapper{ row-gap:0; } .color-block-support-panel .block-editor-tools-panel-color-gradient-settings__item.first{ margin-top:0; } .dimensions-block-support-panel .single-column{ grid-column:span 1; } .block-editor-hooks__layout-constrained .components-base-control{ margin-bottom:0; } .block-editor-hooks__layout-constrained-helptext{ color:#757575; font-size:12px; margin-bottom:0; } .block-editor-hooks__flex-layout-justification-controls,.block-editor-hooks__flex-layout-orientation-controls{ margin-bottom:12px; } .block-editor-hooks__flex-layout-justification-controls legend,.block-editor-hooks__flex-layout-orientation-controls legend{ margin-bottom:8px; } .block-editor__spacing-visualizer{ border-color:var(--wp-admin-theme-color); border-style:solid; bottom:0; box-sizing:border-box; left:0; opacity:.5; pointer-events:none; position:absolute; right:0; top:0; } .typography-block-support-panel .single-column{ grid-column:span 1; } .block-editor-block-toolbar{ display:flex; flex-grow:1; overflow-x:auto; overflow-y:hidden; position:relative; width:100%; } @media not (prefers-reduced-motion){ .block-editor-block-toolbar{ transition:border-color .1s linear,box-shadow .1s linear; } } @media (min-width:600px){ .block-editor-block-toolbar{ overflow:inherit; } } .block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group{ background:none; border:0; border-left:1px solid #ddd; margin-bottom:-1px; margin-top:-1px; } .block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button:before{ background:color-mix(in srgb, var(--wp-block-synced-color) 10%, #0000); border-radius:2px; } .block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-connected .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors,.block-editor-block-toolbar.is-synced .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-synced .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors{ color:var(--wp-block-synced-color); } .block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2),.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar,.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar-group,.block-editor-block-toolbar>:last-child,.block-editor-block-toolbar>:last-child .components-toolbar,.block-editor-block-toolbar>:last-child .components-toolbar-group{ border-left:none; } .block-editor-block-toolbar .components-toolbar-group:empty{ display:none; } .block-editor-block-contextual-toolbar{ background-color:#fff; display:block; flex-shrink:3; position:sticky; top:0; width:100%; z-index:31; } .block-editor-block-contextual-toolbar.components-accessible-toolbar{ border:none; border-radius:0; } .block-editor-block-contextual-toolbar.is-unstyled{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); } .block-editor-block-contextual-toolbar .block-editor-block-toolbar{ overflow:auto; overflow-y:hidden; scrollbar-color:#e0e0e0 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:auto; scrollbar-width:thin; will-change:transform; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar{ height:12px; width:12px; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-track{ background-color:initial; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:#e0e0e0; border:3px solid #0000; border-radius:8px; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .block-editor-block-contextual-toolbar .block-editor-block-toolbar{ scrollbar-color:#949494 #0000; } } .block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar-group:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child:after{ display:none; } .block-editor-block-contextual-toolbar>.block-editor-block-toolbar{ flex-grow:0; width:auto; } .block-editor-block-contextual-toolbar .block-editor-block-parent-selector{ margin-bottom:-1px; margin-top:-1px; position:relative; } .block-editor-block-contextual-toolbar .block-editor-block-parent-selector:after{ align-items:center; background-color:#1e1e1e; border-radius:100%; content:""; display:inline-flex; height:2px; left:0; position:absolute; top:15px; width:2px; } .block-editor-block-toolbar__block-controls .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.block-editor-block-toolbar__block-controls .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ margin:0 !important; width:24px !important; } .block-editor-block-toolbar__block-controls .components-toolbar-group{ padding:0; } .block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar-group{ display:flex; flex-wrap:nowrap; } .block-editor-block-toolbar__slot{ display:inline-flex; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon{ width:auto; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } .show-icon-labels .components-accessible-toolbar .components-toolbar-group>div:first-child:last-child>.components-button.has-icon{ padding-left:6px; padding-right:6px; } .show-icon-labels .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.show-icon-labels .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ height:0 !important; min-width:0 !important; width:0 !important; } .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ border-bottom-left-radius:0; border-top-left-radius:0; padding-left:12px; padding-right:12px; text-wrap:nowrap; } .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button .block-editor-block-icon{ width:0; } .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container{ position:relative; width:auto; } @media (min-width:600px){ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{ background:#e0e0e0; content:""; height:1px; margin-top:-.5px; position:absolute; right:50%; top:50%; transform:translate(50%); width:100%; } } @media (min-width:782px){ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button,.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{ padding-left:6px; padding-right:6px; } .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover-button{ padding-left:8px; padding-right:8px; } .show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-mover{ border-right:1px solid #ddd; margin-left:-6px; margin-right:6px; white-space:nowrap; } .show-icon-labels .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon{ padding-left:12px; padding-right:12px; } .show-icon-labels .block-editor-block-contextual-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button.block-editor-block-mover-button{ width:auto; } .show-icon-labels .components-toolbar,.show-icon-labels .components-toolbar-group{ flex-shrink:1; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button+.components-button{ margin-right:6px; } .block-editor-block-toolbar-change-design-content-wrapper{ padding:12px; width:320px; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr 1fr; grid-gap:12px; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ min-height:100px; } .block-editor-inserter{ background:none; border:none; display:inline-block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:0; padding:0; } @media (min-width:782px){ .block-editor-inserter{ position:relative; } } .block-editor-inserter__main-area{ gap:16px; height:100%; position:relative; } .block-editor-inserter__main-area.show-as-tabs{ gap:0; } @media (min-width:782px){ .block-editor-inserter__main-area .block-editor-tabbed-sidebar{ width:350px; } } .block-editor-inserter__popover.is-quick .components-popover__content{ border:none; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; outline:none; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>*{ border-left:1px solid #ccc; border-right:1px solid #ccc; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:first-child{ border-radius:4px 4px 0 0; border-top:1px solid #ccc; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:last-child{ border-bottom:1px solid #ccc; border-radius:0 0 4px 4px; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>.components-button{ border:1px solid #1e1e1e; } .block-editor-inserter__popover .block-editor-inserter__menu{ margin:-12px; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__tablist{ top:60px; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__main-area{ height:auto; overflow:visible; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__preview-container{ display:none; } .block-editor-inserter__toggle.components-button{ align-items:center; border:none; cursor:pointer; display:inline-flex; outline:none; padding:0; } @media not (prefers-reduced-motion){ .block-editor-inserter__toggle.components-button{ transition:color .2s ease; } } .block-editor-inserter__menu{ height:100%; overflow:visible; position:relative; } @media (min-width:782px){ .block-editor-inserter__menu.show-panel{ width:630px; } } .block-editor-inserter__inline-elements{ margin-top:-1px; } .block-editor-inserter__menu.is-bottom:after{ border-bottom-color:#fff; } .components-popover.block-editor-inserter__popover{ z-index:99999; } .block-editor-inserter__search{ padding:16px 16px 0; } .block-editor-inserter__no-tab-container{ flex-grow:1; overflow-y:auto; position:relative; } .block-editor-inserter__panel-header{ align-items:center; display:inline-flex; padding:16px 16px 0; position:relative; } .block-editor-inserter__panel-content{ padding:16px; } .block-editor-inserter__panel-title,.block-editor-inserter__panel-title button{ color:#757575; font-size:11px; font-weight:500; margin:0 0 0 12px; text-transform:uppercase; } .block-editor-inserter__panel-dropdown select.components-select-control__input.components-select-control__input.components-select-control__input{ height:36px; line-height:36px; } .block-editor-inserter__panel-dropdown select{ border:none; } .block-editor-inserter__reusable-blocks-panel{ position:relative; text-align:left; } .block-editor-inserter__no-results,.block-editor-inserter__patterns-loading{ padding:32px; text-align:center; } .block-editor-inserter__child-blocks{ padding:0 16px; } .block-editor-inserter__parent-block-header{ align-items:center; display:flex; } .block-editor-inserter__parent-block-header h2{ font-size:13px; } .block-editor-inserter__parent-block-header .block-editor-block-icon{ margin-left:8px; } .block-editor-inserter__preview-container__popover{ top:16px !important; } .block-editor-inserter__preview-container{ display:none; max-height:calc(100% - 32px); overflow-y:hidden; padding:16px; width:280px; } @media (min-width:782px){ .block-editor-inserter__preview-container{ display:block; } } .block-editor-inserter__preview-container .block-editor-inserter__media-list__list-item{ height:100%; } .block-editor-inserter__preview-container .block-editor-block-card{ padding-bottom:4px; padding-left:0; padding-right:0; } .block-editor-inserter__insertable-blocks-at-selection{ border-bottom:1px solid #e0e0e0; } .block-editor-inserter__block-patterns-tabs-container,.block-editor-inserter__media-tabs-container{ display:flex; flex-direction:column; flex-grow:1; justify-content:space-between; padding:16px; } .block-editor-inserter__category-tablist{ margin-bottom:8px; } .block-editor-inserter__category-panel{ display:flex; flex-direction:column; outline:1px solid #0000; padding:0 16px; } @media (min-width:782px){ .block-editor-inserter__category-panel{ background:#f0f0f0; border-right:1px solid #e0e0e0; border-top:1px solid #e0e0e0; height:calc(100% + 1px); padding:0; position:absolute; right:350px; top:-1px; width:280px; } .block-editor-inserter__category-panel .block-editor-block-patterns-list,.block-editor-inserter__category-panel .block-editor-inserter__media-list{ padding:0 24px 16px; } } .block-editor-inserter__patterns-category-panel-header{ padding:8px 0; } @media (min-width:782px){ .block-editor-inserter__patterns-category-panel-header{ padding:8px 24px; } } .block-editor-inserter__patterns-category-no-results{ margin-top:24px; } .block-editor-inserter__patterns-filter-help{ border-top:1px solid #ddd; color:#757575; min-width:280px; padding:16px; } .block-editor-block-patterns-list,.block-editor-inserter__media-list{ flex-grow:1; height:100%; overflow-y:auto; } .block-editor-inserter__preview-content{ align-items:center; background:#f0f0f0; display:grid; flex-grow:1; } .block-editor-inserter__preview-content-missing{ align-items:center; background:#f0f0f0; border-radius:2px; color:#757575; display:flex; flex:1; justify-content:center; min-height:144px; } .block-editor-inserter__tips{ border-top:1px solid #ddd; flex-shrink:0; padding:16px; position:relative; } .block-editor-inserter__quick-inserter{ max-width:100%; width:100%; } @media (min-width:782px){ .block-editor-inserter__quick-inserter{ width:350px; } } .block-editor-inserter__quick-inserter-results .block-editor-inserter__panel-header{ float:right; height:0; padding:0; } .block-editor-inserter__quick-inserter.has-expand .block-editor-inserter__panel-content,.block-editor-inserter__quick-inserter.has-search .block-editor-inserter__panel-content{ padding:16px; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr 1fr; grid-gap:8px; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ min-height:100px; } .block-editor-inserter__quick-inserter-separator{ border-top:1px solid #ddd; } .block-editor-inserter__popover.is-quick>.components-popover__content{ padding:0; } .block-editor-inserter__quick-inserter-expand.components-button{ background:#1e1e1e; border-radius:0; color:#fff; display:block; width:100%; } .block-editor-inserter__quick-inserter-expand.components-button:hover{ color:#fff; } .block-editor-inserter__quick-inserter-expand.components-button:active{ color:#ccc; } .block-editor-inserter__quick-inserter-expand.components-button.components-button:focus:not(:disabled){ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); box-shadow:none; } .block-editor-block-patterns-explorer__sidebar{ bottom:0; overflow-x:visible; overflow-y:scroll; padding:24px 32px 32px; position:absolute; right:0; top:72px; width:280px; } .block-editor-block-patterns-explorer__sidebar__categories-list__item{ display:block; height:48px; text-align:right; width:100%; } .block-editor-block-patterns-explorer__search{ margin-bottom:32px; } .block-editor-block-patterns-explorer__search-results-count{ padding-bottom:32px; } .block-editor-block-patterns-explorer__list{ margin-right:280px; padding:24px 0 32px; } .block-editor-block-patterns-explorer__list .block-editor-patterns__sync-status-filter .components-input-control__container{ width:380px; } .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ display:grid; grid-gap:32px; grid-template-columns:repeat(1, 1fr); margin-bottom:16px; } @media (min-width:1080px){ .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ grid-template-columns:repeat(2, 1fr); } } @media (min-width:1440px){ .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ grid-template-columns:repeat(3, 1fr); } } .block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ min-height:240px; } .block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ height:inherit; max-height:800px; min-height:100px; } .components-heading.block-editor-inserter__patterns-category-panel-title{ font-weight:500; } .block-editor-inserter__media-library-button.components-button,.block-editor-inserter__patterns-explore-button.components-button{ justify-content:center; margin-top:16px; padding:16px; width:100%; } .block-editor-inserter__media-panel{ display:flex; flex-direction:column; min-height:100%; padding:0 16px; } @media (min-width:782px){ .block-editor-inserter__media-panel{ padding:0; } } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-spinner{ align-items:center; display:flex; flex:1; height:100%; justify-content:center; } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{ margin-bottom:24px; } @media (min-width:782px){ .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{ margin-bottom:0; padding:16px 24px; } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search:not(:focus-within){ --wp-components-color-background:#fff; } } .block-editor-inserter__media-list__list-item{ cursor:pointer; margin-bottom:24px; position:relative; } .block-editor-inserter__media-list__list-item.is-placeholder{ min-height:100px; } .block-editor-inserter__media-list__list-item[draggable=true] .block-editor-inserter__media-list__list-item{ cursor:grab; } .block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview>*{ outline-color:#0000004d; } .block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview-options>button{ display:block; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options{ left:8px; position:absolute; top:8px; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button{ background:#fff; display:none; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button.is-opened,.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:focus{ display:block; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:hover{ box-shadow:inset 0 0 0 2px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-inserter__media-list__item{ height:100%; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview{ align-items:center; border-radius:2px; display:flex; overflow:hidden; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview>*{ margin:0 auto; max-width:100%; outline:1px solid #0000001a; outline-offset:-1px; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview .block-editor-inserter__media-list__item-preview-spinner{ align-items:center; background:#ffffffb3; display:flex; height:100%; justify-content:center; pointer-events:none; position:absolute; width:100%; } .block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } @media not (prefers-reduced-motion){ .block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{ transition:outline .1s linear; } } .block-editor-inserter__media-list__item-preview-options__popover .components-menu-item__button .components-menu-item__item{ min-width:auto; } .block-editor-inserter__mobile-tab-navigation{ height:100%; padding:16px; } .block-editor-inserter__mobile-tab-navigation>*{ height:100%; } @media (min-width:600px){ .block-editor-inserter-media-tab-media-preview-inserter-external-image-modal{ max-width:480px; } } .block-editor-inserter-media-tab-media-preview-inserter-external-image-modal p{ margin:0; } .block-editor-inserter__hint{ margin:16px 16px 0; } .block-editor-patterns__sync-status-filter .components-input-control__container select.components-select-control__input{ height:40px; } .block-editor-inserter__pattern-panel-placeholder{ display:none; } .block-editor-inserter__menu.is-zoom-out{ display:flex; } @media (min-width:782px){ .block-editor-inserter__menu.is-zoom-out.show-panel:after{ content:""; display:block; height:100%; width:300px; } } @media (max-width:959px){ .show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{ flex-direction:column; } } .show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{ flex-direction:column; } .block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{ display:none; padding:0 24px 16px; } @media (min-width:480px){ .block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{ display:block; } } .spacing-sizes-control .spacing-sizes-control__custom-value-input,.spacing-sizes-control .spacing-sizes-control__label{ margin-bottom:0; } .spacing-sizes-control .spacing-sizes-control__custom-value-range,.spacing-sizes-control .spacing-sizes-control__range-control{ flex:1; margin-bottom:0; } .spacing-sizes-control__header{ height:16px; margin-bottom:12px; } .spacing-sizes-control__dropdown{ height:24px; } .spacing-sizes-control__custom-select-control,.spacing-sizes-control__custom-value-input{ flex:1; } .spacing-sizes-control__custom-toggle,.spacing-sizes-control__icon{ flex:0 0 auto; } .spacing-sizes-control__icon{ margin-right:-4px; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }:root{ --wp-admin-theme-color:#007cba; --wp-admin-theme-color--rgb:0, 124, 186; --wp-admin-theme-color-darker-10:#006ba1; --wp-admin-theme-color-darker-10--rgb:0, 107, 161; --wp-admin-theme-color-darker-20:#005a87; --wp-admin-theme-color-darker-20--rgb:0, 90, 135; --wp-admin-border-width-focus:2px; --wp-block-synced-color:#7a00df; --wp-block-synced-color--rgb:122, 0, 223; --wp-bound-block-color:var(--wp-block-synced-color); } @media (min-resolution:192dpi){ :root{ --wp-admin-border-width-focus:1.5px; } } .block-editor-autocompleters__block{ white-space:nowrap; } .block-editor-autocompleters__block .block-editor-block-icon{ margin-right:8px; } .block-editor-autocompleters__block[aria-selected=true] .block-editor-block-icon{ color:inherit !important; } .block-editor-autocompleters__link{ white-space:nowrap; } .block-editor-autocompleters__link .block-editor-block-icon{ margin-right:8px; } .block-editor-global-styles-background-panel__inspector-media-replace-container{ border:1px solid #ddd; border-radius:2px; grid-column:1 / -1; } .block-editor-global-styles-background-panel__inspector-media-replace-container.is-open{ background-color:#f0f0f0; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item{ border:0; flex-grow:1; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__inspector-media-replace-container .block-editor-global-styles-background-panel__inspector-preview-inner{ height:100%; } .block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__inspector-media-replace-container .components-dropdown .block-editor-global-styles-background-panel__dropdown-toggle{ height:40px; } .block-editor-global-styles-background-panel__image-tools-panel-item{ border:1px solid #ddd; grid-column:1 / -1; position:relative; } .block-editor-global-styles-background-panel__image-tools-panel-item .components-drop-zone__content-icon{ display:none; } .block-editor-global-styles-background-panel__image-tools-panel-item .components-dropdown{ display:block; } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button{ color:#1e1e1e; display:block; width:100%; } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:hover{ color:var(--wp-admin-theme-color); } .block-editor-global-styles-background-panel__image-tools-panel-item button.components-button:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading{ height:100%; padding:10px 0 0; position:absolute; width:100%; z-index:1; } .block-editor-global-styles-background-panel__image-tools-panel-item .block-editor-global-styles-background-panel__loading svg{ margin:0; } .block-editor-global-styles-background-panel__dropdown-toggle,.block-editor-global-styles-background-panel__image-preview-content{ height:100%; padding-left:12px; width:100%; } .block-editor-global-styles-background-panel__dropdown-toggle{ background:#0000; border:none; cursor:pointer; } .block-editor-global-styles-background-panel__inspector-media-replace-title{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-editor-global-styles-background-panel__inspector-preview-inner .block-editor-global-styles-background-panel__inspector-image-indicator-wrapper{ height:20px; min-width:auto; width:20px; } .block-editor-global-styles-background-panel__inspector-image-indicator{ background-size:cover; border-radius:50%; display:block; height:20px; position:relative; width:20px; } .block-editor-global-styles-background-panel__inspector-image-indicator:after{ border:1px solid #0000; border-radius:50%; bottom:-1px; box-shadow:inset 0 0 0 1px #0003; box-sizing:inherit; content:""; left:-1px; position:absolute; right:-1px; top:-1px; } .block-editor-global-styles-background-panel__dropdown-content-wrapper{ min-width:260px; overflow-x:hidden; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker-wrapper{ background-color:#f0f0f0; border:1px solid #ddd; border-radius:2px; width:100%; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker__media--image{ max-height:180px; } .block-editor-global-styles-background-panel__dropdown-content-wrapper .components-focal-point-picker:after{ content:none; } .modal-open .block-editor-global-styles-background-panel__popover{ z-index:159890; } .block-editor-global-styles-background-panel__media-replace-popover .components-popover__content{ width:226px; } .block-editor-global-styles-background-panel__media-replace-popover .components-button{ padding:0 8px; } .block-editor-global-styles-background-panel__media-replace-popover .components-button .components-menu-items__item-icon.has-icon-right{ margin-left:16px; } .block-editor-block-alignment-control__menu-group .components-menu-item__info{ margin-top:0; } iframe[name=editor-canvas]{ background-color:#ddd; box-sizing:border-box; display:block; height:100%; width:100%; } @media not (prefers-reduced-motion){ iframe[name=editor-canvas]{ transition:all .4s cubic-bezier(.46, .03, .52, .96); } } .block-editor-block-icon{ align-items:center; display:flex; height:24px; justify-content:center; width:24px; } .block-editor-block-icon.has-colors svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-block-icon.has-colors svg{ fill:CanvasText; } } .block-editor-block-icon svg{ max-height:24px; max-width:24px; min-height:20px; min-width:20px; } .block-editor-block-inspector p:not(.components-base-control__help){ margin-top:0; } .block-editor-block-inspector h2,.block-editor-block-inspector h3{ color:#1e1e1e; font-size:13px; margin-bottom:1.5em; } .block-editor-block-inspector .components-base-control:where(:not(:last-child)),.block-editor-block-inspector .components-radio-control:where(:not(:last-child)){ margin-bottom:16px; } .block-editor-block-inspector .components-focal-point-picker-control .components-base-control,.block-editor-block-inspector .components-query-controls .components-base-control,.block-editor-block-inspector .components-range-control .components-base-control{ margin-bottom:0; } .block-editor-block-inspector .components-panel__body{ border:none; border-top:1px solid #e0e0e0; margin-top:-1px; } .block-editor-block-inspector__no-block-tools,.block-editor-block-inspector__no-blocks{ background:#fff; display:block; font-size:13px; padding:32px 16px; text-align:center; } .block-editor-block-inspector__no-block-tools{ border-top:1px solid #ddd; } .block-editor-block-list__insertion-point{ bottom:0; left:0; position:absolute; right:0; top:0; } .block-editor-block-list__insertion-point-indicator{ background:var(--wp-admin-theme-color); border-radius:2px; opacity:0; position:absolute; transform-origin:center; will-change:transform, opacity; } .block-editor-block-list__insertion-point.is-vertical>.block-editor-block-list__insertion-point-indicator{ height:4px; top:calc(50% - 2px); width:100%; } .block-editor-block-list__insertion-point.is-horizontal>.block-editor-block-list__insertion-point-indicator{ bottom:0; left:calc(50% - 2px); top:0; width:4px; } .block-editor-block-list__insertion-point-inserter{ display:none; justify-content:center; left:calc(50% - 12px); position:absolute; top:calc(50% - 12px); will-change:transform; } @media (min-width:480px){ .block-editor-block-list__insertion-point-inserter{ display:flex; } } .block-editor-block-list__block-side-inserter-popover .components-popover__content>div{ pointer-events:none; } .block-editor-block-list__block-side-inserter-popover .components-popover__content>div>*{ pointer-events:all; } .block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter{ line-height:0; position:absolute; right:0; top:0; } .block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter:disabled{ display:none; } .block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{ background:#1e1e1e; color:#fff; height:24px; min-width:24px; padding:0; } .block-editor-block-list__empty-block-inserter .block-editor-inserter__toggle.components-button.has-icon:hover,.block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{ background:var(--wp-admin-theme-color); color:#fff; } .block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon{ background:var(--wp-admin-theme-color); } .block-editor-block-list__insertion-point-inserter .block-editor-inserter__toggle.components-button.has-icon:hover{ background:#1e1e1e; } @keyframes hide-during-dragging{ to{ position:fixed; transform:translate(9999px, 9999px); } } .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar{ border:1px solid #1e1e1e; border-radius:2px; margin-bottom:8px; margin-top:8px; overflow:visible; pointer-events:all; position:static; width:auto; } .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{ margin-left:56px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-contextual-toolbar.has-parent{ margin-left:0; } .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar{ overflow:visible; } .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar .components-toolbar-group{ border-right-color:#1e1e1e; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar{ background-color:#1e1e1e; color:#f0f0f0; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar.block-editor-block-contextual-toolbar{ border-color:#2f2f2f; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button{ color:#ddd; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:hover{ color:#fff; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:focus:before{ box-shadow:inset 0 0 0 1px #1e1e1e, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button:disabled,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar button[aria-disabled=true]{ color:#757575; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ background-color:#1e1e1e; border-color:#2f2f2f; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .block-editor-block-switcher__toggle{ color:#f0f0f0; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar,.components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .components-toolbar-group{ border-right-color:#2f2f2f !important; } .components-popover.block-editor-block-list__block-popover .is-inverted-toolbar .is-pressed{ color:var(--wp-admin-theme-color); } .components-popover.block-editor-block-list__block-popover.is-insertion-point-visible{ visibility:hidden; } .is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{ opacity:0; } @media not (prefers-reduced-motion){ .is-dragging-components-draggable .components-popover.block-editor-block-list__block-popover{ animation:hide-during-dragging 1ms linear forwards; } } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{ left:-57px; position:absolute; } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector:before{ content:""; } .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ background-color:#fff; border:1px solid #1e1e1e; padding-left:6px; padding-right:6px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ padding-left:12px; padding-right:12px; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-parent-selector{ left:auto; margin-left:-1px; position:relative; } .show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-mover__move-button-container,.show-icon-labels .components-popover.block-editor-block-list__block-popover .block-editor-block-toolbar__block-controls .block-editor-block-mover{ border-left:1px solid #1e1e1e; } .is-dragging-components-draggable .components-tooltip{ display:none; } .components-popover.block-editor-block-popover__inbetween .block-editor-button-pattern-inserter__button{ left:50%; pointer-events:all; position:absolute; top:50%; transform:translateX(-50%) translateY(-50%); } .block-editor-block-lock-modal{ z-index:1000001; } @media (min-width:600px){ .block-editor-block-lock-modal .components-modal__frame{ max-width:480px; } } .block-editor-block-lock-modal__options legend{ margin-bottom:16px; padding:0; } .block-editor-block-lock-modal__checklist{ margin:0; } .block-editor-block-lock-modal__options-all{ padding:12px 0; } .block-editor-block-lock-modal__options-all .components-checkbox-control__label{ font-weight:600; } .block-editor-block-lock-modal__checklist-item{ align-items:center; display:flex; gap:12px; justify-content:space-between; margin-bottom:0; padding:12px 0 12px 32px; } .block-editor-block-lock-modal__checklist-item .block-editor-block-lock-modal__lock-icon{ flex-shrink:0; margin-right:12px; fill:#1e1e1e; } .block-editor-block-lock-modal__checklist-item:hover{ background-color:#f0f0f0; border-radius:2px; } .block-editor-block-lock-modal__template-lock{ border-top:1px solid #ddd; margin-top:16px; padding-top:16px; } .block-editor-block-lock-modal__actions{ margin-top:24px; } .block-editor-block-lock-toolbar .components-button.has-icon{ min-width:36px !important; } .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{ margin-left:-6px !important; } .show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-lock-toolbar{ border-left:1px solid #1e1e1e; margin-left:6px !important; margin-right:-6px; } .block-editor-block-breadcrumb{ list-style:none; margin:0; padding:0; } .block-editor-block-breadcrumb li{ display:inline-flex; margin:0; } .block-editor-block-breadcrumb li .block-editor-block-breadcrumb__separator{ fill:currentColor; margin-left:-4px; margin-right:-4px; transform:scaleX(1); } .block-editor-block-breadcrumb li:last-child .block-editor-block-breadcrumb__separator{ display:none; } .block-editor-block-breadcrumb__current{ cursor:default; } .block-editor-block-breadcrumb__button.block-editor-block-breadcrumb__button,.block-editor-block-breadcrumb__current{ color:#1e1e1e; font-size:inherit; padding:0 8px; } .block-editor-block-card{ align-items:flex-start; color:#1e1e1e; display:flex; padding:16px; } .block-editor-block-card__title{ align-items:center; display:flex; flex-wrap:wrap; font-weight:500; gap:4px 8px; } .block-editor-block-card__title.block-editor-block-card__title{ font-size:13px; line-height:1.4; margin:0; } .block-editor-block-card__name{ padding:3px 0; } .block-editor-block-card .block-editor-block-icon{ flex:0 0 24px; height:24px; margin-left:0; margin-right:12px; width:24px; } .block-editor-block-card.is-synced .block-editor-block-icon{ color:var(--wp-block-synced-color); } .block-editor-block-compare{ height:auto; } .block-editor-block-compare__wrapper{ display:flex; padding-bottom:16px; } .block-editor-block-compare__wrapper>div{ display:flex; flex-direction:column; justify-content:space-between; max-width:600px; min-width:200px; padding:0 16px 0 0; width:50%; } .block-editor-block-compare__wrapper>div button{ float:right; } .block-editor-block-compare__wrapper .block-editor-block-compare__converted{ border-left:1px solid #ddd; padding-left:15px; padding-right:0; } .block-editor-block-compare__wrapper .block-editor-block-compare__html{ border-bottom:1px solid #ddd; color:#1e1e1e; font-family:Menlo,Consolas,monaco,monospace; font-size:12px; line-height:1.7; padding-bottom:15px; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span{ background-color:#e6ffed; padding-bottom:3px; padding-top:3px; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__added{ background-color:#acf2bd; } .block-editor-block-compare__wrapper .block-editor-block-compare__html span.block-editor-block-compare__removed{ background-color:#cc1818; } .block-editor-block-compare__wrapper .block-editor-block-compare__preview{ padding:16px 0 0; } .block-editor-block-compare__wrapper .block-editor-block-compare__preview p{ font-size:12px; margin-top:0; } .block-editor-block-compare__wrapper .block-editor-block-compare__action{ margin-top:16px; } .block-editor-block-compare__wrapper .block-editor-block-compare__heading{ font-size:1em; font-weight:400; margin:.67em 0; } .block-editor-block-draggable-chip-wrapper{ left:0; position:absolute; top:-24px; } .block-editor-block-draggable-chip{ background-color:#1e1e1e; border-radius:2px; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; color:#fff; cursor:grabbing; display:inline-flex; height:48px; padding:0 13px; position:relative; -webkit-user-select:none; user-select:none; width:max-content; } .block-editor-block-draggable-chip svg{ fill:currentColor; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content{ justify-content:flex-start; margin:auto; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item{ margin-right:6px; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content>.components-flex__item:last-child{ margin-right:0; } .block-editor-block-draggable-chip .block-editor-block-draggable-chip__content .block-editor-block-icon svg{ min-height:18px; min-width:18px; } .block-editor-block-draggable-chip .components-flex__item{ font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; } .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ align-items:center; background-color:initial; bottom:0; display:flex; justify-content:center; left:0; opacity:0; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ transition:all .1s linear .1s; } } .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled .block-editor-block-draggable-chip__disabled-icon{ background:#0000 linear-gradient(-45deg, #0000 47.5%, #fff 0, #fff 52.5%, #0000 0); border-radius:50%; box-shadow:inset 0 0 0 1.5px #fff; display:inline-block; height:20px; padding:0; width:20px; } .block-draggable-invalid-drag-token .block-editor-block-draggable-chip__disabled.block-editor-block-draggable-chip__disabled{ background-color:#757575; box-shadow:0 1px 2px #0000000d,0 2px 3px #0000000a,0 6px 6px #00000008,0 8px 8px #00000005; opacity:1; } .block-editor-block-manager__no-results{ font-style:italic; padding:24px 0; text-align:center; } .block-editor-block-manager__search{ margin:16px 0; } .block-editor-block-manager__disabled-blocks-count{ background-color:#fff; border:1px solid #ddd; border-width:1px 0; box-shadow:-32px 0 0 0 #fff,32px 0 0 0 #fff; padding:8px; position:sticky; text-align:center; top:-5px; z-index:2; } .block-editor-block-manager__disabled-blocks-count~.block-editor-block-manager__results .block-editor-block-manager__category-title{ top:31px; } .block-editor-block-manager__disabled-blocks-count .is-link{ margin-left:12px; } .block-editor-block-manager__category{ margin:0 0 24px; } .block-editor-block-manager__category-title{ background-color:#fff; padding:16px 0; position:sticky; top:-4px; z-index:1; } .block-editor-block-manager__category-title .components-checkbox-control__label{ font-weight:600; } .block-editor-block-manager__checklist{ margin-top:0; } .block-editor-block-manager__category-title,.block-editor-block-manager__checklist-item{ border-bottom:1px solid #ddd; } .block-editor-block-manager__checklist-item{ align-items:center; display:flex; justify-content:space-between; margin-bottom:0; padding:8px 0 8px 16px; } .components-modal__content .block-editor-block-manager__checklist-item.components-checkbox-control__input-container{ margin:0 8px; } .block-editor-block-manager__checklist-item .block-editor-block-icon{ margin-right:10px; fill:#1e1e1e; } .block-editor-block-manager__results{ border-top:1px solid #ddd; } .block-editor-block-manager__disabled-blocks-count+.block-editor-block-manager__results{ border-top-width:0; } .block-editor-block-mover__move-button-container{ border:none; display:flex; justify-content:center; padding:0; } @media (min-width:600px){ .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container{ flex-direction:column; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>*{ height:20px; min-width:0 !important; width:100%; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container>:before{ height:calc(100% - 4px); } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{ flex-shrink:0; top:3px; } .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{ bottom:3px; flex-shrink:0; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{ width:48px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container>*{ min-width:0 !important; overflow:hidden; width:24px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button{ padding-left:0; padding-right:0; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-up-button svg{ left:5px; } .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container .block-editor-block-mover-button.is-down-button svg{ right:5px; } } .block-editor-block-mover__drag-handle{ cursor:grab; } @media (min-width:600px){ .block-editor-block-mover__drag-handle{ min-width:0 !important; overflow:hidden; width:24px; } .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon.has-icon{ padding-left:0; padding-right:0; } } .components-button.block-editor-block-mover-button{ overflow:hidden; } .components-button.block-editor-block-mover-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .components-button.block-editor-block-mover-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .components-button.block-editor-block-mover-button:focus,.components-button.block-editor-block-mover-button:focus:before,.components-button.block-editor-block-mover-button:focus:enabled{ box-shadow:none; outline:none; } .components-button.block-editor-block-mover-button:focus-visible:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-navigation__container{ min-width:280px; } .block-editor-block-navigation__label{ color:#757575; font-size:11px; font-weight:500; margin:0 0 12px; text-transform:uppercase; } .block-editor-block-patterns-list__list-item{ cursor:pointer; margin-bottom:16px; position:relative; } .block-editor-block-patterns-list__list-item.is-placeholder{ min-height:100px; } .block-editor-block-patterns-list__list-item[draggable=true]{ cursor:grab; } .block-editor-block-patterns-list__item{ height:100%; outline:0; scroll-margin-bottom:56px; scroll-margin-top:24px; } .block-editor-block-patterns-list__item .block-editor-block-patterns-list__item-title{ flex-grow:1; font-size:12px; text-align:left; } .block-editor-block-patterns-list__item .block-editor-block-preview__container{ align-items:center; border-radius:4px; display:flex; overflow:hidden; } .block-editor-block-patterns-list__item .block-editor-block-preview__container:after{ border-radius:4px; outline:1px solid #0000001a; outline-offset:-1px; } @media not (prefers-reduced-motion){ .block-editor-block-patterns-list__item .block-editor-block-preview__container:after{ transition:outline .1s linear; } } .block-editor-block-patterns-list__item.is-selected .block-editor-block-preview__container:after{ outline-color:#1e1e1e; outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } .block-editor-block-patterns-list__item:hover .block-editor-block-preview__container:after{ outline-color:#0000004d; } .block-editor-block-patterns-list__item[data-focus-visible] .block-editor-block-preview__container:after{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-details:not(:empty){ align-items:center; margin-top:8px; padding-bottom:4px; } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper{ height:24px; min-width:24px; } .block-editor-block-patterns-list__item .block-editor-patterns__pattern-icon-wrapper .block-editor-patterns__pattern-icon{ fill:var(--wp-block-synced-color); } .block-editor-patterns__grid-pagination-wrapper .block-editor-patterns__grid-pagination{ border-top:1px solid #2f2f2f; justify-content:center; padding:4px; } .show-icon-labels .block-editor-patterns__grid-pagination-button{ width:auto; } .show-icon-labels .block-editor-patterns__grid-pagination-button span{ display:none; } .show-icon-labels .block-editor-patterns__grid-pagination-button:before{ content:attr(aria-label); } .components-popover.block-editor-block-popover{ margin:0 !important; pointer-events:none; position:absolute; z-index:31; } .components-popover.block-editor-block-popover .components-popover__content{ margin:0 !important; min-width:auto; overflow-y:visible; width:max-content; } .components-popover.block-editor-block-popover:not(.block-editor-block-popover__inbetween,.block-editor-block-popover__drop-zone,.block-editor-block-list__block-side-inserter-popover) .components-popover__content *{ pointer-events:all; } .components-popover.block-editor-block-popover__inbetween,.components-popover.block-editor-block-popover__inbetween *{ pointer-events:none; } .components-popover.block-editor-block-popover__inbetween .is-with-inserter,.components-popover.block-editor-block-popover__inbetween .is-with-inserter *{ pointer-events:all; } .components-popover.block-editor-block-popover__drop-zone *{ pointer-events:none; } .components-popover.block-editor-block-popover__drop-zone .block-editor-block-popover__drop-zone-foreground{ background-color:var(--wp-admin-theme-color); border-radius:2px; inset:0; position:absolute; } .block-editor-block-preview__container{ overflow:hidden; position:relative; width:100%; } .block-editor-block-preview__container .block-editor-block-preview__content{ left:0; margin:0; min-height:auto; overflow:visible; text-align:initial; top:0; transform-origin:top left; width:100%; } .block-editor-block-preview__container .block-editor-block-preview__content .block-editor-block-list__insertion-point,.block-editor-block-preview__container .block-editor-block-preview__content .block-list-appender{ display:none; } .block-editor-block-preview__container:after{ bottom:0; content:""; left:0; position:absolute; right:0; top:0; z-index:1; } .block-editor-block-rename-modal{ z-index:1000001; } .block-editor-block-styles__preview-panel{ display:none; z-index:90; } @media (min-width:782px){ .block-editor-block-styles__preview-panel{ display:block; } } .block-editor-block-styles__preview-panel .block-editor-block-icon{ display:none; } .block-editor-block-styles__variants{ display:flex; flex-wrap:wrap; gap:8px; justify-content:space-between; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item{ box-shadow:inset 0 0 0 1px #ddd; color:#1e1e1e; display:inline-block; width:calc(50% - 4px); } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:hover{ box-shadow:inset 0 0 0 1px #ddd; color:var(--wp-admin-theme-color); } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover{ background-color:#1e1e1e; box-shadow:none; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active .block-editor-block-styles__item-text,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:hover .block-editor-block-styles__item-text{ color:#fff; } .block-editor-block-styles__variants button.components-button.block-editor-block-styles__item.is-active:focus,.block-editor-block-styles__variants button.components-button.block-editor-block-styles__item:focus{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-styles__variants .block-editor-block-styles__item-text{ text-align:start; text-align-last:center; white-space:normal; word-break:break-all; } .block-editor-block-styles__block-preview-container,.block-editor-block-styles__block-preview-container *{ box-sizing:border-box !important; } .block-editor-block-switcher{ position:relative; } .block-editor-block-switcher .components-button.components-dropdown-menu__toggle.has-icon.has-icon{ min-width:36px; } .block-editor-block-switcher__no-switcher-icon,.block-editor-block-switcher__toggle{ position:relative; } .components-button.block-editor-block-switcher__no-switcher-icon,.components-button.block-editor-block-switcher__toggle{ display:block; height:48px; margin:0; } .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.components-button.block-editor-block-switcher__toggle .block-editor-block-icon{ margin:auto; } .components-button.block-editor-block-switcher__no-switcher-icon{ display:flex; } .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ margin-left:auto; margin-right:auto; min-width:24px !important; } .components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true],.components-button.block-editor-block-switcher__no-switcher-icon[aria-disabled=true]:hover{ color:#1e1e1e; } .components-popover.block-editor-block-switcher__popover .components-popover__content{ min-width:300px; } .block-editor-block-switcher__popover-preview-container{ bottom:0; left:0; pointer-events:none; position:absolute; top:-1px; width:100%; } .block-editor-block-switcher__popover-preview{ overflow:hidden; } .block-editor-block-switcher__popover-preview .components-popover__content{ background:#fff; border:1px solid #1e1e1e; border-radius:4px; box-shadow:none; outline:none; overflow:auto; width:300px; } .block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview{ margin:16px 0; max-height:468px; overflow:hidden; padding:0 16px; } .block-editor-block-switcher__popover-preview .block-editor-block-switcher__preview.is-pattern-list-preview{ overflow:unset; } .block-editor-block-switcher__preview-title{ color:#757575; font-size:11px; font-weight:500; margin-bottom:12px; text-transform:uppercase; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon{ min-width:36px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle{ height:48px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-icon,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{ height:48px; width:48px; } .block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__no-switcher-icon .block-editor-block-switcher__transform,.block-editor-block-contextual-toolbar .components-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform{ padding:12px; } .block-editor-block-switcher__preview-patterns-container{ padding-bottom:16px; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item{ margin-top:16px; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-preview__container{ cursor:pointer; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{ border:1px solid #0000; border-radius:2px; height:100%; position:relative; } @media not (prefers-reduced-motion){ .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item{ transition:all .05s ease-in-out; } } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:focus,.block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item:hover{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) #1e1e1e; } .block-editor-block-switcher__preview-patterns-container .block-editor-block-switcher__preview-patterns-container-list__list-item .block-editor-block-switcher__preview-patterns-container-list__item .block-editor-block-switcher__preview-patterns-container-list__item-title{ cursor:pointer; font-size:12px; padding:4px; text-align:center; } .block-editor-block-switcher__no-transforms{ color:#757575; margin:0; padding:6px 8px; } .block-editor-block-switcher__binding-indicator{ display:block; padding:8px; } .block-editor-block-types-list>[role=presentation]{ display:flex; flex-wrap:wrap; overflow:hidden; } .block-editor-block-pattern-setup{ align-items:flex-start; border-radius:2px; display:flex; flex-direction:column; justify-content:center; width:100%; } .block-editor-block-pattern-setup.view-mode-grid{ padding-top:4px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__toolbar{ justify-content:center; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{ column-count:2; column-gap:24px; display:block; padding:0 32px; width:100%; } @media (min-width:1440px){ .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container{ column-count:3; } } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-preview__container,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container div[role=button]{ cursor:pointer; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item{ scroll-margin:5px 0; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-preview__container{ box-shadow:0 0 0 2px var(--wp-admin-theme-color); } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-preview__container{ box-shadow:0 0 0 var(--wp-admin-border-width-focus) #fff, 0 0 0 calc(var(--wp-admin-border-width-focus)*2) var(--wp-admin-theme-color); outline:2px solid #0000; outline-offset:2px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:focus .block-editor-block-pattern-setup-list__item-title,.block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__item:hover .block-editor-block-pattern-setup-list__item-title{ color:var(--wp-admin-theme-color); } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item{ break-inside:avoid-column; margin-bottom:24px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-pattern-setup-list__item-title{ cursor:pointer; font-size:12px; padding-top:8px; text-align:center; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__container{ border:1px solid #ddd; border-radius:4px; min-height:100px; } .block-editor-block-pattern-setup.view-mode-grid .block-editor-block-pattern-setup__container .block-editor-block-pattern-setup-list__list-item .block-editor-block-preview__content{ width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar{ align-items:center; align-self:stretch; background-color:#fff; border-top:1px solid #ddd; bottom:0; box-sizing:border-box; color:#1e1e1e; display:flex; flex-direction:row; height:60px; justify-content:space-between; margin:0; padding:16px; position:absolute; text-align:left; width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__display-controls{ display:flex; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions,.block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__navigation{ display:flex; width:calc(50% - 36px); } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__toolbar .block-editor-block-pattern-setup__actions{ justify-content:flex-end; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container{ box-sizing:border-box; display:flex; flex-direction:column; height:100%; width:100%; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container{ height:100%; list-style:none; margin:0; overflow:hidden; padding:0; position:relative; transform-style:preserve-3d; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container *{ box-sizing:border-box; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{ background-color:#fff; height:100%; margin:auto; padding:0; position:absolute; top:0; width:100%; z-index:100; } @media not (prefers-reduced-motion){ .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide{ transition:transform .5s,z-index .5s; } } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.active-slide{ opacity:1; position:relative; z-index:102; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.previous-slide{ transform:translateX(-100%); z-index:101; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .carousel-container .pattern-slide.next-slide{ transform:translateX(100%); z-index:101; } .block-editor-block-pattern-setup .block-editor-block-pattern-setup__container .block-list-appender{ display:none; } .block-editor-block-pattern-setup__carousel,.block-editor-block-pattern-setup__grid{ width:100%; } .block-editor-block-variation-transforms{ padding:0 16px 16px 52px; width:100%; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle{ border:1px solid #757575; border-radius:2px; justify-content:left; min-height:30px; padding:6px 12px; position:relative; text-align:left; width:100%; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle.components-dropdown-menu__toggle{ padding-right:24px; } .block-editor-block-variation-transforms .components-dropdown-menu__toggle:focus:not(:disabled){ border-color:var(--wp-admin-theme-color); box-shadow:0 0 0 calc(var(--wp-admin-border-width-focus) - 1px) var(--wp-admin-theme-color); } .block-editor-block-variation-transforms .components-dropdown-menu__toggle svg{ height:100%; padding:0; position:absolute; right:0; top:0; } .block-editor-block-variation-transforms__popover .components-popover__content{ min-width:230px; } .components-border-radius-control{ margin-bottom:12px; } .components-border-radius-control legend{ margin-bottom:8px; } .components-border-radius-control .components-border-radius-control__wrapper{ align-items:flex-start; display:flex; justify-content:space-between; } .components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__unit-control{ flex-shrink:0; margin-bottom:0; margin-right:16px; width:calc(50% - 8px); } .components-border-radius-control .components-border-radius-control__wrapper .components-border-radius-control__range-control{ flex:1; margin-right:12px; } .components-border-radius-control .components-border-radius-control__input-controls-wrapper{ display:grid; gap:16px; grid-template-columns:repeat(2, minmax(0, 1fr)); margin-right:12px; } .components-border-radius-control .component-border-radius-control__linked-button{ display:flex; justify-content:center; margin-top:8px; } .components-border-radius-control .component-border-radius-control__linked-button svg{ margin-right:0; } .block-editor-color-gradient-control .block-editor-color-gradient-control__color-indicator{ margin-bottom:12px; } .block-editor-color-gradient-control__fieldset{ min-width:0; } .block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings,.block-editor-panel-color-gradient-settings.block-editor-panel-color-gradient-settings>div:not(:first-of-type){ display:block; } @media screen and (min-width:782px){ .block-editor-panel-color-gradient-settings .components-circular-option-picker__swatches{ display:grid; grid-template-columns:repeat(6, 28px); } } .block-editor-block-inspector .block-editor-panel-color-gradient-settings .components-base-control{ margin-bottom:inherit; } .block-editor-panel-color-gradient-settings__dropdown-content .block-editor-color-gradient-control__panel{ padding:16px; width:260px; } .block-editor-panel-color-gradient-settings__color-indicator{ background:linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .block-editor-tools-panel-color-gradient-settings__item{ border-bottom:1px solid #ddd; border-left:1px solid #ddd; border-right:1px solid #ddd; max-width:100%; padding:0; position:relative; } .block-editor-tools-panel-color-gradient-settings__item:nth-child(1 of .block-editor-tools-panel-color-gradient-settings__item){ border-top:1px solid #ddd; border-top-left-radius:2px; border-top-right-radius:2px; margin-top:24px; } .block-editor-tools-panel-color-gradient-settings__item:nth-last-child(1 of .block-editor-tools-panel-color-gradient-settings__item){ border-bottom-left-radius:2px; border-bottom-right-radius:2px; } .block-editor-tools-panel-color-gradient-settings__item>div,.block-editor-tools-panel-color-gradient-settings__item>div>button{ border-radius:inherit; } .block-editor-tools-panel-color-gradient-settings__dropdown{ display:block; padding:0; } .block-editor-tools-panel-color-gradient-settings__dropdown>button{ height:auto; padding-bottom:10px; padding-top:10px; text-align:left; } .block-editor-tools-panel-color-gradient-settings__dropdown>button.is-open{ background:#f0f0f0; color:var(--wp-admin-theme-color); } .block-editor-tools-panel-color-gradient-settings__dropdown .block-editor-panel-color-gradient-settings__color-name{ max-width:calc(100% - 44px); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-panel-color-gradient-settings__dropdown{ width:100%; } .block-editor-panel-color-gradient-settings__dropdown .component-color-indicator{ flex-shrink:0; } .block-editor-panel-color-gradient-settings__reset{ margin:auto 8px; opacity:0; position:absolute; right:0; top:8px; } @media not (prefers-reduced-motion){ .block-editor-panel-color-gradient-settings__reset{ transition:opacity .1s ease-in-out; } } .block-editor-panel-color-gradient-settings__reset.block-editor-panel-color-gradient-settings__reset{ border-radius:2px; } .block-editor-panel-color-gradient-settings__dropdown:hover+.block-editor-panel-color-gradient-settings__reset,.block-editor-panel-color-gradient-settings__reset:focus,.block-editor-panel-color-gradient-settings__reset:hover{ opacity:1; } @media (hover:none){ .block-editor-panel-color-gradient-settings__reset{ opacity:1; } } .block-editor-date-format-picker{ border:none; margin:0 0 16px; padding:0; } .block-editor-date-format-picker__custom-format-select-control__custom-option{ border-top:1px solid #ddd; } .block-editor-duotone-control__popover.components-popover>.components-popover__content{ padding:8px; width:260px; } .block-editor-duotone-control__popover.components-popover .components-menu-group__label{ padding:0; } .block-editor-duotone-control__popover.components-popover .components-circular-option-picker__swatches{ display:grid; gap:12px; grid-template-columns:repeat(6, 28px); justify-content:space-between; } .block-editor-duotone-control__unset-indicator{ background:linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .components-font-appearance-control [role=option]{ color:#1e1e1e; text-transform:capitalize; } .block-editor-font-family-control:not(.is-next-has-no-margin-bottom){ margin-bottom:8px; } .block-editor-global-styles__toggle-icon{ fill:currentColor; } .block-editor-global-styles__shadow-popover-container{ width:230px; } .block-editor-global-styles__shadow__list{ display:flex; flex-wrap:wrap; gap:12px; padding-bottom:8px; } .block-editor-global-styles__clear-shadow{ text-align:right; } .block-editor-global-styles-filters-panel__dropdown,.block-editor-global-styles__shadow-dropdown{ display:block; padding:0; position:relative; } .block-editor-global-styles-filters-panel__dropdown button,.block-editor-global-styles__shadow-dropdown button{ padding:8px; width:100%; } .block-editor-global-styles-filters-panel__dropdown button.is-open,.block-editor-global-styles__shadow-dropdown button.is-open{ background-color:#f0f0f0; } .block-editor-global-styles__shadow-editor__remove-button{ margin:auto 8px; opacity:0; position:absolute; right:0; top:8px; } @media not (prefers-reduced-motion){ .block-editor-global-styles__shadow-editor__remove-button{ transition:opacity .1s ease-in-out; } } .block-editor-global-styles__shadow-dropdown:hover .block-editor-global-styles__shadow-editor__remove-button,.block-editor-global-styles__shadow-editor__remove-button:focus,.block-editor-global-styles__shadow-editor__remove-button:hover{ opacity:1; } @media (hover:none){ .block-editor-global-styles__shadow-editor__remove-button{ opacity:1; } } .block-editor-global-styles-filters-panel__dropdown{ border:1px solid #ddd; border-radius:2px; } .block-editor-global-styles__shadow-indicator{ align-items:center; appearance:none; background:none; border:1px solid #e0e0e0; border-radius:2px; box-sizing:border-box; color:#2f2f2f; cursor:pointer; display:inline-flex; height:26px; padding:0; transform:scale(1); width:26px; will-change:transform; } @media not (prefers-reduced-motion){ .block-editor-global-styles__shadow-indicator{ transition:transform .1s ease; } } .block-editor-global-styles__shadow-indicator:focus{ border:2px solid #757575; } .block-editor-global-styles__shadow-indicator:hover{ transform:scale(1.2); } .block-editor-global-styles__shadow-indicator.unset{ background:linear-gradient(-45deg, #0000 48%, #ddd 0, #ddd 52%, #0000 0); } .block-editor-global-styles-advanced-panel__custom-css-input textarea{ direction:ltr; font-family:Menlo,Consolas,monaco,monospace; } .block-editor-panel-duotone-settings__reset{ margin:auto 8px; opacity:0; position:absolute; right:0; top:8px; } @media not (prefers-reduced-motion){ .block-editor-panel-duotone-settings__reset{ transition:opacity .1s ease-in-out; } } .block-editor-global-styles-filters-panel__dropdown:hover .block-editor-panel-duotone-settings__reset,.block-editor-panel-duotone-settings__reset:focus,.block-editor-panel-duotone-settings__reset:hover{ opacity:1; } @media (hover:none){ .block-editor-panel-duotone-settings__reset{ opacity:1; } } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer{ z-index:30; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .components-popover__content *{ pointer-events:none; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer.is-dropping-allowed .block-editor-grid-visualizer__drop-zone{ pointer-events:all; } .block-editor-grid-visualizer.block-editor-grid-visualizer.block-editor-grid-visualizer .block-editor-inserter *{ pointer-events:auto; } .block-editor-grid-visualizer__grid{ display:grid; position:absolute; } .block-editor-grid-visualizer__cell{ display:grid; position:relative; } .block-editor-grid-visualizer__cell .block-editor-inserter{ bottom:0; color:inherit; left:0; overflow:hidden; position:absolute; right:0; top:0; z-index:32; } .block-editor-grid-visualizer__cell .block-editor-inserter .block-editor-grid-visualizer__appender{ box-shadow:inset 0 0 0 1px color-mix(in srgb, currentColor 20%, #0000); color:inherit; height:100%; opacity:0; overflow:hidden; padding:0 !important; width:100%; } .block-editor-grid-visualizer__cell.is-highlighted .block-editor-grid-visualizer__drop-zone,.block-editor-grid-visualizer__cell.is-highlighted .block-editor-inserter{ background:var(--wp-admin-theme-color); } .block-editor-grid-visualizer__cell .block-editor-grid-visualizer__appender:focus,.block-editor-grid-visualizer__cell:hover .block-editor-grid-visualizer__appender{ background-color:color-mix(in srgb, currentColor 20%, #0000); opacity:1; } .block-editor-grid-visualizer__drop-zone{ background:#cccccc1a; grid-column:1; grid-row:1; height:100%; min-height:8px; min-width:8px; width:100%; } .block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer{ z-index:30; } .block-editor-grid-item-resizer.block-editor-grid-item-resizer.block-editor-grid-item-resizer .components-popover__content *{ pointer-events:none; } .block-editor-grid-item-resizer__box{ border:1px solid var(--wp-admin-theme-color); } .block-editor-grid-item-resizer__box .components-resizable-box__handle.components-resizable-box__handle.components-resizable-box__handle{ pointer-events:all; } .block-editor-grid-item-mover__move-button-container{ border:none; display:flex; justify-content:center; padding:0; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button{ min-width:0 !important; padding-left:0; padding-right:0; width:24px; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button svg{ min-width:24px; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{ border-radius:2px; content:""; display:block; height:32px; left:8px; position:absolute; right:8px; z-index:-1; } @media not (prefers-reduced-motion){ .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:before{ animation:components-button__appear-animation .1s ease; animation-fill-mode:forwards; } } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:before,.block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus:enabled{ box-shadow:none; outline:none; } .block-editor-grid-item-mover__move-button-container .block-editor-grid-item-mover-button:focus-visible:before{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-grid-item-mover__move-vertical-button-container{ display:flex; position:relative; } @media (min-width:600px){ .block-editor-grid-item-mover__move-vertical-button-container{ flex-direction:column; justify-content:space-around; } .block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button{ height:20px !important; min-width:0 !important; width:100%; } .block-editor-grid-item-mover__move-vertical-button-container>.block-editor-grid-item-mover-button.block-editor-grid-item-mover-button:before{ height:calc(100% - 4px); } .block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-down-button svg,.block-editor-grid-item-mover__move-vertical-button-container .block-editor-grid-item-mover-button.is-up-button svg{ flex-shrink:0; height:20px; } .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container{ height:40px; position:relative; top:-5px; } } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container{ position:relative; } @media (min-width:600px){ .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#e0e0e0; content:""; height:100%; position:absolute; top:0; width:1px; } } @media (min-width:782px){ .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left{ padding-right:6px; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-left:before{ right:0; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right{ padding-left:6px; } .show-icon-labels .block-editor-grid-item-mover__move-horizontal-button-container.is-right:before{ left:0; } @media (min-width:600px){ .show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#e0e0e0; content:""; height:1px; left:50%; margin-top:-.5px; position:absolute; top:50%; transform:translate(-50%); width:100%; } } @media (min-width:782px){ .show-icon-labels .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-grid-item-mover-button{ white-space:nowrap; } .show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-horizontal-button-container:before{ background:#ddd; height:24px; top:4px; } .show-icon-labels .editor-collapsible-block-toolbar .block-editor-grid-item-mover__move-vertical-button-container:before{ background:#ddd; width:calc(100% - 24px); } .block-editor-height-control{ border:0; margin:0; padding:0; } .block-editor-iframe__container{ height:100%; width:100%; } .block-editor-iframe__scale-container{ height:100%; } .block-editor-iframe__scale-container.is-zoomed-out{ position:absolute; right:0; width:var(--wp-block-editor-iframe-zoom-out-scale-container-width, 100vw); } .block-editor-image-size-control{ margin-bottom:1em; } .block-editor-image-size-control .block-editor-image-size-control__height,.block-editor-image-size-control .block-editor-image-size-control__width{ margin-bottom:1.115em; } .block-editor-block-types-list__list-item{ display:block; margin:0; padding:0; width:33.33%; } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled) .block-editor-block-icon.has-colors{ color:var(--wp-block-synced-color); } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{ color:var(--wp-block-synced-color) !important; filter:brightness(.95); } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{ color:var(--wp-block-synced-color) !important; } .block-editor-block-types-list__list-item.is-synced .components-button.block-editor-block-types-list__item:not(:disabled):after{ background:var(--wp-block-synced-color); } .components-button.block-editor-block-types-list__item{ align-items:stretch; background:#0000; color:#1e1e1e; cursor:pointer; display:flex; flex-direction:column; font-size:13px; height:auto; justify-content:center; padding:8px; position:relative; width:100%; word-break:break-word; } @media not (prefers-reduced-motion){ .components-button.block-editor-block-types-list__item{ transition:all .05s ease-in-out; } } .components-button.block-editor-block-types-list__item:disabled{ cursor:default; opacity:.6; } .components-button.block-editor-block-types-list__item:not(:disabled):hover .block-editor-block-types-list__item-title{ color:var(--wp-admin-theme-color) !important; filter:brightness(.95); } .components-button.block-editor-block-types-list__item:not(:disabled):hover svg{ color:var(--wp-admin-theme-color) !important; } .components-button.block-editor-block-types-list__item:not(:disabled):hover:after{ background:var(--wp-admin-theme-color); border-radius:2px; bottom:0; content:""; left:0; opacity:.04; pointer-events:none; position:absolute; right:0; top:0; } .components-button.block-editor-block-types-list__item:not(:disabled):focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .components-button.block-editor-block-types-list__item:not(:disabled).is-active{ background:#1e1e1e; color:#fff; outline:2px solid #0000; outline-offset:-2px; } .block-editor-block-types-list__item-icon{ color:#1e1e1e; padding:12px 20px; } @media not (prefers-reduced-motion){ .block-editor-block-types-list__item-icon{ transition:all .05s ease-in-out; } } .block-editor-block-types-list__item-icon .block-editor-block-icon{ margin-left:auto; margin-right:auto; } @media not (prefers-reduced-motion){ .block-editor-block-types-list__item-icon svg{ transition:all .15s ease-out; } } .block-editor-block-types-list__list-item[draggable=true] .block-editor-block-types-list__item-icon{ cursor:grab; } .block-editor-block-types-list__item-title{ font-size:12px; hyphens:auto; padding:4px 2px 8px; } .block-editor-block-inspector__tabs [role=tablist]{ width:100%; } .block-editor-inspector-popover-header{ margin-bottom:16px; } .items-justified-left{ justify-content:flex-start; } .items-justified-center{ justify-content:center; } .items-justified-right{ justify-content:flex-end; } .items-justified-space-between{ justify-content:space-between; } @keyframes loadingpulse{ 0%{ opacity:1; } 50%{ opacity:0; } to{ opacity:1; } } .block-editor-link-control{ min-width:350px; position:relative; } .components-popover__content .block-editor-link-control{ max-width:350px; min-width:auto; width:90vw; } .show-icon-labels .block-editor-link-control .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-link-control .components-button.has-icon:before{ content:attr(aria-label); } .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top{ flex-wrap:wrap; gap:4px; } .show-icon-labels .block-editor-link-control .block-editor-link-control__search-item-top .components-button.has-icon{ padding:4px; width:auto; } .show-icon-labels .block-editor-link-control .is-preview .block-editor-link-control__search-item-header{ margin-right:0; min-width:100%; } .block-editor-link-control__search-input-wrapper{ margin-bottom:8px; position:relative; } .block-editor-link-control__search-input-container,.block-editor-link-control__search-input-wrapper{ position:relative; } .block-editor-link-control__field{ margin:16px; } .block-editor-link-control__field .components-base-control__label{ color:#1e1e1e; } .block-editor-link-control__search-error{ margin:-8px 16px 16px; } .block-editor-link-control__search-actions{ padding:8px 16px 16px; } .block-editor-link-control__search-results-wrapper{ position:relative; } .block-editor-link-control__search-results-wrapper:after,.block-editor-link-control__search-results-wrapper:before{ content:""; display:block; left:-1px; pointer-events:none; position:absolute; right:16px; z-index:100; } .block-editor-link-control__search-results-wrapper:before{ bottom:auto; height:8px; top:0; } .block-editor-link-control__search-results-wrapper:after{ bottom:0; height:16px; top:auto; } .block-editor-link-control__search-results{ margin-top:-16px; max-height:200px; overflow-y:auto; padding:8px; } .block-editor-link-control__search-results.is-loading{ opacity:.2; } .block-editor-link-control__search-item.components-button.components-menu-item__button{ height:auto; text-align:left; } .block-editor-link-control__search-item .components-menu-item__item{ display:inline-block; overflow:hidden; text-overflow:ellipsis; width:100%; } .block-editor-link-control__search-item .components-menu-item__item mark{ background-color:initial; color:inherit; font-weight:600; } .block-editor-link-control__search-item .components-menu-item__shortcut{ color:#757575; text-transform:capitalize; white-space:nowrap; } .block-editor-link-control__search-item[aria-selected]{ background:#f0f0f0; } .block-editor-link-control__search-item.is-current{ background:#0000; border:0; cursor:default; flex-direction:column; padding:16px; width:100%; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header{ align-items:center; display:block; flex-direction:row; gap:8px; margin-right:8px; overflow-wrap:break-word; white-space:pre-wrap; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-info{ color:#757575; font-size:12px; line-height:1.1; word-break:break-all; } .block-editor-link-control__search-item.is-preview .block-editor-link-control__search-item-header{ display:flex; flex:1; } .block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-header{ align-items:center; } .block-editor-link-control__search-item.is-url-title .block-editor-link-control__search-item-title{ word-break:break-all; } .block-editor-link-control__search-item .block-editor-link-control__search-item-details{ display:flex; flex-direction:column; gap:4px; justify-content:space-between; } .block-editor-link-control__search-item .block-editor-link-control__search-item-header .block-editor-link-control__search-item-icon{ background-color:#f0f0f0; border-radius:2px; height:32px; width:32px; } .block-editor-link-control__search-item .block-editor-link-control__search-item-icon{ align-items:center; display:flex; flex-shrink:0; justify-content:center; position:relative; } .block-editor-link-control__search-item .block-editor-link-control__search-item-icon img{ width:16px; } .block-editor-link-control__search-item.is-error .block-editor-link-control__search-item-icon{ max-height:32px; top:0; width:32px; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title{ line-height:1.1; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus{ box-shadow:none; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title:focus-visible{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; text-decoration:none; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title mark{ background-color:initial; color:inherit; font-weight:600; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title span{ font-weight:400; } .block-editor-link-control__search-item .block-editor-link-control__search-item-title .components-external-link__icon{ height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; clip:rect(0, 0, 0, 0); border:0; } .block-editor-link-control__search-item-top{ align-items:center; display:flex; flex-direction:row; width:100%; } .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon img,.block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon svg{ opacity:0; } .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{ background-color:#f0f0f0; border-radius:100%; bottom:0; content:""; display:block; left:0; position:absolute; right:0; top:0; } @media not (prefers-reduced-motion){ .block-editor-link-control__search-item.is-fetching .block-editor-link-control__search-item-icon:before{ animation:loadingpulse 1s linear infinite; animation-delay:.5s; } } .block-editor-link-control__loading{ align-items:center; display:flex; margin:16px; } .block-editor-link-control__loading .components-spinner{ margin-top:0; } .components-button+.block-editor-link-control__search-create{ overflow:visible; padding:12px 16px; } .components-button+.block-editor-link-control__search-create:before{ content:""; display:block; left:0; position:absolute; top:-10px; width:100%; } .block-editor-link-control__search-create{ align-items:center; } .block-editor-link-control__search-create .block-editor-link-control__search-item-title{ margin-bottom:0; } .block-editor-link-control__search-create .block-editor-link-control__search-item-icon{ top:0; } .block-editor-link-control__drawer-inner{ display:flex; flex-basis:100%; flex-direction:column; position:relative; } .block-editor-link-control__setting{ flex:1; margin-bottom:0; padding:8px 0 8px 24px; } .block-editor-link-control__setting .components-base-control__field{ display:flex; } .block-editor-link-control__setting .components-base-control__field .components-checkbox-control__label{ color:#1e1e1e; } .block-editor-link-control__setting input{ margin-left:0; } .is-preview .block-editor-link-control__setting{ padding:20px 8px 8px 0; } .block-editor-link-control__tools{ margin-top:-16px; padding:8px 8px 0; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle{ gap:0; padding-left:0; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true]{ color:#1e1e1e; } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{ transform:rotate(90deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=true] svg{ transition:transform .1s ease; } } .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{ transform:rotate(0deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-link-control__tools .components-button.block-editor-link-control__drawer-toggle[aria-expanded=false] svg{ transition:transform .1s ease; } } .block-editor-link-control .block-editor-link-control__search-input .components-spinner{ display:block; } .block-editor-link-control .block-editor-link-control__search-input .components-spinner.components-spinner{ bottom:auto; left:auto; position:absolute; right:40px; top:calc(50% - 8px); } .block-editor-link-control .block-editor-link-control__search-input-wrapper.has-actions .components-spinner{ right:12px; top:calc(50% + 4px); } .block-editor-list-view-tree{ border-collapse:collapse; margin:0; padding:0; width:100%; } .components-modal__content .block-editor-list-view-tree{ margin:-12px -6px 0; width:calc(100% + 12px); } .block-editor-list-view-tree.is-dragging tbody{ pointer-events:none; } .block-editor-list-view-leaf{ position:relative; transform:translateY(0); } .block-editor-list-view-leaf.is-draggable,.block-editor-list-view-leaf.is-draggable .block-editor-list-view-block-contents{ cursor:grab; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button[aria-expanded=true]{ color:inherit; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button:hover{ color:var(--wp-admin-theme-color); } .block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{ fill:currentColor; } @media (forced-colors:active){ .block-editor-list-view-leaf .block-editor-list-view-block-select-button svg{ fill:CanvasText; } } .is-dragging-components-draggable .block-editor-list-view-leaf:not(.is-selected) .block-editor-list-view-block-select-button:hover{ color:inherit; } .block-editor-list-view-leaf.is-selected td{ background:var(--wp-admin-theme-color); } .block-editor-list-view-leaf.is-selected.is-synced td{ background:var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents .block-editor-block-icon,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:hover{ color:var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-synced:not(.is-selected) .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents,.block-editor-list-view-leaf.is-selected .components-button.has-icon{ color:#fff; } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); } .block-editor-list-view-leaf.is-selected.is-synced .block-editor-list-view-block-contents:focus:after{ box-shadow:inset 0 0 0 1px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-block-synced-color); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block__menu:focus{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) #fff; } .block-editor-list-view-leaf.is-first-selected td:first-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf.is-first-selected td:last-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf.is-last-selected td:first-child{ border-bottom-left-radius:2px; } .block-editor-list-view-leaf.is-last-selected td:last-child{ border-bottom-right-radius:2px; } .block-editor-list-view-leaf.is-branch-selected:not(.is-selected):not(.is-synced-branch){ background:rgba(var(--wp-admin-theme-color--rgb), .04); } .block-editor-list-view-leaf.is-synced-branch.is-branch-selected{ background:rgba(var(--wp-block-synced-color--rgb), .04); } .block-editor-list-view-leaf.is-branch-selected.is-first-selected td:first-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf.is-branch-selected.is-first-selected td:last-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:first-child{ border-top-left-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-first-selected td:last-child{ border-top-right-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:first-child{ border-bottom-left-radius:2px; } .block-editor-list-view-leaf[data-expanded=false].is-branch-selected.is-last-selected td:last-child{ border-bottom-right-radius:2px; } .block-editor-list-view-leaf.is-branch-selected:not(.is-selected) td{ border-radius:0; } .block-editor-list-view-leaf.is-displacement-normal{ transform:translateY(0); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-normal{ transition:transform .2s; } } .block-editor-list-view-leaf.is-displacement-up{ transform:translateY(-32px); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-up{ transition:transform .2s; } } .block-editor-list-view-leaf.is-displacement-down{ transform:translateY(32px); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-displacement-down{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks{ transform:translateY(calc(var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{ transform:translateY(calc(-32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-up{ transition:transform .2s; } } .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{ transform:translateY(calc(32px + var(--wp-admin--list-view-dragged-items-height, 32px)*-1)); } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-after-dragged-blocks.is-displacement-down{ transition:transform .2s; } } .block-editor-list-view-leaf.is-dragging{ left:0; opacity:0; pointer-events:none; z-index:-9999; } .block-editor-list-view-leaf .block-editor-list-view-block-contents{ align-items:center; border-radius:2px; box-sizing:border-box; color:inherit; display:flex; font-family:inherit; font-size:13px; font-weight:400; height:32px; margin:0; padding:6px 4px 6px 0; position:relative; text-align:left; text-decoration:none; white-space:nowrap; width:100%; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf .block-editor-list-view-block-contents{ transition:box-shadow .1s linear; } } .components-modal__content .block-editor-list-view-leaf .block-editor-list-view-block-contents{ padding-left:0; padding-right:0; } .block-editor-list-view-leaf .block-editor-list-view-block-contents:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents{ box-shadow:none; } .block-editor-list-view-leaf .block-editor-list-view-block-contents:focus:after,.block-editor-list-view-leaf.is-nesting .block-editor-list-view-block-contents:after{ border-radius:inherit; bottom:0; box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); content:""; left:0; pointer-events:none; position:absolute; right:-29px; top:0; z-index:2; } .block-editor-list-view-leaf.has-single-cell .block-editor-list-view-block-contents:focus:after{ right:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu:focus,.block-editor-list-view-leaf.is-nesting .block-editor-list-view__menu{ box-shadow:inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); z-index:1; } .block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{ opacity:1; } @keyframes __wp-base-styles-fade-in{ 0%{ opacity:0; } to{ opacity:1; } } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf.is-visible .block-editor-list-view-block-contents{ animation:__wp-base-styles-fade-in .08s linear 0s; animation-fill-mode:forwards; } } .block-editor-list-view-leaf .block-editor-block-icon{ flex:0 0 24px; margin-right:4px; } .block-editor-list-view-leaf .block-editor-list-view-block__contents-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{ padding:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell{ line-height:0; vertical-align:middle; width:36px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell>*{ opacity:0; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell:hover>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell.is-visible>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:focus-within>*,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell:hover>*{ opacity:1; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell,.block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell,.block-editor-list-view-leaf .block-editor-list-view-block__mover-cell .components-button.has-icon{ min-width:24px; padding:0; width:24px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell{ padding-right:4px; } .block-editor-list-view-leaf .block-editor-list-view-block__menu-cell .components-button.has-icon{ height:24px; } .block-editor-list-view-leaf .block-editor-list-view-block__mover-cell-alignment-wrapper{ align-items:center; display:flex; flex-direction:column; height:100%; } .block-editor-list-view-leaf .block-editor-block-mover-button{ height:24px; position:relative; width:36px; } .block-editor-list-view-leaf .block-editor-block-mover-button svg{ height:24px; position:relative; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button{ align-items:flex-end; margin-top:-6px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-up-button svg{ bottom:-4px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button{ align-items:flex-start; margin-bottom:-6px; } .block-editor-list-view-leaf .block-editor-block-mover-button.is-down-button svg{ top:-4px; } .block-editor-list-view-leaf .block-editor-block-mover-button:before{ height:16px; left:0; min-width:100%; right:0; } .block-editor-list-view-leaf .block-editor-inserter__toggle{ background:#1e1e1e; color:#fff; height:24px; margin:6px 6px 6px 1px; min-width:24px; } .block-editor-list-view-leaf .block-editor-inserter__toggle:active{ color:#fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__label-wrapper svg{ left:2px; position:relative; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__title{ flex:1; position:relative; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__title .components-truncate{ position:absolute; transform:translateY(-50%); width:100%; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor-wrapper{ max-width:min(110px, 40%); position:relative; width:100%; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__anchor{ position:absolute; right:0; transform:translateY(-50%); } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__anchor{ background:#0000004d; color:#fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__lock,.block-editor-list-view-leaf .block-editor-list-view-block-select-button__sticky{ line-height:0; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__images{ display:flex; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image{ background-size:cover; border-radius:1px; height:18px; width:18px; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:only-child){ box-shadow:0 0 0 2px #fff; } .block-editor-list-view-leaf .block-editor-list-view-block-select-button__image:not(:first-child){ margin-left:-6px; } .block-editor-list-view-leaf.is-selected .block-editor-list-view-block-select-button__image:not(:only-child){ box-shadow:0 0 0 2px var(--wp-admin-theme-color); } .block-editor-list-view-draggable-chip{ opacity:.8; } .block-editor-list-view-appender__cell .block-editor-list-view-appender__container,.block-editor-list-view-appender__cell .block-editor-list-view-block__contents-container,.block-editor-list-view-block__contents-cell .block-editor-list-view-appender__container,.block-editor-list-view-block__contents-cell .block-editor-list-view-block__contents-container{ display:flex; } .block-editor-list-view__expander{ cursor:pointer; height:24px; width:24px; } .block-editor-list-view-leaf[aria-level] .block-editor-list-view__expander{ margin-left:192px; } .block-editor-list-view-leaf[aria-level="1"] .block-editor-list-view__expander{ margin-left:0; } .block-editor-list-view-leaf[aria-level="2"] .block-editor-list-view__expander{ margin-left:24px; } .block-editor-list-view-leaf[aria-level="3"] .block-editor-list-view__expander{ margin-left:48px; } .block-editor-list-view-leaf[aria-level="4"] .block-editor-list-view__expander{ margin-left:72px; } .block-editor-list-view-leaf[aria-level="5"] .block-editor-list-view__expander{ margin-left:96px; } .block-editor-list-view-leaf[aria-level="6"] .block-editor-list-view__expander{ margin-left:120px; } .block-editor-list-view-leaf[aria-level="7"] .block-editor-list-view__expander{ margin-left:144px; } .block-editor-list-view-leaf[aria-level="8"] .block-editor-list-view__expander{ margin-left:168px; } .block-editor-list-view-leaf .block-editor-list-view__expander{ visibility:hidden; } .block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{ transform:rotate(90deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf[data-expanded=true] .block-editor-list-view__expander svg{ transition:transform .2s ease; } } .block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{ transform:rotate(0deg); visibility:visible; } @media not (prefers-reduced-motion){ .block-editor-list-view-leaf[data-expanded=false] .block-editor-list-view__expander svg{ transition:transform .2s ease; } } .block-editor-list-view-drop-indicator{ pointer-events:none; } .block-editor-list-view-drop-indicator .block-editor-list-view-drop-indicator__line{ background:var(--wp-admin-theme-color); border-radius:4px; height:4px; } .block-editor-list-view-drop-indicator--preview{ pointer-events:none; } .block-editor-list-view-drop-indicator--preview .components-popover__content{ overflow:hidden !important; } .block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line{ background:rgba(var(--wp-admin-theme-color--rgb), .04); border-radius:4px; height:32px; overflow:hidden; } .block-editor-list-view-drop-indicator--preview .block-editor-list-view-drop-indicator__line--darker{ background:rgba(var(--wp-admin-theme-color--rgb), .09); } .block-editor-list-view-placeholder{ height:32px; margin:0; padding:0; } .list-view-appender .block-editor-inserter__toggle{ background-color:#1e1e1e; color:#fff; height:24px; margin:8px 0 0 24px; padding:0; } .list-view-appender .block-editor-inserter__toggle.has-icon.is-next-40px-default-size{ min-width:24px; } .list-view-appender .block-editor-inserter__toggle:focus,.list-view-appender .block-editor-inserter__toggle:hover{ background:var(--wp-admin-theme-color); color:#fff; } .list-view-appender__description{ display:none; } .block-editor-media-placeholder__url-input-form{ min-width:260px; } @media (min-width:600px){ .block-editor-media-placeholder__url-input-form{ width:300px; } } .block-editor-media-placeholder__url-input-form input{ direction:ltr; } .modal-open .block-editor-media-replace-flow__options{ display:none; } .block-editor-media-replace-flow__indicator{ margin-left:4px; } .block-editor-media-replace-flow__media-upload-menu:not(:empty)+.block-editor-media-flow__url-input{ border-top:1px solid #1e1e1e; margin-top:8px; padding-bottom:8px; } .block-editor-media-flow__url-input{ margin-left:-8px; margin-right:-8px; padding:16px; } .block-editor-media-flow__url-input .block-editor-media-replace-flow__image-url-label{ display:block; margin-bottom:8px; top:16px; } .block-editor-media-flow__url-input .block-editor-link-control{ width:300px; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-url-input{ margin:0; padding:0; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-info,.block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item-title{ max-width:200px; white-space:nowrap; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__tools{ justify-content:flex-end; padding:16px var(--wp-admin-border-width-focus) var(--wp-admin-border-width-focus); } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-item.is-current{ padding:0; width:auto; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-input.block-editor-link-control__search-input input[type=text]{ margin:0; width:100%; } .block-editor-media-flow__url-input .block-editor-link-control .block-editor-link-control__search-actions{ padding:8px 0 0; } .block-editor-media-flow__error{ max-width:255px; padding:0 20px 20px; } .block-editor-media-flow__error .components-with-notices-ui{ max-width:255px; } .block-editor-media-flow__error .components-with-notices-ui .components-notice__content{ overflow:hidden; word-wrap:break-word; } .block-editor-media-flow__error .components-with-notices-ui .components-notice__dismiss{ position:absolute; right:10px; } .block-editor-multi-selection-inspector__card{ padding:16px; } .block-editor-multi-selection-inspector__card-title{ font-weight:500; } .block-editor-multi-selection-inspector__card .block-editor-block-icon{ height:24px; margin-left:-2px; padding:0 3px; width:36px; } .block-editor-responsive-block-control{ border-bottom:1px solid #ccc; margin-bottom:28px; padding-bottom:14px; } .block-editor-responsive-block-control:last-child{ border-bottom:0; padding-bottom:0; } .block-editor-responsive-block-control__title{ margin:0 0 .6em -3px; } .block-editor-responsive-block-control__label{ font-weight:600; margin-bottom:.6em; margin-left:-3px; } .block-editor-responsive-block-control__inner{ margin-left:-1px; } .block-editor-responsive-block-control__toggle{ margin-left:1px; } .block-editor-responsive-block-control .components-base-control__help{ border:0; clip-path:inset(50%); height:1px; margin:-1px; overflow:hidden; padding:0; position:absolute; width:1px; word-wrap:normal !important; } .components-popover.block-editor-rich-text__inline-format-toolbar{ z-index:99998; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-popover__content{ border-radius:2px; box-shadow:none; margin-bottom:8px; min-width:auto; outline:none; width:auto; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar{ border-radius:2px; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar-group{ background:none; } .components-popover.block-editor-rich-text__inline-format-toolbar .components-dropdown-menu__toggle,.components-popover.block-editor-rich-text__inline-format-toolbar .components-toolbar__control{ min-height:48px; min-width:48px; padding-left:12px; padding-right:12px; } .block-editor-rich-text__inline-format-toolbar-group .components-dropdown-menu__toggle{ justify-content:center; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon{ width:auto; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button.has-icon:after{ content:attr(aria-label); } .block-editor-skip-to-selected-block{ position:absolute; top:-9999em; } .block-editor-skip-to-selected-block:focus{ background:#f1f1f1; font-size:14px; font-weight:600; z-index:100000; } .block-editor-tabbed-sidebar{ background-color:#fff; display:flex; flex-direction:column; flex-grow:1; height:100%; overflow:hidden; } .block-editor-tabbed-sidebar__tablist-and-close-button{ border-bottom:1px solid #ddd; display:flex; justify-content:space-between; padding-right:8px; } .block-editor-tabbed-sidebar__close-button{ align-self:center; background:#fff; order:1; } .block-editor-tabbed-sidebar__tablist{ margin-bottom:-1px; } .block-editor-tabbed-sidebar__tabpanel{ display:flex; flex-direction:column; flex-grow:1; overflow-y:auto; scrollbar-gutter:auto; } .block-editor-tool-selector__help{ border-top:1px solid #ddd; color:#757575; margin:8px -8px -8px; min-width:280px; padding:16px; } .block-editor-tool-selector__menu .components-menu-item__info{ margin-left:36px; text-align:left; } .block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{ flex-grow:1; padding:1px; position:relative; } @media (min-width:600px){ .block-editor-block-list__block .block-editor-url-input,.block-editor-url-input,.components-popover .block-editor-url-input{ min-width:300px; width:auto; } } .block-editor-block-list__block .block-editor-url-input.is-full-width,.block-editor-block-list__block .block-editor-url-input.is-full-width__suggestions,.block-editor-url-input.is-full-width,.block-editor-url-input.is-full-width__suggestions,.components-popover .block-editor-url-input.is-full-width,.components-popover .block-editor-url-input.is-full-width__suggestions{ width:100%; } .block-editor-block-list__block .block-editor-url-input .components-spinner,.block-editor-url-input .components-spinner,.components-popover .block-editor-url-input .components-spinner{ margin:0; position:absolute; right:8px; top:calc(50% - 8px); } .block-editor-url-input__suggestions{ max-height:200px; overflow-y:auto; padding:4px 0; width:302px; } @media not (prefers-reduced-motion){ .block-editor-url-input__suggestions{ transition:all .15s ease-in-out; } } .block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{ display:none; } @media (min-width:600px){ .block-editor-url-input .components-spinner,.block-editor-url-input__suggestions{ display:grid; } } .block-editor-url-input__suggestion{ background:#fff; border:none; box-shadow:none; color:#757575; cursor:pointer; display:block; font-size:13px; height:auto; min-height:36px; text-align:left; width:100%; } .block-editor-url-input__suggestion:hover{ background:#ddd; } .block-editor-url-input__suggestion.is-selected,.block-editor-url-input__suggestion:focus{ background:var(--wp-admin-theme-color-darker-20); color:#fff; outline:none; } .components-toolbar-group>.block-editor-url-input__button,.components-toolbar>.block-editor-url-input__button{ position:inherit; } .block-editor-url-input__button .block-editor-url-input__back{ margin-right:4px; overflow:visible; } .block-editor-url-input__button .block-editor-url-input__back:after{ background:#ddd; content:""; display:block; height:24px; position:absolute; right:-1px; width:1px; } .block-editor-url-input__button-modal{ background:#fff; border:1px solid #ddd; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; } .block-editor-url-input__button-modal-line{ align-items:flex-start; display:flex; flex-direction:row; flex-grow:1; flex-shrink:1; min-width:0; } .block-editor-url-popover__additional-controls{ border-top:1px solid #1e1e1e; padding:8px; } .block-editor-url-popover__input-container{ padding:8px; } .block-editor-url-popover__row{ align-items:center; display:flex; gap:4px; } .block-editor-url-popover__row>:not(.block-editor-url-popover__settings-toggle){ flex-grow:1; gap:8px; } .block-editor-url-popover__additional-controls .components-button.has-icon{ height:auto; padding-left:8px; padding-right:8px; text-align:left; } .block-editor-url-popover__additional-controls .components-button.has-icon>svg{ margin-right:8px; } .block-editor-url-popover__settings-toggle{ flex-shrink:0; } .block-editor-url-popover__settings-toggle[aria-expanded=true] .dashicon{ transform:rotate(180deg); } .block-editor-url-popover__settings{ border-top:1px solid #1e1e1e; display:block; padding:16px; } .block-editor-url-popover__link-editor,.block-editor-url-popover__link-viewer{ display:flex; } .block-editor-url-popover__link-viewer-url{ align-items:center; display:flex; flex-grow:1; flex-shrink:1; margin-right:8px; max-width:350px; min-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } .block-editor-url-popover__link-viewer-url.has-invalid-link{ color:#cc1818; } .block-editor-url-popover__expand-on-click{ align-items:center; display:flex; min-width:350px; white-space:nowrap; } .block-editor-url-popover__expand-on-click .text{ flex-grow:1; } .block-editor-url-popover__expand-on-click .text p{ line-height:16px; margin:0; } .block-editor-url-popover__expand-on-click .text p.description{ color:#757575; font-size:12px; } .block-editor-hooks__block-hooks .components-toggle-control .components-h-stack .components-h-stack{ flex-direction:row; } .block-editor-hooks__block-hooks .block-editor-hooks__block-hooks-helptext{ color:#757575; font-size:12px; margin-bottom:16px; } div.block-editor-bindings__panel{ grid-template-columns:repeat(auto-fit, minmax(100%, 1fr)); } div.block-editor-bindings__panel button:hover .block-editor-bindings__item span{ color:inherit; } .border-block-support-panel .single-column{ grid-column:span 1; } .color-block-support-panel .block-editor-contrast-checker{ grid-column:span 2; margin-top:16px; } .color-block-support-panel .block-editor-contrast-checker .components-notice__content{ margin-right:0; } .color-block-support-panel.color-block-support-panel .color-block-support-panel__inner-wrapper{ row-gap:0; } .color-block-support-panel .block-editor-tools-panel-color-gradient-settings__item.first{ margin-top:0; } .dimensions-block-support-panel .single-column{ grid-column:span 1; } .block-editor-hooks__layout-constrained .components-base-control{ margin-bottom:0; } .block-editor-hooks__layout-constrained-helptext{ color:#757575; font-size:12px; margin-bottom:0; } .block-editor-hooks__flex-layout-justification-controls,.block-editor-hooks__flex-layout-orientation-controls{ margin-bottom:12px; } .block-editor-hooks__flex-layout-justification-controls legend,.block-editor-hooks__flex-layout-orientation-controls legend{ margin-bottom:8px; } .block-editor__spacing-visualizer{ border-color:var(--wp-admin-theme-color); border-style:solid; bottom:0; box-sizing:border-box; left:0; opacity:.5; pointer-events:none; position:absolute; right:0; top:0; } .typography-block-support-panel .single-column{ grid-column:span 1; } .block-editor-block-toolbar{ display:flex; flex-grow:1; overflow-x:auto; overflow-y:hidden; position:relative; width:100%; } @media not (prefers-reduced-motion){ .block-editor-block-toolbar{ transition:border-color .1s linear,box-shadow .1s linear; } } @media (min-width:600px){ .block-editor-block-toolbar{ overflow:inherit; } } .block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group{ background:none; border:0; border-right:1px solid #ddd; margin-bottom:-1px; margin-top:-1px; } .block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button:before{ background:color-mix(in srgb, var(--wp-block-synced-color) 10%, #0000); border-radius:2px; } .block-editor-block-toolbar.is-connected .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-connected .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors,.block-editor-block-toolbar.is-synced .block-editor-block-switcher .components-button .block-editor-block-icon,.block-editor-block-toolbar.is-synced .components-toolbar-button.block-editor-block-switcher__no-switcher-icon:disabled .block-editor-block-icon.has-colors{ color:var(--wp-block-synced-color); } .block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2),.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar,.block-editor-block-toolbar:has(>:last-child:empty)>:nth-last-child(2) .components-toolbar-group,.block-editor-block-toolbar>:last-child,.block-editor-block-toolbar>:last-child .components-toolbar,.block-editor-block-toolbar>:last-child .components-toolbar-group{ border-right:none; } .block-editor-block-toolbar .components-toolbar-group:empty{ display:none; } .block-editor-block-contextual-toolbar{ background-color:#fff; display:block; flex-shrink:3; position:sticky; top:0; width:100%; z-index:31; } .block-editor-block-contextual-toolbar.components-accessible-toolbar{ border:none; border-radius:0; } .block-editor-block-contextual-toolbar.is-unstyled{ box-shadow:0 1px 0 0 rgba(0,0,0,.133); } .block-editor-block-contextual-toolbar .block-editor-block-toolbar{ overflow:auto; overflow-y:hidden; scrollbar-color:#e0e0e0 #0000; scrollbar-gutter:stable both-edges; scrollbar-gutter:auto; scrollbar-width:thin; will-change:transform; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar{ height:12px; width:12px; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-track{ background-color:initial; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar::-webkit-scrollbar-thumb{ background-clip:padding-box; background-color:#e0e0e0; border:3px solid #0000; border-radius:8px; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus::-webkit-scrollbar-thumb,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover::-webkit-scrollbar-thumb{ background-color:#949494; } .block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:focus-within,.block-editor-block-contextual-toolbar .block-editor-block-toolbar:hover{ scrollbar-color:#949494 #0000; } @media (hover:none){ .block-editor-block-contextual-toolbar .block-editor-block-toolbar{ scrollbar-color:#949494 #0000; } } .block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar-group:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child .components-toolbar:after,.block-editor-block-contextual-toolbar .block-editor-block-toolbar>:last-child:after{ display:none; } .block-editor-block-contextual-toolbar>.block-editor-block-toolbar{ flex-grow:0; width:auto; } .block-editor-block-contextual-toolbar .block-editor-block-parent-selector{ margin-bottom:-1px; margin-top:-1px; position:relative; } .block-editor-block-contextual-toolbar .block-editor-block-parent-selector:after{ align-items:center; background-color:#1e1e1e; border-radius:100%; content:""; display:inline-flex; height:2px; position:absolute; right:0; top:15px; width:2px; } .block-editor-block-toolbar__block-controls .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.block-editor-block-toolbar__block-controls .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ margin:0 !important; width:24px !important; } .block-editor-block-toolbar__block-controls .components-toolbar-group{ padding:0; } .block-editor-block-toolbar .components-toolbar,.block-editor-block-toolbar .components-toolbar-group,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar,.block-editor-rich-text__inline-format-toolbar-group .components-toolbar-group{ display:flex; flex-wrap:nowrap; } .block-editor-block-toolbar__slot{ display:inline-flex; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon{ width:auto; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon svg{ display:none; } .show-icon-labels .block-editor-block-toolbar .components-button.has-icon:after{ content:attr(aria-label); font-size:12px; } .show-icon-labels .components-accessible-toolbar .components-toolbar-group>div:first-child:last-child>.components-button.has-icon{ padding-left:6px; padding-right:6px; } .show-icon-labels .block-editor-block-switcher .components-dropdown-menu__toggle .block-editor-block-icon,.show-icon-labels .block-editor-block-switcher__no-switcher-icon .block-editor-block-icon{ height:0 !important; min-width:0 !important; width:0 !important; } .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button{ border-bottom-right-radius:0; border-top-right-radius:0; padding-left:12px; padding-right:12px; text-wrap:nowrap; } .show-icon-labels .block-editor-block-parent-selector .block-editor-block-parent-selector__button .block-editor-block-icon{ width:0; } .show-icon-labels .block-editor-block-mover .block-editor-block-mover__move-button-container{ position:relative; width:auto; } @media (min-width:600px){ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{ background:#e0e0e0; content:""; height:1px; left:50%; margin-top:-.5px; position:absolute; top:50%; transform:translate(-50%); width:100%; } } @media (min-width:782px){ .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover__move-button-container:before{ background:#1e1e1e; } } .show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover-button,.show-icon-labels .block-editor-block-mover.is-horizontal .block-editor-block-mover__move-button-container{ padding-left:6px; padding-right:6px; } .show-icon-labels .block-editor-block-mover:not(.is-horizontal) .block-editor-block-mover-button{ padding-left:8px; padding-right:8px; } .show-icon-labels .block-editor-block-toolbar__block-controls .block-editor-block-mover{ border-left:1px solid #ddd; margin-left:6px; margin-right:-6px; white-space:nowrap; } .show-icon-labels .block-editor-block-mover .block-editor-block-mover__drag-handle.has-icon{ padding-left:12px; padding-right:12px; } .show-icon-labels .block-editor-block-contextual-toolbar .block-editor-block-mover.is-horizontal .block-editor-block-mover-button.block-editor-block-mover-button{ width:auto; } .show-icon-labels .components-toolbar,.show-icon-labels .components-toolbar-group{ flex-shrink:1; } .show-icon-labels .block-editor-rich-text__inline-format-toolbar-group .components-button+.components-button{ margin-left:6px; } .block-editor-block-toolbar-change-design-content-wrapper{ padding:12px; width:320px; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr 1fr; grid-gap:12px; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .block-editor-block-toolbar-change-design-content-wrapper .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ min-height:100px; } .block-editor-inserter{ background:none; border:none; display:inline-block; font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif; font-size:13px; line-height:0; padding:0; } @media (min-width:782px){ .block-editor-inserter{ position:relative; } } .block-editor-inserter__main-area{ gap:16px; height:100%; position:relative; } .block-editor-inserter__main-area.show-as-tabs{ gap:0; } @media (min-width:782px){ .block-editor-inserter__main-area .block-editor-tabbed-sidebar{ width:350px; } } .block-editor-inserter__popover.is-quick .components-popover__content{ border:none; box-shadow:0 1px 1px #00000008,0 1px 2px #00000005,0 3px 3px #00000005,0 4px 4px #00000003; outline:none; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>*{ border-left:1px solid #ccc; border-right:1px solid #ccc; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:first-child{ border-radius:4px 4px 0 0; border-top:1px solid #ccc; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>:last-child{ border-bottom:1px solid #ccc; border-radius:0 0 4px 4px; } .block-editor-inserter__popover.is-quick .components-popover__content .block-editor-inserter__quick-inserter>.components-button{ border:1px solid #1e1e1e; } .block-editor-inserter__popover .block-editor-inserter__menu{ margin:-12px; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__tablist{ top:60px; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__main-area{ height:auto; overflow:visible; } .block-editor-inserter__popover .block-editor-inserter__menu .block-editor-inserter__preview-container{ display:none; } .block-editor-inserter__toggle.components-button{ align-items:center; border:none; cursor:pointer; display:inline-flex; outline:none; padding:0; } @media not (prefers-reduced-motion){ .block-editor-inserter__toggle.components-button{ transition:color .2s ease; } } .block-editor-inserter__menu{ height:100%; overflow:visible; position:relative; } @media (min-width:782px){ .block-editor-inserter__menu.show-panel{ width:630px; } } .block-editor-inserter__inline-elements{ margin-top:-1px; } .block-editor-inserter__menu.is-bottom:after{ border-bottom-color:#fff; } .components-popover.block-editor-inserter__popover{ z-index:99999; } .block-editor-inserter__search{ padding:16px 16px 0; } .block-editor-inserter__no-tab-container{ flex-grow:1; overflow-y:auto; position:relative; } .block-editor-inserter__panel-header{ align-items:center; display:inline-flex; padding:16px 16px 0; position:relative; } .block-editor-inserter__panel-content{ padding:16px; } .block-editor-inserter__panel-title,.block-editor-inserter__panel-title button{ color:#757575; font-size:11px; font-weight:500; margin:0 12px 0 0; text-transform:uppercase; } .block-editor-inserter__panel-dropdown select.components-select-control__input.components-select-control__input.components-select-control__input{ height:36px; line-height:36px; } .block-editor-inserter__panel-dropdown select{ border:none; } .block-editor-inserter__reusable-blocks-panel{ position:relative; text-align:right; } .block-editor-inserter__no-results,.block-editor-inserter__patterns-loading{ padding:32px; text-align:center; } .block-editor-inserter__child-blocks{ padding:0 16px; } .block-editor-inserter__parent-block-header{ align-items:center; display:flex; } .block-editor-inserter__parent-block-header h2{ font-size:13px; } .block-editor-inserter__parent-block-header .block-editor-block-icon{ margin-right:8px; } .block-editor-inserter__preview-container__popover{ top:16px !important; } .block-editor-inserter__preview-container{ display:none; max-height:calc(100% - 32px); overflow-y:hidden; padding:16px; width:280px; } @media (min-width:782px){ .block-editor-inserter__preview-container{ display:block; } } .block-editor-inserter__preview-container .block-editor-inserter__media-list__list-item{ height:100%; } .block-editor-inserter__preview-container .block-editor-block-card{ padding-bottom:4px; padding-left:0; padding-right:0; } .block-editor-inserter__insertable-blocks-at-selection{ border-bottom:1px solid #e0e0e0; } .block-editor-inserter__block-patterns-tabs-container,.block-editor-inserter__media-tabs-container{ display:flex; flex-direction:column; flex-grow:1; justify-content:space-between; padding:16px; } .block-editor-inserter__category-tablist{ margin-bottom:8px; } .block-editor-inserter__category-panel{ display:flex; flex-direction:column; outline:1px solid #0000; padding:0 16px; } @media (min-width:782px){ .block-editor-inserter__category-panel{ background:#f0f0f0; border-left:1px solid #e0e0e0; border-top:1px solid #e0e0e0; height:calc(100% + 1px); left:350px; padding:0; position:absolute; top:-1px; width:280px; } .block-editor-inserter__category-panel .block-editor-block-patterns-list,.block-editor-inserter__category-panel .block-editor-inserter__media-list{ padding:0 24px 16px; } } .block-editor-inserter__patterns-category-panel-header{ padding:8px 0; } @media (min-width:782px){ .block-editor-inserter__patterns-category-panel-header{ padding:8px 24px; } } .block-editor-inserter__patterns-category-no-results{ margin-top:24px; } .block-editor-inserter__patterns-filter-help{ border-top:1px solid #ddd; color:#757575; min-width:280px; padding:16px; } .block-editor-block-patterns-list,.block-editor-inserter__media-list{ flex-grow:1; height:100%; overflow-y:auto; } .block-editor-inserter__preview-content{ align-items:center; background:#f0f0f0; display:grid; flex-grow:1; } .block-editor-inserter__preview-content-missing{ align-items:center; background:#f0f0f0; border-radius:2px; color:#757575; display:flex; flex:1; justify-content:center; min-height:144px; } .block-editor-inserter__tips{ border-top:1px solid #ddd; flex-shrink:0; padding:16px; position:relative; } .block-editor-inserter__quick-inserter{ max-width:100%; width:100%; } @media (min-width:782px){ .block-editor-inserter__quick-inserter{ width:350px; } } .block-editor-inserter__quick-inserter-results .block-editor-inserter__panel-header{ float:left; height:0; padding:0; } .block-editor-inserter__quick-inserter.has-expand .block-editor-inserter__panel-content,.block-editor-inserter__quick-inserter.has-search .block-editor-inserter__panel-content{ padding:16px; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list{ display:grid; grid-template-columns:1fr 1fr; grid-gap:8px; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ margin-bottom:0; } .block-editor-inserter__quick-inserter-patterns .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ min-height:100px; } .block-editor-inserter__quick-inserter-separator{ border-top:1px solid #ddd; } .block-editor-inserter__popover.is-quick>.components-popover__content{ padding:0; } .block-editor-inserter__quick-inserter-expand.components-button{ background:#1e1e1e; border-radius:0; color:#fff; display:block; width:100%; } .block-editor-inserter__quick-inserter-expand.components-button:hover{ color:#fff; } .block-editor-inserter__quick-inserter-expand.components-button:active{ color:#ccc; } .block-editor-inserter__quick-inserter-expand.components-button.components-button:focus:not(:disabled){ background:var(--wp-admin-theme-color); border-color:var(--wp-admin-theme-color); box-shadow:none; } .block-editor-block-patterns-explorer__sidebar{ bottom:0; left:0; overflow-x:visible; overflow-y:scroll; padding:24px 32px 32px; position:absolute; top:72px; width:280px; } .block-editor-block-patterns-explorer__sidebar__categories-list__item{ display:block; height:48px; text-align:left; width:100%; } .block-editor-block-patterns-explorer__search{ margin-bottom:32px; } .block-editor-block-patterns-explorer__search-results-count{ padding-bottom:32px; } .block-editor-block-patterns-explorer__list{ margin-left:280px; padding:24px 0 32px; } .block-editor-block-patterns-explorer__list .block-editor-patterns__sync-status-filter .components-input-control__container{ width:380px; } .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ display:grid; grid-gap:32px; grid-template-columns:repeat(1, 1fr); margin-bottom:16px; } @media (min-width:1080px){ .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ grid-template-columns:repeat(2, 1fr); } } @media (min-width:1440px){ .block-editor-block-patterns-explorer .block-editor-block-patterns-list{ grid-template-columns:repeat(3, 1fr); } } .block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-block-patterns-list__list-item{ min-height:240px; } .block-editor-block-patterns-explorer .block-editor-block-patterns-list .block-editor-inserter__media-list__list-item{ height:inherit; max-height:800px; min-height:100px; } .components-heading.block-editor-inserter__patterns-category-panel-title{ font-weight:500; } .block-editor-inserter__media-library-button.components-button,.block-editor-inserter__patterns-explore-button.components-button{ justify-content:center; margin-top:16px; padding:16px; width:100%; } .block-editor-inserter__media-panel{ display:flex; flex-direction:column; min-height:100%; padding:0 16px; } @media (min-width:782px){ .block-editor-inserter__media-panel{ padding:0; } } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-spinner{ align-items:center; display:flex; flex:1; height:100%; justify-content:center; } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{ margin-bottom:24px; } @media (min-width:782px){ .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search{ margin-bottom:0; padding:16px 24px; } .block-editor-inserter__media-panel .block-editor-inserter__media-panel-search:not(:focus-within){ --wp-components-color-background:#fff; } } .block-editor-inserter__media-list__list-item{ cursor:pointer; margin-bottom:24px; position:relative; } .block-editor-inserter__media-list__list-item.is-placeholder{ min-height:100px; } .block-editor-inserter__media-list__list-item[draggable=true] .block-editor-inserter__media-list__list-item{ cursor:grab; } .block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview>*{ outline-color:#0000004d; } .block-editor-inserter__media-list__list-item.is-hovered .block-editor-inserter__media-list__item-preview-options>button{ display:block; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options{ position:absolute; right:8px; top:8px; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button{ background:#fff; display:none; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button.is-opened,.block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:focus{ display:block; } .block-editor-inserter__media-list__list-item .block-editor-inserter__media-list__item-preview-options>button:hover{ box-shadow:inset 0 0 0 2px #fff, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); outline:2px solid #0000; } .block-editor-inserter__media-list__item{ height:100%; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview{ align-items:center; border-radius:2px; display:flex; overflow:hidden; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview>*{ margin:0 auto; max-width:100%; outline:1px solid #0000001a; outline-offset:-1px; } .block-editor-inserter__media-list__item .block-editor-inserter__media-list__item-preview .block-editor-inserter__media-list__item-preview-spinner{ align-items:center; background:#ffffffb3; display:flex; height:100%; justify-content:center; pointer-events:none; position:absolute; width:100%; } .block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{ outline-color:var(--wp-admin-theme-color); outline-offset:calc(var(--wp-admin-border-width-focus)*-1); outline-width:var(--wp-admin-border-width-focus); } @media not (prefers-reduced-motion){ .block-editor-inserter__media-list__item:focus .block-editor-inserter__media-list__item-preview>*{ transition:outline .1s linear; } } .block-editor-inserter__media-list__item-preview-options__popover .components-menu-item__button .components-menu-item__item{ min-width:auto; } .block-editor-inserter__mobile-tab-navigation{ height:100%; padding:16px; } .block-editor-inserter__mobile-tab-navigation>*{ height:100%; } @media (min-width:600px){ .block-editor-inserter-media-tab-media-preview-inserter-external-image-modal{ max-width:480px; } } .block-editor-inserter-media-tab-media-preview-inserter-external-image-modal p{ margin:0; } .block-editor-inserter__hint{ margin:16px 16px 0; } .block-editor-patterns__sync-status-filter .components-input-control__container select.components-select-control__input{ height:40px; } .block-editor-inserter__pattern-panel-placeholder{ display:none; } .block-editor-inserter__menu.is-zoom-out{ display:flex; } @media (min-width:782px){ .block-editor-inserter__menu.is-zoom-out.show-panel:after{ content:""; display:block; height:100%; width:300px; } } @media (max-width:959px){ .show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-block-patterns-explorer .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{ flex-direction:column; } } .show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-next,.show-icon-labels .block-editor-inserter__category-panel .block-editor-patterns__grid-pagination .block-editor-patterns__grid-pagination-previous{ flex-direction:column; } .block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{ display:none; padding:0 24px 16px; } @media (min-width:480px){ .block-editor-tabbed-sidebar__tabpanel .block-editor-inserter__help-text{ display:block; } } .spacing-sizes-control .spacing-sizes-control__custom-value-input,.spacing-sizes-control .spacing-sizes-control__label{ margin-bottom:0; } .spacing-sizes-control .spacing-sizes-control__custom-value-range,.spacing-sizes-control .spacing-sizes-control__range-control{ flex:1; margin-bottom:0; } .spacing-sizes-control__header{ height:16px; margin-bottom:12px; } .spacing-sizes-control__dropdown{ height:24px; } .spacing-sizes-control__custom-select-control,.spacing-sizes-control__custom-value-input{ flex:1; } .spacing-sizes-control__custom-toggle,.spacing-sizes-control__icon{ flex:0 0 auto; } .spacing-sizes-control__icon{ margin-left:-4px; } body.admin-color-light{ --wp-admin-theme-color:#0085ba; --wp-admin-theme-color--rgb:0, 133, 186; --wp-admin-theme-color-darker-10:#0073a1; --wp-admin-theme-color-darker-10--rgb:0, 115, 161; --wp-admin-theme-color-darker-20:#006187; --wp-admin-theme-color-darker-20--rgb:0, 97, 135; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-light{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-modern{ --wp-admin-theme-color:#3858e9; --wp-admin-theme-color--rgb:56, 88, 233; --wp-admin-theme-color-darker-10:#2145e6; --wp-admin-theme-color-darker-10--rgb:33, 69, 230; --wp-admin-theme-color-darker-20:#183ad6; --wp-admin-theme-color-darker-20--rgb:24, 58, 214; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-modern{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-blue{ --wp-admin-theme-color:#096484; --wp-admin-theme-color--rgb:9, 100, 132; --wp-admin-theme-color-darker-10:#07526c; --wp-admin-theme-color-darker-10--rgb:7, 82, 108; --wp-admin-theme-color-darker-20:#064054; --wp-admin-theme-color-darker-20--rgb:6, 64, 84; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-blue{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-coffee{ --wp-admin-theme-color:#46403c; --wp-admin-theme-color--rgb:70, 64, 60; --wp-admin-theme-color-darker-10:#383330; --wp-admin-theme-color-darker-10--rgb:56, 51, 48; --wp-admin-theme-color-darker-20:#2b2724; --wp-admin-theme-color-darker-20--rgb:43, 39, 36; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-coffee{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ectoplasm{ --wp-admin-theme-color:#523f6d; --wp-admin-theme-color--rgb:82, 63, 109; --wp-admin-theme-color-darker-10:#46365d; --wp-admin-theme-color-darker-10--rgb:70, 54, 93; --wp-admin-theme-color-darker-20:#3a2c4d; --wp-admin-theme-color-darker-20--rgb:58, 44, 77; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ectoplasm{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-midnight{ --wp-admin-theme-color:#e14d43; --wp-admin-theme-color--rgb:225, 77, 67; --wp-admin-theme-color-darker-10:#dd382d; --wp-admin-theme-color-darker-10--rgb:221, 56, 45; --wp-admin-theme-color-darker-20:#d02c21; --wp-admin-theme-color-darker-20--rgb:208, 44, 33; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-midnight{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-ocean{ --wp-admin-theme-color:#627c83; --wp-admin-theme-color--rgb:98, 124, 131; --wp-admin-theme-color-darker-10:#576e74; --wp-admin-theme-color-darker-10--rgb:87, 110, 116; --wp-admin-theme-color-darker-20:#4c6066; --wp-admin-theme-color-darker-20--rgb:76, 96, 102; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-ocean{ --wp-admin-border-width-focus:1.5px; } } body.admin-color-sunrise{ --wp-admin-theme-color:#dd823b; --wp-admin-theme-color--rgb:221, 130, 59; --wp-admin-theme-color-darker-10:#d97426; --wp-admin-theme-color-darker-10--rgb:217, 116, 38; --wp-admin-theme-color-darker-20:#c36922; --wp-admin-theme-color-darker-20--rgb:195, 105, 34; --wp-admin-border-width-focus:2px; } @media (min-resolution:192dpi){ body.admin-color-sunrise{ --wp-admin-border-width-focus:1.5px; } }html, body { padding: 0; margin: 0; } body { font-family: sans-serif; } /* Text meant only for screen readers */ .screen-reader-text { border: 0; clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; } /* Dashicons */ .dashicons { display: inline-block; width: 20px; height: 20px; background-color: transparent; background-repeat: no-repeat; background-size: 20px; background-position: center; transition: background .1s ease-in; position: relative; top: 5px; } .dashicons-no { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M15.55%2013.7l-2.19%202.06-3.42-3.65-3.64%203.43-2.06-2.18%203.64-3.43-3.42-3.64%202.18-2.06%203.43%203.64%203.64-3.42%202.05%202.18-3.64%203.43z%27%20fill%3D%27%23fff%27%2F%3E%3C%2Fsvg%3E"); } .dashicons-admin-comments { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M5%202h9q.82%200%201.41.59T16%204v7q0%20.82-.59%201.41T14%2013h-2l-5%205v-5H5q-.82%200-1.41-.59T3%2011V4q0-.82.59-1.41T5%202z%27%20fill%3D%27%2382878c%27%2F%3E%3C%2Fsvg%3E"); } .wp-embed-comments a:hover .dashicons-admin-comments { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M5%202h9q.82%200%201.41.59T16%204v7q0%20.82-.59%201.41T14%2013h-2l-5%205v-5H5q-.82%200-1.41-.59T3%2011V4q0-.82.59-1.41T5%202z%27%20fill%3D%27%230073aa%27%2F%3E%3C%2Fsvg%3E"); } .dashicons-share { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.5%2012q1.24%200%202.12.88T17.5%2015t-.88%202.12-2.12.88-2.12-.88T11.5%2015q0-.34.09-.69l-4.38-2.3Q6.32%2013%205%2013q-1.24%200-2.12-.88T2%2010t.88-2.12T5%207q1.3%200%202.21.99l4.38-2.3q-.09-.35-.09-.69%200-1.24.88-2.12T14.5%202t2.12.88T17.5%205t-.88%202.12T14.5%208q-1.3%200-2.21-.99l-4.38%202.3Q8%209.66%208%2010t-.09.69l4.38%202.3q.89-.99%202.21-.99z%27%20fill%3D%27%2382878c%27%2F%3E%3C%2Fsvg%3E"); display: none; } .js .dashicons-share { display: inline-block; } .wp-embed-share-dialog-open:hover .dashicons-share { background-image: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.5%2012q1.24%200%202.12.88T17.5%2015t-.88%202.12-2.12.88-2.12-.88T11.5%2015q0-.34.09-.69l-4.38-2.3Q6.32%2013%205%2013q-1.24%200-2.12-.88T2%2010t.88-2.12T5%207q1.3%200%202.21.99l4.38-2.3q-.09-.35-.09-.69%200-1.24.88-2.12T14.5%202t2.12.88T17.5%205t-.88%202.12T14.5%208q-1.3%200-2.21-.99l-4.38%202.3Q8%209.66%208%2010t-.09.69l4.38%202.3q.89-.99%202.21-.99z%27%20fill%3D%27%230073aa%27%2F%3E%3C%2Fsvg%3E"); } .wp-embed { padding: 25px; font-size: 14px; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; line-height: 1.5; color: #8c8f94; background: #fff; border: 1px solid #dcdcde; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); /* Clearfix */ overflow: auto; zoom: 1; } .wp-embed a { color: #8c8f94; text-decoration: none; } .wp-embed a:hover { text-decoration: underline; } .wp-embed-featured-image { margin-bottom: 20px; } .wp-embed-featured-image img { width: 100%; height: auto; border: none; } .wp-embed-featured-image.square { float: left; max-width: 160px; margin-right: 20px; } .wp-embed p { margin: 0; } p.wp-embed-heading { margin: 0 0 15px; font-weight: 600; font-size: 22px; line-height: 1.3; } .wp-embed-heading a { color: #2c3338; } .wp-embed .wp-embed-more { color: #c3c4c7; } .wp-embed-footer { display: table; width: 100%; margin-top: 30px; } .wp-embed-site-icon { position: absolute; top: 50%; left: 0; transform: translateY(-50%); height: 25px; width: 25px; border: 0; } .wp-embed-site-title { font-weight: 600; line-height: 1.78571428; } .wp-embed-site-title a { position: relative; display: inline-block; padding-left: 35px; } .wp-embed-site-title, .wp-embed-meta { display: table-cell; } .wp-embed-meta { text-align: right; white-space: nowrap; vertical-align: middle; } .wp-embed-comments, .wp-embed-share { display: inline; } .wp-embed-meta a:hover { text-decoration: none; color: #2271b1; } .wp-embed-comments a { line-height: 1.78571428; display: inline-block; } .wp-embed-comments + .wp-embed-share { margin-left: 10px; } .wp-embed-share-dialog { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #1d2327; background-color: rgba(0, 0, 0, 0.9); color: #fff; opacity: 1; transition: opacity .25s ease-in-out; } .wp-embed-share-dialog.hidden { opacity: 0; visibility: hidden; } .wp-embed-share-dialog-open, .wp-embed-share-dialog-close { margin: -8px 0 0; padding: 0; background: transparent; border: none; cursor: pointer; outline: none; } .wp-embed-share-dialog-open .dashicons, .wp-embed-share-dialog-close .dashicons { padding: 4px; } .wp-embed-share-dialog-open .dashicons { top: 8px; } .wp-embed-share-dialog-open:focus .dashicons, .wp-embed-share-dialog-close:focus .dashicons { box-shadow: 0 0 0 2px #2271b1; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; border-radius: 100%; } .wp-embed-share-dialog-close { position: absolute; top: 20px; right: 20px; font-size: 22px; } .wp-embed-share-dialog-close:hover { text-decoration: none; } .wp-embed-share-dialog-close .dashicons { height: 24px; width: 24px; background-size: 24px; } .wp-embed-share-dialog-content { height: 100%; transform-style: preserve-3d; overflow: hidden; } .wp-embed-share-dialog-text { margin-top: 25px; padding: 20px; } .wp-embed-share-tabs { margin: 0 0 20px; padding: 0; list-style: none; } .wp-embed-share-tab-button { display: inline-block; } .wp-embed-share-tab-button button { margin: 0; padding: 0; border: none; background: transparent; font-size: 16px; line-height: 1.3; color: #a7aaad; cursor: pointer; transition: color .1s ease-in; } .wp-embed-share-tab-button [aria-selected="true"] { color: #fff; } .wp-embed-share-tab-button button:hover { color: #fff; } .wp-embed-share-tab-button + .wp-embed-share-tab-button { margin: 0 0 0 10px; padding: 0 0 0 11px; border-left: 1px solid #a7aaad; } .wp-embed-share-tab[aria-hidden="true"] { display: none; } p.wp-embed-share-description { margin: 0; font-size: 14px; line-height: 1; font-style: italic; color: #a7aaad; } .wp-embed-share-input { box-sizing: border-box; width: 100%; border: none; height: 28px; margin: 0 0 10px; padding: 0 5px; font-size: 14px; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; line-height: 1.5; resize: none; cursor: text; } textarea.wp-embed-share-input { height: 72px; } html[dir="rtl"] .wp-embed-featured-image.square { float: right; margin-right: 0; margin-left: 20px; } html[dir="rtl"] .wp-embed-site-title a { padding-left: 0; padding-right: 35px; } html[dir="rtl"] .wp-embed-site-icon { margin-right: 0; margin-left: 10px; left: auto; right: 0; } html[dir="rtl"] .wp-embed-meta { text-align: left; } html[dir="rtl"] .wp-embed-share { margin-left: 0; margin-right: 10px; } html[dir="rtl"] .wp-embed-share-dialog-close { right: auto; left: 20px; } html[dir="rtl"] .wp-embed-share-tab-button + .wp-embed-share-tab-button { margin: 0 10px 0 0; padding: 0 11px 0 0; border-left: none; border-right: 1px solid #a7aaad; } /*! This file is auto-generated */ .wp-core-ui .button,.wp-core-ui .button-primary,.wp-core-ui .button-secondary{display:inline-block;text-decoration:none;font-size:13px;line-height:2.15384615;min-height:30px;margin:0;padding:0 10px;cursor:pointer;border-width:1px;border-style:solid;-webkit-appearance:none;border-radius:3px;white-space:nowrap;box-sizing:border-box}.wp-core-ui button::-moz-focus-inner,.wp-core-ui input[type=button]::-moz-focus-inner,.wp-core-ui input[type=reset]::-moz-focus-inner,.wp-core-ui input[type=submit]::-moz-focus-inner{border-width:0;border-style:none;padding:0}.wp-core-ui .button-group.button-large .button,.wp-core-ui .button.button-large{min-height:32px;line-height:2.30769231;padding:0 12px}.wp-core-ui .button-group.button-small .button,.wp-core-ui .button.button-small{min-height:26px;line-height:2.18181818;padding:0 8px;font-size:11px}.wp-core-ui .button-group.button-hero .button,.wp-core-ui .button.button-hero{font-size:14px;min-height:46px;line-height:3.14285714;padding:0 36px}.wp-core-ui .button.hidden{display:none}.wp-core-ui input[type=reset],.wp-core-ui input[type=reset]:active,.wp-core-ui input[type=reset]:focus,.wp-core-ui input[type=reset]:hover{background:0 0;border:none;box-shadow:none;padding:0 2px 1px;width:auto}.wp-core-ui .button,.wp-core-ui .button-secondary{color:#2271b1;border-color:#2271b1;background:#f6f7f7;vertical-align:top}.wp-core-ui p .button{vertical-align:baseline}.wp-core-ui .button-secondary:hover,.wp-core-ui .button.hover,.wp-core-ui .button:hover{background:#f0f0f1;border-color:#0a4b78;color:#0a4b78}.wp-core-ui .button-secondary:focus,.wp-core-ui .button.focus,.wp-core-ui .button:focus{background:#f6f7f7;border-color:#3582c4;color:#0a4b78;box-shadow:0 0 0 1px #3582c4;outline:2px solid transparent;outline-offset:0}.wp-core-ui .button-secondary:active,.wp-core-ui .button:active{background:#f6f7f7;border-color:#8c8f94;box-shadow:none}.wp-core-ui .button.active,.wp-core-ui .button.active:hover{background-color:#dcdcde;color:#135e96;border-color:#0a4b78;box-shadow:inset 0 2px 5px -3px #0a4b78}.wp-core-ui .button.active:focus{border-color:#3582c4;box-shadow:inset 0 2px 5px -3px #0a4b78,0 0 0 1px #3582c4}.wp-core-ui .button-disabled,.wp-core-ui .button-secondary.disabled,.wp-core-ui .button-secondary:disabled,.wp-core-ui .button-secondary[disabled],.wp-core-ui .button.disabled,.wp-core-ui .button:disabled,.wp-core-ui .button[disabled]{color:#a7aaad!important;border-color:#dcdcde!important;background:#f6f7f7!important;box-shadow:none!important;cursor:default;transform:none!important}.wp-core-ui .button-secondary[aria-disabled=true],.wp-core-ui .button[aria-disabled=true]{cursor:default}.wp-core-ui .button-link{margin:0;padding:0;box-shadow:none;border:0;border-radius:0;background:0 0;cursor:pointer;text-align:right;color:#2271b1;text-decoration:underline;transition-property:border,background,color;transition-duration:.05s;transition-timing-function:ease-in-out}.wp-core-ui .button-link:active,.wp-core-ui .button-link:hover{color:#135e96}.wp-core-ui .button-link:focus{color:#043959;box-shadow:0 0 0 2px #2271b1;outline:2px solid transparent}.wp-core-ui .button-link-delete{color:#d63638}.wp-core-ui .button-link-delete:focus,.wp-core-ui .button-link-delete:hover{color:#d63638;background:0 0}.wp-core-ui .button-link-delete:disabled{background:0 0!important}.wp-core-ui .button-primary{background:#2271b1;border-color:#2271b1;color:#fff;text-decoration:none;text-shadow:none}.wp-core-ui .button-primary.focus,.wp-core-ui .button-primary.hover,.wp-core-ui .button-primary:focus,.wp-core-ui .button-primary:hover{background:#135e96;border-color:#135e96;color:#fff}.wp-core-ui .button-primary.focus,.wp-core-ui .button-primary:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #2271b1}.wp-core-ui .button-primary.active,.wp-core-ui .button-primary.active:focus,.wp-core-ui .button-primary.active:hover,.wp-core-ui .button-primary:active{background:#135e96;border-color:#135e96;box-shadow:none;color:#fff}.wp-core-ui .button-primary-disabled,.wp-core-ui .button-primary.disabled,.wp-core-ui .button-primary:disabled,.wp-core-ui .button-primary[disabled]{color:#a7aaad!important;background:#f6f7f7!important;border-color:#dcdcde!important;box-shadow:none!important;text-shadow:none!important;cursor:default}.wp-core-ui .button-primary[aria-disabled=true]{cursor:default}.wp-core-ui .button-group{position:relative;display:inline-block;white-space:nowrap;font-size:0;vertical-align:middle}.wp-core-ui .button-group>.button{display:inline-block;border-radius:0;margin-left:-1px}.wp-core-ui .button-group>.button:first-child{border-radius:0 3px 3px 0}.wp-core-ui .button-group>.button:last-child{border-radius:3px 0 0 3px}.wp-core-ui .button-group>.button-primary+.button{border-right:0}.wp-core-ui .button-group>.button:focus{position:relative;z-index:1}.wp-core-ui .button-group>.button.active{background-color:#dcdcde;color:#135e96;border-color:#0a4b78;box-shadow:inset 0 2px 5px -3px #0a4b78}.wp-core-ui .button-group>.button.active:focus{border-color:#3582c4;box-shadow:inset 0 2px 5px -3px #0a4b78,0 0 0 1px #3582c4}@media screen and (max-width:782px){.wp-core-ui .button,.wp-core-ui .button.button-large,.wp-core-ui .button.button-small,a.preview,input#publish,input#save-post{padding:0 14px;line-height:2.71428571;font-size:14px;vertical-align:middle;min-height:40px;margin-bottom:4px}.wp-core-ui .copy-to-clipboard-container .copy-attachment-url{margin-bottom:0}#media-upload.wp-core-ui .button{padding:0 10px 1px;min-height:24px;line-height:22px;font-size:13px}.media-frame.mode-grid .bulk-select .button{margin-bottom:0}.wp-core-ui .save-post-status.button{position:relative;margin:0 10px 0 14px}.wp-core-ui.wp-customizer .button{font-size:13px;line-height:2.15384615;min-height:30px;margin:0;vertical-align:inherit}.wp-customizer .theme-overlay .theme-actions .button{margin-bottom:5px}.media-modal-content .media-toolbar-primary .media-button{margin-top:10px;margin-right:5px}.interim-login .button.button-large{min-height:30px;line-height:2;padding:0 12px 2px}}<?php return array('dependencies' => array('wp-react-refresh-runtime'), 'version' => '461b2e321e6e009f2209'); <?php return array('dependencies' => array(), 'version' => '8f1acdfb845f670b0ef2'); <?php return array('dependencies' => array('wp-react-refresh-runtime'), 'version' => '461b2e321e6e009f2209'); <?php return array('dependencies' => array(), 'version' => '8f1acdfb845f670b0ef2'); [09-Oct-2025 09:44:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php on line 18 [09-Oct-2025 09:44:34 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php on line 18 [09-Oct-2025 09:58:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php on line 18 [09-Oct-2025 09:58:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTML_Tag_Processor" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/interactivity-api/class-wp-interactivity-api-directives-processor.php on line 18 <?php /** * Interactivity API: Functions and hooks * * @package WordPress * @subpackage Interactivity API * @since 6.5.0 */ /** * Retrieves the main WP_Interactivity_API instance. * * It provides access to the WP_Interactivity_API instance, creating one if it * doesn't exist yet. * * @since 6.5.0 * * @global WP_Interactivity_API $wp_interactivity * * @return WP_Interactivity_API The main WP_Interactivity_API instance. */ function wp_interactivity(): WP_Interactivity_API { global $wp_interactivity; if ( ! ( $wp_interactivity instanceof WP_Interactivity_API ) ) { $wp_interactivity = new WP_Interactivity_API(); } return $wp_interactivity; } /** * Processes the interactivity directives contained within the HTML content * and updates the markup accordingly. * * @since 6.5.0 * * @param string $html The HTML content to process. * @return string The processed HTML content. It returns the original content when the HTML contains unbalanced tags. */ function wp_interactivity_process_directives( string $html ): string { return wp_interactivity()->process_directives( $html ); } /** * Gets and/or sets the initial state of an Interactivity API store for a * given namespace. * * If state for that store namespace already exists, it merges the new * provided state with the existing one. * * The namespace can be omitted inside derived state getters, using the * namespace where the getter is defined. * * @since 6.5.0 * @since 6.6.0 The namespace can be omitted when called inside derived state getters. * * @param string $store_namespace The unique store namespace identifier. * @param array $state Optional. The array that will be merged with the existing state for the specified * store namespace. * @return array The state for the specified store namespace. This will be the updated state if a $state argument was * provided. */ function wp_interactivity_state( ?string $store_namespace = null, array $state = array() ): array { return wp_interactivity()->state( $store_namespace, $state ); } /** * Gets and/or sets the configuration of the Interactivity API for a given * store namespace. * * If configuration for that store namespace exists, it merges the new * provided configuration with the existing one. * * @since 6.5.0 * * @param string $store_namespace The unique store namespace identifier. * @param array $config Optional. The array that will be merged with the existing configuration for the * specified store namespace. * @return array The configuration for the specified store namespace. This will be the updated configuration if a * $config argument was provided. */ function wp_interactivity_config( string $store_namespace, array $config = array() ): array { return wp_interactivity()->config( $store_namespace, $config ); } /** * Generates a `data-wp-context` directive attribute by encoding a context * array. * * This helper function simplifies the creation of `data-wp-context` directives * by providing a way to pass an array of data, which encodes into a JSON string * safe for direct use as a HTML attribute value. * * Example: * * <div <?php echo wp_interactivity_data_wp_context( array( 'isOpen' => true, 'count' => 0 ) ); ?>> * * @since 6.5.0 * * @param array $context The array of context data to encode. * @param string $store_namespace Optional. The unique store namespace identifier. * @return string A complete `data-wp-context` directive with a JSON encoded value representing the context array and * the store namespace if specified. */ function wp_interactivity_data_wp_context( array $context, string $store_namespace = '' ): string { return 'data-wp-context=\'' . ( $store_namespace ? $store_namespace . '::' : '' ) . ( empty( $context ) ? '{}' : wp_json_encode( $context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ) . '\''; } /** * Gets the current Interactivity API context for a given namespace. * * The function should be used only during directive processing. If the * `$store_namespace` parameter is omitted, it uses the current namespace value * on the internal namespace stack. * * It returns an empty array when the specified namespace is not defined. * * @since 6.6.0 * * @param string $store_namespace Optional. The unique store namespace identifier. * @return array The context for the specified store namespace. */ function wp_interactivity_get_context( ?string $store_namespace = null ): array { return wp_interactivity()->get_context( $store_namespace ); } /** * Returns an array representation of the current element being processed. * * The function should be used only during directive processing. * * @since 6.7.0 * * @return array{attributes: array<string, string|bool>}|null Current element. */ function wp_interactivity_get_element(): ?array { return wp_interactivity()->get_element(); } <?php /** * Interactivity API: WP_Interactivity_API_Directives_Processor class. * * @package WordPress * @subpackage Interactivity API * @since 6.5.0 */ /** * Class used to iterate over the tags of an HTML string and help process the * directive attributes. * * @since 6.5.0 * * @access private */ final class WP_Interactivity_API_Directives_Processor extends WP_HTML_Tag_Processor { /** * List of tags whose closer tag is not visited by the WP_HTML_Tag_Processor. * * @since 6.5.0 * @var string[] */ const TAGS_THAT_DONT_VISIT_CLOSER_TAG = array( 'SCRIPT', 'IFRAME', 'NOEMBED', 'NOFRAMES', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP', ); /** * Returns the content between two balanced template tags. * * It positions the cursor in the closer tag of the balanced template tag, * if it exists. * * @since 6.5.0 * * @access private * * @return string|null The content between the current opener template tag and its matching closer tag or null if it * doesn't find the matching closing tag or the current tag is not a template opener tag. */ public function get_content_between_balanced_template_tags() { if ( 'TEMPLATE' !== $this->get_tag() ) { return null; } $positions = $this->get_after_opener_tag_and_before_closer_tag_positions(); if ( ! $positions ) { return null; } list( $after_opener_tag, $before_closer_tag ) = $positions; return substr( $this->html, $after_opener_tag, $before_closer_tag - $after_opener_tag ); } /** * Sets the content between two balanced tags. * * @since 6.5.0 * * @access private * * @param string $new_content The string to replace the content between the matching tags. * @return bool Whether the content was successfully replaced. */ public function set_content_between_balanced_tags( string $new_content ): bool { $positions = $this->get_after_opener_tag_and_before_closer_tag_positions( true ); if ( ! $positions ) { return false; } list( $after_opener_tag, $before_closer_tag ) = $positions; $this->lexical_updates[] = new WP_HTML_Text_Replacement( $after_opener_tag, $before_closer_tag - $after_opener_tag, esc_html( $new_content ) ); return true; } /** * Appends content after the closing tag of a template tag. * * It positions the cursor in the closer tag of the balanced template tag, * if it exists. * * @access private * * @param string $new_content The string to append after the closing template tag. * @return bool Whether the content was successfully appended. */ public function append_content_after_template_tag_closer( string $new_content ): bool { if ( empty( $new_content ) || 'TEMPLATE' !== $this->get_tag() || ! $this->is_tag_closer() ) { return false; } // Flushes any changes. $this->get_updated_html(); $bookmark = 'append_content_after_template_tag_closer'; $this->set_bookmark( $bookmark ); $after_closing_tag = $this->bookmarks[ $bookmark ]->start + $this->bookmarks[ $bookmark ]->length; $this->release_bookmark( $bookmark ); // Appends the new content. $this->lexical_updates[] = new WP_HTML_Text_Replacement( $after_closing_tag, 0, $new_content ); return true; } /** * Gets the positions right after the opener tag and right before the closer * tag in a balanced tag. * * By default, it positions the cursor in the closer tag of the balanced tag. * If $rewind is true, it seeks back to the opener tag. * * @since 6.5.0 * * @access private * * @param bool $rewind Optional. Whether to seek back to the opener tag after finding the positions. Defaults to false. * @return array|null Start and end byte position, or null when no balanced tag bookmarks. */ private function get_after_opener_tag_and_before_closer_tag_positions( bool $rewind = false ) { // Flushes any changes. $this->get_updated_html(); $bookmarks = $this->get_balanced_tag_bookmarks(); if ( ! $bookmarks ) { return null; } list( $opener_tag, $closer_tag ) = $bookmarks; $after_opener_tag = $this->bookmarks[ $opener_tag ]->start + $this->bookmarks[ $opener_tag ]->length; $before_closer_tag = $this->bookmarks[ $closer_tag ]->start; if ( $rewind ) { $this->seek( $opener_tag ); } $this->release_bookmark( $opener_tag ); $this->release_bookmark( $closer_tag ); return array( $after_opener_tag, $before_closer_tag ); } /** * Returns a pair of bookmarks for the current opener tag and the matching * closer tag. * * It positions the cursor in the closer tag of the balanced tag, if it * exists. * * @since 6.5.0 * * @return array|null A pair of bookmarks, or null if there's no matching closing tag. */ private function get_balanced_tag_bookmarks() { static $i = 0; $opener_tag = 'opener_tag_of_balanced_tag_' . ++$i; $this->set_bookmark( $opener_tag ); if ( ! $this->next_balanced_tag_closer_tag() ) { $this->release_bookmark( $opener_tag ); return null; } $closer_tag = 'closer_tag_of_balanced_tag_' . ++$i; $this->set_bookmark( $closer_tag ); return array( $opener_tag, $closer_tag ); } /** * Skips processing the content between tags. * * It positions the cursor in the closer tag of the foreign element, if it * exists. * * This function is intended to skip processing SVG and MathML inner content * instead of bailing out the whole processing. * * @since 6.5.0 * * @access private * * @return bool Whether the foreign content was successfully skipped. */ public function skip_to_tag_closer(): bool { $depth = 1; $tag_name = $this->get_tag(); while ( $depth > 0 && $this->next_tag( array( 'tag_closers' => 'visit' ) ) ) { if ( ! $this->is_tag_closer() && $this->get_attribute_names_with_prefix( 'data-wp-' ) ) { /* translators: 1: SVG or MATH HTML tag. */ $message = sprintf( __( 'Interactivity directives were detected inside an incompatible %1$s tag. These directives will be ignored in the server side render.' ), $tag_name ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); } if ( $this->get_tag() === $tag_name ) { if ( $this->has_self_closing_flag() ) { continue; } $depth += $this->is_tag_closer() ? -1 : 1; } } return 0 === $depth; } /** * Finds the matching closing tag for an opening tag. * * When called while the processor is on an open tag, it traverses the HTML * until it finds the matching closer tag, respecting any in-between content, * including nested tags of the same name. Returns false when called on a * closer tag, a tag that doesn't have a closer tag (void), a tag that * doesn't visit the closer tag, or if no matching closing tag was found. * * @since 6.5.0 * * @access private * * @return bool Whether a matching closing tag was found. */ public function next_balanced_tag_closer_tag(): bool { $depth = 0; $tag_name = $this->get_tag(); if ( ! $this->has_and_visits_its_closer_tag() ) { return false; } while ( $this->next_tag( array( 'tag_name' => $tag_name, 'tag_closers' => 'visit', ) ) ) { if ( ! $this->is_tag_closer() ) { ++$depth; continue; } if ( 0 === $depth ) { return true; } --$depth; } return false; } /** * Checks whether the current tag has and will visit its matching closer tag. * * @since 6.5.0 * * @access private * * @return bool Whether the current tag has a closer tag. */ public function has_and_visits_its_closer_tag(): bool { $tag_name = $this->get_tag(); return null !== $tag_name && ( ! WP_HTML_Processor::is_void( $tag_name ) && ! in_array( $tag_name, self::TAGS_THAT_DONT_VISIT_CLOSER_TAG, true ) ); } } <?php /** * Interactivity API: WP_Interactivity_API class. * * @package WordPress * @subpackage Interactivity API * @since 6.5.0 */ /** * Class used to process the Interactivity API on the server. * * @since 6.5.0 */ final class WP_Interactivity_API { /** * Holds the mapping of directive attribute names to their processor methods. * * @since 6.5.0 * @var array */ private static $directive_processors = array( 'data-wp-interactive' => 'data_wp_interactive_processor', 'data-wp-router-region' => 'data_wp_router_region_processor', 'data-wp-context' => 'data_wp_context_processor', 'data-wp-bind' => 'data_wp_bind_processor', 'data-wp-class' => 'data_wp_class_processor', 'data-wp-style' => 'data_wp_style_processor', 'data-wp-text' => 'data_wp_text_processor', /* * `data-wp-each` needs to be processed in the last place because it moves * the cursor to the end of the processed items to prevent them to be * processed twice. */ 'data-wp-each' => 'data_wp_each_processor', ); /** * Holds the initial state of the different Interactivity API stores. * * This state is used during the server directive processing. Then, it is * serialized and sent to the client as part of the interactivity data to be * recovered during the hydration of the client interactivity stores. * * @since 6.5.0 * @var array */ private $state_data = array(); /** * Holds the configuration required by the different Interactivity API stores. * * This configuration is serialized and sent to the client as part of the * interactivity data and can be accessed by the client interactivity stores. * * @since 6.5.0 * @var array */ private $config_data = array(); /** * Flag that indicates whether the `data-wp-router-region` directive has * been found in the HTML and processed. * * The value is saved in a private property of the WP_Interactivity_API * instance instead of using a static variable inside the processor * function, which would hold the same value for all instances * independently of whether they have processed any * `data-wp-router-region` directive or not. * * @since 6.5.0 * @var bool */ private $has_processed_router_region = false; /** * Stack of namespaces defined by `data-wp-interactive` directives, in * the order they are processed. * * This is only available during directive processing, otherwise it is `null`. * * @since 6.6.0 * @var array<string>|null */ private $namespace_stack = null; /** * Stack of contexts defined by `data-wp-context` directives, in * the order they are processed. * * This is only available during directive processing, otherwise it is `null`. * * @since 6.6.0 * @var array<array<mixed>>|null */ private $context_stack = null; /** * Representation in array format of the element currently being processed. * * This is only available during directive processing, otherwise it is `null`. * * @since 6.7.0 * @var array{attributes: array<string, string|bool>}|null */ private $current_element = null; /** * Gets and/or sets the initial state of an Interactivity API store for a * given namespace. * * If state for that store namespace already exists, it merges the new * provided state with the existing one. * * When no namespace is specified, it returns the state defined for the * current value in the internal namespace stack during a `process_directives` call. * * @since 6.5.0 * @since 6.6.0 The `$store_namespace` param is optional. * * @param string $store_namespace Optional. The unique store namespace identifier. * @param array $state Optional. The array that will be merged with the existing state for the specified * store namespace. * @return array The current state for the specified store namespace. This will be the updated state if a $state * argument was provided. */ public function state( ?string $store_namespace = null, ?array $state = null ): array { if ( ! $store_namespace ) { if ( $state ) { _doing_it_wrong( __METHOD__, __( 'The namespace is required when state data is passed.' ), '6.6.0' ); return array(); } if ( null !== $store_namespace ) { _doing_it_wrong( __METHOD__, __( 'The namespace should be a non-empty string.' ), '6.6.0' ); return array(); } if ( null === $this->namespace_stack ) { _doing_it_wrong( __METHOD__, __( 'The namespace can only be omitted during directive processing.' ), '6.6.0' ); return array(); } $store_namespace = end( $this->namespace_stack ); } if ( ! isset( $this->state_data[ $store_namespace ] ) ) { $this->state_data[ $store_namespace ] = array(); } if ( is_array( $state ) ) { $this->state_data[ $store_namespace ] = array_replace_recursive( $this->state_data[ $store_namespace ], $state ); } return $this->state_data[ $store_namespace ]; } /** * Gets and/or sets the configuration of the Interactivity API for a given * store namespace. * * If configuration for that store namespace exists, it merges the new * provided configuration with the existing one. * * @since 6.5.0 * * @param string $store_namespace The unique store namespace identifier. * @param array $config Optional. The array that will be merged with the existing configuration for the * specified store namespace. * @return array The configuration for the specified store namespace. This will be the updated configuration if a * $config argument was provided. */ public function config( string $store_namespace, array $config = array() ): array { if ( ! isset( $this->config_data[ $store_namespace ] ) ) { $this->config_data[ $store_namespace ] = array(); } if ( is_array( $config ) ) { $this->config_data[ $store_namespace ] = array_replace_recursive( $this->config_data[ $store_namespace ], $config ); } return $this->config_data[ $store_namespace ]; } /** * Prints the serialized client-side interactivity data. * * Encodes the config and initial state into JSON and prints them inside a * script tag of type "application/json". Once in the browser, the state will * be parsed and used to hydrate the client-side interactivity stores and the * configuration will be available using a `getConfig` utility. * * @since 6.5.0 * * @deprecated 6.7.0 Client data passing is handled by the {@see "script_module_data_{$module_id}"} filter. */ public function print_client_interactivity_data() { _deprecated_function( __METHOD__, '6.7.0' ); } /** * Set client-side interactivity-router data. * * Once in the browser, the state will be parsed and used to hydrate the client-side * interactivity stores and the configuration will be available using a `getConfig` utility. * * @since 6.7.0 * * @param array $data Data to filter. * @return array Data for the Interactivity Router script module. */ public function filter_script_module_interactivity_router_data( array $data ): array { if ( ! isset( $data['i18n'] ) ) { $data['i18n'] = array(); } $data['i18n']['loading'] = __( 'Loading page, please wait.' ); $data['i18n']['loaded'] = __( 'Page Loaded.' ); return $data; } /** * Set client-side interactivity data. * * Once in the browser, the state will be parsed and used to hydrate the client-side * interactivity stores and the configuration will be available using a `getConfig` utility. * * @since 6.7.0 * * @param array $data Data to filter. * @return array Data for the Interactivity API script module. */ public function filter_script_module_interactivity_data( array $data ): array { if ( empty( $this->state_data ) && empty( $this->config_data ) ) { return $data; } $config = array(); foreach ( $this->config_data as $key => $value ) { if ( ! empty( $value ) ) { $config[ $key ] = $value; } } if ( ! empty( $config ) ) { $data['config'] = $config; } $state = array(); foreach ( $this->state_data as $key => $value ) { if ( ! empty( $value ) ) { $state[ $key ] = $value; } } if ( ! empty( $state ) ) { $data['state'] = $state; } return $data; } /** * Returns the latest value on the context stack with the passed namespace. * * When the namespace is omitted, it uses the current namespace on the * namespace stack during a `process_directives` call. * * @since 6.6.0 * * @param string $store_namespace Optional. The unique store namespace identifier. */ public function get_context( ?string $store_namespace = null ): array { if ( null === $this->context_stack ) { _doing_it_wrong( __METHOD__, __( 'The context can only be read during directive processing.' ), '6.6.0' ); return array(); } if ( ! $store_namespace ) { if ( null !== $store_namespace ) { _doing_it_wrong( __METHOD__, __( 'The namespace should be a non-empty string.' ), '6.6.0' ); return array(); } $store_namespace = end( $this->namespace_stack ); } $context = end( $this->context_stack ); return ( $store_namespace && $context && isset( $context[ $store_namespace ] ) ) ? $context[ $store_namespace ] : array(); } /** * Returns an array representation of the current element being processed. * * The returned array contains a copy of the element attributes. * * @since 6.7.0 * * @return array{attributes: array<string, string|bool>}|null Current element. */ public function get_element(): ?array { if ( null === $this->current_element ) { _doing_it_wrong( __METHOD__, __( 'The element can only be read during directive processing.' ), '6.7.0' ); } return $this->current_element; } /** * Registers the `@wordpress/interactivity` script modules. * * @deprecated 6.7.0 Script Modules registration is handled by {@see wp_default_script_modules()}. * * @since 6.5.0 */ public function register_script_modules() { _deprecated_function( __METHOD__, '6.7.0', 'wp_default_script_modules' ); } /** * Adds the necessary hooks for the Interactivity API. * * @since 6.5.0 */ public function add_hooks() { add_filter( 'script_module_data_@wordpress/interactivity', array( $this, 'filter_script_module_interactivity_data' ) ); add_filter( 'script_module_data_@wordpress/interactivity-router', array( $this, 'filter_script_module_interactivity_router_data' ) ); } /** * Processes the interactivity directives contained within the HTML content * and updates the markup accordingly. * * @since 6.5.0 * * @param string $html The HTML content to process. * @return string The processed HTML content. It returns the original content when the HTML contains unbalanced tags. */ public function process_directives( string $html ): string { if ( ! str_contains( $html, 'data-wp-' ) ) { return $html; } $this->namespace_stack = array(); $this->context_stack = array(); $result = $this->_process_directives( $html ); $this->namespace_stack = null; $this->context_stack = null; return null === $result ? $html : $result; } /** * Processes the interactivity directives contained within the HTML content * and updates the markup accordingly. * * It uses the WP_Interactivity_API instance's context and namespace stacks, * which are shared between all calls. * * This method returns null if the HTML contains unbalanced tags. * * @since 6.6.0 * * @param string $html The HTML content to process. * @return string|null The processed HTML content. It returns null when the HTML contains unbalanced tags. */ private function _process_directives( string $html ) { $p = new WP_Interactivity_API_Directives_Processor( $html ); $tag_stack = array(); $unbalanced = false; $directive_processor_prefixes = array_keys( self::$directive_processors ); $directive_processor_prefixes_reversed = array_reverse( $directive_processor_prefixes ); /* * Save the current size for each stack to restore them in case * the processing finds unbalanced tags. */ $namespace_stack_size = count( $this->namespace_stack ); $context_stack_size = count( $this->context_stack ); while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) { $tag_name = $p->get_tag(); /* * Directives inside SVG and MATH tags are not processed, * as they are not compatible with the Tag Processor yet. * We still process the rest of the HTML. */ if ( 'SVG' === $tag_name || 'MATH' === $tag_name ) { if ( $p->get_attribute_names_with_prefix( 'data-wp-' ) ) { /* translators: 1: SVG or MATH HTML tag, 2: Namespace of the interactive block. */ $message = sprintf( __( 'Interactivity directives were detected on an incompatible %1$s tag when processing "%2$s". These directives will be ignored in the server side render.' ), $tag_name, end( $this->namespace_stack ) ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); } $p->skip_to_tag_closer(); continue; } if ( $p->is_tag_closer() ) { list( $opening_tag_name, $directives_prefixes ) = end( $tag_stack ); if ( 0 === count( $tag_stack ) || $opening_tag_name !== $tag_name ) { /* * If the tag stack is empty or the matching opening tag is not the * same than the closing tag, it means the HTML is unbalanced and it * stops processing it. */ $unbalanced = true; break; } else { // Remove the last tag from the stack. array_pop( $tag_stack ); } } else { if ( 0 !== count( $p->get_attribute_names_with_prefix( 'data-wp-each-child' ) ) ) { /* * If the tag has a `data-wp-each-child` directive, jump to its closer * tag because those tags have already been processed. */ $p->next_balanced_tag_closer_tag(); continue; } else { $directives_prefixes = array(); // Checks if there is a server directive processor registered for each directive. foreach ( $p->get_attribute_names_with_prefix( 'data-wp-' ) as $attribute_name ) { if ( ! preg_match( /* * This must align with the client-side regex used by the interactivity API. * @see https://github.com/WordPress/gutenberg/blob/ca616014255efbb61f34c10917d52a2d86c1c660/packages/interactivity/src/vdom.ts#L20-L32 */ '/' . '^data-wp-' . // Match alphanumeric characters including hyphen-separated // segments. It excludes underscore intentionally to prevent confusion. // E.g., "custom-directive". '([a-z0-9]+(?:-[a-z0-9]+)*)' . // (Optional) Match '--' followed by any alphanumeric charachters. It // excludes underscore intentionally to prevent confusion, but it can // contain multiple hyphens. E.g., "--custom-prefix--with-more-info". '(?:--([a-z0-9_-]+))?$' . '/i', $attribute_name ) ) { continue; } list( $directive_prefix ) = $this->extract_prefix_and_suffix( $attribute_name ); if ( array_key_exists( $directive_prefix, self::$directive_processors ) ) { $directives_prefixes[] = $directive_prefix; } } /* * If this tag will visit its closer tag, it adds it to the tag stack * so it can process its closing tag and check for unbalanced tags. */ if ( $p->has_and_visits_its_closer_tag() ) { $tag_stack[] = array( $tag_name, $directives_prefixes ); } } } /* * If the matching opener tag didn't have any directives, it can skip the * processing. */ if ( 0 === count( $directives_prefixes ) ) { continue; } // Directive processing might be different depending on if it is entering the tag or exiting it. $modes = array( 'enter' => ! $p->is_tag_closer(), 'exit' => $p->is_tag_closer() || ! $p->has_and_visits_its_closer_tag(), ); // Get the element attributes to include them in the element representation. $element_attrs = array(); $attr_names = $p->get_attribute_names_with_prefix( '' ) ?? array(); foreach ( $attr_names as $name ) { $element_attrs[ $name ] = $p->get_attribute( $name ); } // Assign the current element right before running its directive processors. $this->current_element = array( 'attributes' => $element_attrs, ); foreach ( $modes as $mode => $should_run ) { if ( ! $should_run ) { continue; } /* * Sorts the attributes by the order of the `directives_processor` array * and checks what directives are present in this element. */ $existing_directives_prefixes = array_intersect( 'enter' === $mode ? $directive_processor_prefixes : $directive_processor_prefixes_reversed, $directives_prefixes ); foreach ( $existing_directives_prefixes as $directive_prefix ) { $func = is_array( self::$directive_processors[ $directive_prefix ] ) ? self::$directive_processors[ $directive_prefix ] : array( $this, self::$directive_processors[ $directive_prefix ] ); call_user_func_array( $func, array( $p, $mode, &$tag_stack ) ); } } // Clear the current element. $this->current_element = null; } if ( $unbalanced ) { // Reset the namespace and context stacks to their previous values. array_splice( $this->namespace_stack, $namespace_stack_size ); array_splice( $this->context_stack, $context_stack_size ); } /* * It returns null if the HTML is unbalanced because unbalanced HTML is * not safe to process. In that case, the Interactivity API runtime will * update the HTML on the client side during the hydration. It will also * display a notice to the developer to inform them about the issue. */ if ( $unbalanced || 0 < count( $tag_stack ) ) { $tag_errored = 0 < count( $tag_stack ) ? end( $tag_stack )[0] : $tag_name; /* translators: %1s: Namespace processed, %2s: The tag that caused the error; could be any HTML tag. */ $message = sprintf( __( 'Interactivity directives failed to process in "%1$s" due to a missing "%2$s" end tag.' ), end( $this->namespace_stack ), $tag_errored ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); return null; } return $p->get_updated_html(); } /** * Evaluates the reference path passed to a directive based on the current * store namespace, state and context. * * @since 6.5.0 * @since 6.6.0 The function now adds a warning when the namespace is null, falsy, or the directive value is empty. * @since 6.6.0 Removed `default_namespace` and `context` arguments. * @since 6.6.0 Add support for derived state. * * @param string|true $directive_value The directive attribute value string or `true` when it's a boolean attribute. * @return mixed|null The result of the evaluation. Null if the reference path doesn't exist or the namespace is falsy. */ private function evaluate( $directive_value ) { $default_namespace = end( $this->namespace_stack ); $context = end( $this->context_stack ); list( $ns, $path ) = $this->extract_directive_value( $directive_value, $default_namespace ); if ( ! $ns || ! $path ) { /* translators: %s: The directive value referenced. */ $message = sprintf( __( 'Namespace or reference path cannot be empty. Directive value referenced: %s' ), $directive_value ); _doing_it_wrong( __METHOD__, $message, '6.6.0' ); return null; } $store = array( 'state' => $this->state_data[ $ns ] ?? array(), 'context' => $context[ $ns ] ?? array(), ); // Checks if the reference path is preceded by a negation operator (!). $should_negate_value = '!' === $path[0]; $path = $should_negate_value ? substr( $path, 1 ) : $path; // Extracts the value from the store using the reference path. $path_segments = explode( '.', $path ); $current = $store; foreach ( $path_segments as $path_segment ) { /* * Special case for numeric arrays and strings. Add length * property mimicking JavaScript behavior. * * @since 6.8.0 */ if ( 'length' === $path_segment ) { if ( is_array( $current ) && array_is_list( $current ) ) { $current = count( $current ); break; } if ( is_string( $current ) ) { /* * Differences in encoding between PHP strings and * JavaScript mean that it's complicated to calculate * the string length JavaScript would see from PHP. * `strlen` is a reasonable approximation. * * Users that desire a more precise length likely have * more precise needs than "bytelength" and should * implement their own length calculation in derived * state taking into account encoding and their desired * output (codepoints, graphemes, bytes, etc.). */ $current = strlen( $current ); break; } } if ( ( is_array( $current ) || $current instanceof ArrayAccess ) && isset( $current[ $path_segment ] ) ) { $current = $current[ $path_segment ]; } elseif ( is_object( $current ) && isset( $current->$path_segment ) ) { $current = $current->$path_segment; } else { $current = null; break; } if ( $current instanceof Closure ) { /* * This state getter's namespace is added to the stack so that * `state()` or `get_config()` read that namespace when called * without specifying one. */ array_push( $this->namespace_stack, $ns ); try { $current = $current(); } catch ( Throwable $e ) { _doing_it_wrong( __METHOD__, sprintf( /* translators: 1: Path pointing to an Interactivity API state property, 2: Namespace for an Interactivity API store. */ __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ), $path, $ns ), '6.6.0' ); return null; } finally { // Remove the property's namespace from the stack. array_pop( $this->namespace_stack ); } } } // Returns the opposite if it contains a negation operator (!). return $should_negate_value ? ! $current : $current; } /** * Extracts the directive attribute name to separate and return the directive * prefix and an optional suffix. * * The suffix is the string after the first double hyphen and the prefix is * everything that comes before the suffix. * * Example: * * extract_prefix_and_suffix( 'data-wp-interactive' ) => array( 'data-wp-interactive', null ) * extract_prefix_and_suffix( 'data-wp-bind--src' ) => array( 'data-wp-bind', 'src' ) * extract_prefix_and_suffix( 'data-wp-foo--and--bar' ) => array( 'data-wp-foo', 'and--bar' ) * * @since 6.5.0 * * @param string $directive_name The directive attribute name. * @return array An array containing the directive prefix and optional suffix. */ private function extract_prefix_and_suffix( string $directive_name ): array { return explode( '--', $directive_name, 2 ); } /** * Parses and extracts the namespace and reference path from the given * directive attribute value. * * If the value doesn't contain an explicit namespace, it returns the * default one. If the value contains a JSON object instead of a reference * path, the function tries to parse it and return the resulting array. If * the value contains strings that represent booleans ("true" and "false"), * numbers ("1" and "1.2") or "null", the function also transform them to * regular booleans, numbers and `null`. * * Example: * * extract_directive_value( 'actions.foo', 'myPlugin' ) => array( 'myPlugin', 'actions.foo' ) * extract_directive_value( 'otherPlugin::actions.foo', 'myPlugin' ) => array( 'otherPlugin', 'actions.foo' ) * extract_directive_value( '{ "isOpen": false }', 'myPlugin' ) => array( 'myPlugin', array( 'isOpen' => false ) ) * extract_directive_value( 'otherPlugin::{ "isOpen": false }', 'myPlugin' ) => array( 'otherPlugin', array( 'isOpen' => false ) ) * * @since 6.5.0 * * @param string|true $directive_value The directive attribute value. It can be `true` when it's a boolean * attribute. * @param string|null $default_namespace Optional. The default namespace if none is explicitly defined. * @return array An array containing the namespace in the first item and the JSON, the reference path, or null on the * second item. */ private function extract_directive_value( $directive_value, $default_namespace = null ): array { if ( empty( $directive_value ) || is_bool( $directive_value ) ) { return array( $default_namespace, null ); } // Replaces the value and namespace if there is a namespace in the value. if ( 1 === preg_match( '/^([\w\-_\/]+)::./', $directive_value ) ) { list($default_namespace, $directive_value) = explode( '::', $directive_value, 2 ); } /* * Tries to decode the value as a JSON object. If it fails and the value * isn't `null`, it returns the value as it is. Otherwise, it returns the * decoded JSON or null for the string `null`. */ $decoded_json = json_decode( $directive_value, true ); if ( null !== $decoded_json || 'null' === $directive_value ) { $directive_value = $decoded_json; } return array( $default_namespace, $directive_value ); } /** * Transforms a kebab-case string to camelCase. * * @param string $str The kebab-case string to transform to camelCase. * @return string The transformed camelCase string. */ private function kebab_to_camel_case( string $str ): string { return lcfirst( preg_replace_callback( '/(-)([a-z])/', function ( $matches ) { return strtoupper( $matches[2] ); }, strtolower( rtrim( $str, '-' ) ) ) ); } /** * Processes the `data-wp-interactive` directive. * * It adds the default store namespace defined in the directive value to the * stack so that it's available for the nested interactivity elements. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_interactive_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { // When exiting tags, it removes the last namespace from the stack. if ( 'exit' === $mode ) { array_pop( $this->namespace_stack ); return; } // Tries to decode the `data-wp-interactive` attribute value. $attribute_value = $p->get_attribute( 'data-wp-interactive' ); /* * Pushes the newly defined namespace or the current one if the * `data-wp-interactive` definition was invalid or does not contain a * namespace. It does so because the function pops out the current namespace * from the stack whenever it finds a `data-wp-interactive`'s closing tag, * independently of whether the previous `data-wp-interactive` definition * contained a valid namespace. */ $new_namespace = null; if ( is_string( $attribute_value ) && ! empty( $attribute_value ) ) { $decoded_json = json_decode( $attribute_value, true ); if ( is_array( $decoded_json ) ) { $new_namespace = $decoded_json['namespace'] ?? null; } else { $new_namespace = $attribute_value; } } $this->namespace_stack[] = ( $new_namespace && 1 === preg_match( '/^([\w\-_\/]+)/', $new_namespace ) ) ? $new_namespace : end( $this->namespace_stack ); } /** * Processes the `data-wp-context` directive. * * It adds the context defined in the directive value to the stack so that * it's available for the nested interactivity elements. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_context_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { // When exiting tags, it removes the last context from the stack. if ( 'exit' === $mode ) { array_pop( $this->context_stack ); return; } $attribute_value = $p->get_attribute( 'data-wp-context' ); $namespace_value = end( $this->namespace_stack ); // Separates the namespace from the context JSON object. list( $namespace_value, $decoded_json ) = is_string( $attribute_value ) && ! empty( $attribute_value ) ? $this->extract_directive_value( $attribute_value, $namespace_value ) : array( $namespace_value, null ); /* * If there is a namespace, it adds a new context to the stack merging the * previous context with the new one. */ if ( is_string( $namespace_value ) ) { $this->context_stack[] = array_replace_recursive( end( $this->context_stack ) !== false ? end( $this->context_stack ) : array(), array( $namespace_value => is_array( $decoded_json ) ? $decoded_json : array() ) ); } else { /* * If there is no namespace, it pushes the current context to the stack. * It needs to do so because the function pops out the current context * from the stack whenever it finds a `data-wp-context`'s closing tag. */ $this->context_stack[] = end( $this->context_stack ); } } /** * Processes the `data-wp-bind` directive. * * It updates or removes the bound attributes based on the evaluation of its * associated reference. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_bind_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $all_bind_directives = $p->get_attribute_names_with_prefix( 'data-wp-bind--' ); foreach ( $all_bind_directives as $attribute_name ) { list( , $bound_attribute ) = $this->extract_prefix_and_suffix( $attribute_name ); if ( empty( $bound_attribute ) ) { return; } $attribute_value = $p->get_attribute( $attribute_name ); $result = $this->evaluate( $attribute_value ); if ( null !== $result && ( false !== $result || ( strlen( $bound_attribute ) > 5 && '-' === $bound_attribute[4] ) ) ) { /* * If the result of the evaluation is a boolean and the attribute is * `aria-` or `data-, convert it to a string "true" or "false". It * follows the exact same logic as Preact because it needs to * replicate what Preact will later do in the client: * https://github.com/preactjs/preact/blob/ea49f7a0f9d1ff2c98c0bdd66aa0cbc583055246/src/diff/props.js#L131C24-L136 */ if ( is_bool( $result ) && ( strlen( $bound_attribute ) > 5 && '-' === $bound_attribute[4] ) ) { $result = $result ? 'true' : 'false'; } $p->set_attribute( $bound_attribute, $result ); } else { $p->remove_attribute( $bound_attribute ); } } } } /** * Processes the `data-wp-class` directive. * * It adds or removes CSS classes in the current HTML element based on the * evaluation of its associated references. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_class_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $all_class_directives = $p->get_attribute_names_with_prefix( 'data-wp-class--' ); foreach ( $all_class_directives as $attribute_name ) { list( , $class_name ) = $this->extract_prefix_and_suffix( $attribute_name ); if ( empty( $class_name ) ) { return; } $attribute_value = $p->get_attribute( $attribute_name ); $result = $this->evaluate( $attribute_value ); if ( $result ) { $p->add_class( $class_name ); } else { $p->remove_class( $class_name ); } } } } /** * Processes the `data-wp-style` directive. * * It updates the style attribute value of the current HTML element based on * the evaluation of its associated references. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_style_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $all_style_attributes = $p->get_attribute_names_with_prefix( 'data-wp-style--' ); foreach ( $all_style_attributes as $attribute_name ) { list( , $style_property ) = $this->extract_prefix_and_suffix( $attribute_name ); if ( empty( $style_property ) ) { continue; } $directive_attribute_value = $p->get_attribute( $attribute_name ); $style_property_value = $this->evaluate( $directive_attribute_value ); $style_attribute_value = $p->get_attribute( 'style' ); $style_attribute_value = ( $style_attribute_value && ! is_bool( $style_attribute_value ) ) ? $style_attribute_value : ''; /* * Checks first if the style property is not falsy and the style * attribute value is not empty because if it is, it doesn't need to * update the attribute value. */ if ( $style_property_value || $style_attribute_value ) { $style_attribute_value = $this->merge_style_property( $style_attribute_value, $style_property, $style_property_value ); /* * If the style attribute value is not empty, it sets it. Otherwise, * it removes it. */ if ( ! empty( $style_attribute_value ) ) { $p->set_attribute( 'style', $style_attribute_value ); } else { $p->remove_attribute( 'style' ); } } } } } /** * Merges an individual style property in the `style` attribute of an HTML * element, updating or removing the property when necessary. * * If a property is modified, the old one is removed and the new one is added * at the end of the list. * * @since 6.5.0 * * Example: * * merge_style_property( 'color:green;', 'color', 'red' ) => 'color:red;' * merge_style_property( 'background:green;', 'color', 'red' ) => 'background:green;color:red;' * merge_style_property( 'color:green;', 'color', null ) => '' * * @param string $style_attribute_value The current style attribute value. * @param string $style_property_name The style property name to set. * @param string|false|null $style_property_value The value to set for the style property. With false, null or an * empty string, it removes the style property. * @return string The new style attribute value after the specified property has been added, updated or removed. */ private function merge_style_property( string $style_attribute_value, string $style_property_name, $style_property_value ): string { $style_assignments = explode( ';', $style_attribute_value ); $result = array(); $style_property_value = ! empty( $style_property_value ) ? rtrim( trim( $style_property_value ), ';' ) : null; $new_style_property = $style_property_value ? $style_property_name . ':' . $style_property_value . ';' : ''; // Generates an array with all the properties but the modified one. foreach ( $style_assignments as $style_assignment ) { if ( empty( trim( $style_assignment ) ) ) { continue; } list( $name, $value ) = explode( ':', $style_assignment ); if ( trim( $name ) !== $style_property_name ) { $result[] = trim( $name ) . ':' . trim( $value ) . ';'; } } // Adds the new/modified property at the end of the list. $result[] = $new_style_property; return implode( '', $result ); } /** * Processes the `data-wp-text` directive. * * It updates the inner content of the current HTML element based on the * evaluation of its associated reference. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_text_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode ) { $attribute_value = $p->get_attribute( 'data-wp-text' ); $result = $this->evaluate( $attribute_value ); /* * Follows the same logic as Preact in the client and only changes the * content if the value is a string or a number. Otherwise, it removes the * content. */ if ( is_string( $result ) || is_numeric( $result ) ) { $p->set_content_between_balanced_tags( esc_html( $result ) ); } else { $p->set_content_between_balanced_tags( '' ); } } } /** * Returns the CSS styles for animating the top loading bar in the router. * * @since 6.5.0 * * @return string The CSS styles for the router's top loading bar animation. */ private function get_router_animation_styles(): string { return <<<CSS .wp-interactivity-router-loading-bar { position: fixed; top: 0; left: 0; margin: 0; padding: 0; width: 100vw; max-width: 100vw !important; height: 4px; background-color: #000; opacity: 0 } .wp-interactivity-router-loading-bar.start-animation { animation: wp-interactivity-router-loading-bar-start-animation 30s cubic-bezier(0.03, 0.5, 0, 1) forwards } .wp-interactivity-router-loading-bar.finish-animation { animation: wp-interactivity-router-loading-bar-finish-animation 300ms ease-in } @keyframes wp-interactivity-router-loading-bar-start-animation { 0% { transform: scaleX(0); transform-origin: 0 0; opacity: 1 } 100% { transform: scaleX(1); transform-origin: 0 0; opacity: 1 } } @keyframes wp-interactivity-router-loading-bar-finish-animation { 0% { opacity: 1 } 50% { opacity: 1 } 100% { opacity: 0 } } CSS; } /** * Deprecated. * * @since 6.5.0 * @deprecated 6.7.0 Use {@see WP_Interactivity_API::print_router_markup} instead. */ public function print_router_loading_and_screen_reader_markup() { _deprecated_function( __METHOD__, '6.7.0', 'WP_Interactivity_API::print_router_markup' ); // Call the new method. $this->print_router_markup(); } /** * Outputs markup for the @wordpress/interactivity-router script module. * * This method prints a div element representing a loading bar visible during * navigation. * * @since 6.7.0 */ public function print_router_markup() { echo <<<HTML <div class="wp-interactivity-router-loading-bar" data-wp-interactive="core/router" data-wp-class--start-animation="state.navigation.hasStarted" data-wp-class--finish-animation="state.navigation.hasFinished" ></div> HTML; } /** * Processes the `data-wp-router-region` directive. * * It renders in the footer a set of HTML elements to notify users about * client-side navigations. More concretely, the elements added are 1) a * top loading bar to visually inform that a navigation is in progress * and 2) an `aria-live` region for accessible navigation announcements. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. */ private function data_wp_router_region_processor( WP_Interactivity_API_Directives_Processor $p, string $mode ) { if ( 'enter' === $mode && ! $this->has_processed_router_region ) { $this->has_processed_router_region = true; // Enqueues as an inline style. wp_register_style( 'wp-interactivity-router-animations', false ); wp_add_inline_style( 'wp-interactivity-router-animations', $this->get_router_animation_styles() ); wp_enqueue_style( 'wp-interactivity-router-animations' ); // Adds the necessary markup to the footer. add_action( 'wp_footer', array( $this, 'print_router_markup' ) ); } } /** * Processes the `data-wp-each` directive. * * This directive gets an array passed as reference and iterates over it * generating new content for each item based on the inner markup of the * `template` tag. * * @since 6.5.0 * * @param WP_Interactivity_API_Directives_Processor $p The directives processor instance. * @param string $mode Whether the processing is entering or exiting the tag. * @param array $tag_stack The reference to the tag stack. */ private function data_wp_each_processor( WP_Interactivity_API_Directives_Processor $p, string $mode, array &$tag_stack ) { if ( 'enter' === $mode && 'TEMPLATE' === $p->get_tag() ) { $attribute_name = $p->get_attribute_names_with_prefix( 'data-wp-each' )[0]; $extracted_suffix = $this->extract_prefix_and_suffix( $attribute_name ); $item_name = isset( $extracted_suffix[1] ) ? $this->kebab_to_camel_case( $extracted_suffix[1] ) : 'item'; $attribute_value = $p->get_attribute( $attribute_name ); $result = $this->evaluate( $attribute_value ); // Gets the content between the template tags and leaves the cursor in the closer tag. $inner_content = $p->get_content_between_balanced_template_tags(); // Checks if there is a manual server-side directive processing. $template_end = 'data-wp-each: template end'; $p->set_bookmark( $template_end ); $p->next_tag(); $manual_sdp = $p->get_attribute( 'data-wp-each-child' ); $p->seek( $template_end ); // Rewinds to the template closer tag. $p->release_bookmark( $template_end ); /* * It doesn't process in these situations: * - Manual server-side directive processing. * - Empty or non-array values. * - Associative arrays because those are deserialized as objects in JS. * - Templates that contain top-level texts because those texts can't be * identified and removed in the client. */ if ( $manual_sdp || empty( $result ) || ! is_array( $result ) || ! array_is_list( $result ) || ! str_starts_with( trim( $inner_content ), '<' ) || ! str_ends_with( trim( $inner_content ), '>' ) ) { array_pop( $tag_stack ); return; } // Extracts the namespace from the directive attribute value. $namespace_value = end( $this->namespace_stack ); list( $namespace_value ) = is_string( $attribute_value ) && ! empty( $attribute_value ) ? $this->extract_directive_value( $attribute_value, $namespace_value ) : array( $namespace_value, null ); // Processes the inner content for each item of the array. $processed_content = ''; foreach ( $result as $item ) { // Creates a new context that includes the current item of the array. $this->context_stack[] = array_replace_recursive( end( $this->context_stack ) !== false ? end( $this->context_stack ) : array(), array( $namespace_value => array( $item_name => $item ) ) ); // Processes the inner content with the new context. $processed_item = $this->_process_directives( $inner_content ); if ( null === $processed_item ) { // If the HTML is unbalanced, stop processing it. array_pop( $this->context_stack ); return; } // Adds the `data-wp-each-child` to each top-level tag. $i = new WP_Interactivity_API_Directives_Processor( $processed_item ); while ( $i->next_tag() ) { $i->set_attribute( 'data-wp-each-child', true ); $i->next_balanced_tag_closer_tag(); } $processed_content .= $i->get_updated_html(); // Removes the current context from the stack. array_pop( $this->context_stack ); } // Appends the processed content after the tag closer of the template. $p->append_content_after_template_tag_closer( $processed_content ); // Pops the last tag because it skipped the closing tag of the template tag. array_pop( $tag_stack ); } } } <?php /** * RSS2 Feed Template for displaying RSS2 Comments feed. * * @package WordPress */ header( 'Content-Type: ' . feed_content_type( 'rss2' ) . '; charset=' . get_option( 'blog_charset' ), true ); echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?' . '>'; /** This action is documented in wp-includes/feed-rss2.php */ do_action( 'rss_tag_pre', 'rss2-comments' ); ?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" <?php /** This action is documented in wp-includes/feed-rss2.php */ do_action( 'rss2_ns' ); ?> <?php /** * Fires at the end of the RSS root to add namespaces. * * @since 2.8.0 */ do_action( 'rss2_comments_ns' ); ?> > <channel> <title> <?php if ( is_singular() ) { /* translators: Comments feed title. %s: Post title. */ printf( ent2ncr( __( 'Comments on: %s' ) ), get_the_title_rss() ); } elseif ( is_search() ) { /* translators: Comments feed title. 1: Site title, 2: Search query. */ printf( ent2ncr( __( 'Comments for %1$s searching on %2$s' ) ), get_bloginfo_rss( 'name' ), get_search_query() ); } else { /* translators: Comments feed title. %s: Site title. */ printf( ent2ncr( __( 'Comments for %s' ) ), get_wp_title_rss() ); } ?> </title> <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" /> <link><?php ( is_single() ) ? the_permalink_rss() : bloginfo_rss( 'url' ); ?></link> <description><?php bloginfo_rss( 'description' ); ?></description> <lastBuildDate><?php echo get_feed_build_date( 'r' ); ?></lastBuildDate> <sy:updatePeriod> <?php /** This filter is documented in wp-includes/feed-rss2.php */ echo apply_filters( 'rss_update_period', 'hourly' ); ?> </sy:updatePeriod> <sy:updateFrequency> <?php /** This filter is documented in wp-includes/feed-rss2.php */ echo apply_filters( 'rss_update_frequency', '1' ); ?> </sy:updateFrequency> <?php /** * Fires at the end of the RSS2 comment feed header. * * @since 2.3.0 */ do_action( 'commentsrss2_head' ); while ( have_comments() ) : the_comment(); $comment_post = get_post( $comment->comment_post_ID ); /** * @global WP_Post $post Global post object. */ $GLOBALS['post'] = $comment_post; ?> <item> <title> <?php if ( ! is_singular() ) { $title = get_the_title( $comment_post->ID ); /** This filter is documented in wp-includes/feed.php */ $title = apply_filters( 'the_title_rss', $title ); /* translators: Individual comment title. 1: Post title, 2: Comment author name. */ printf( ent2ncr( __( 'Comment on %1$s by %2$s' ) ), $title, get_comment_author_rss() ); } else { /* translators: Comment author title. %s: Comment author name. */ printf( ent2ncr( __( 'By: %s' ) ), get_comment_author_rss() ); } ?> </title> <link><?php comment_link(); ?></link> <dc:creator><![CDATA[<?php echo get_comment_author_rss(); ?>]]></dc:creator> <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_comment_time( 'Y-m-d H:i:s', true, false ), false ); ?></pubDate> <guid isPermaLink="false"><?php comment_guid(); ?></guid> <?php if ( post_password_required( $comment_post ) ) : ?> <description><?php echo ent2ncr( __( 'Protected Comments: Please enter your password to view comments.' ) ); ?></description> <content:encoded><![CDATA[<?php echo get_the_password_form(); ?>]]></content:encoded> <?php else : ?> <description><![CDATA[<?php comment_text_rss(); ?>]]></description> <content:encoded><![CDATA[<?php comment_text(); ?>]]></content:encoded> <?php endif; // End if post_password_required(). ?> <?php /** * Fires at the end of each RSS2 comment feed item. * * @since 2.1.0 * * @param int $comment_id The ID of the comment being displayed. * @param int $comment_post_id The ID of the post the comment is connected to. */ do_action( 'commentrss2_item', $comment->comment_ID, $comment_post->ID ); ?> </item> <?php endwhile; ?> </channel> </rss> <?php /** * Object Cache API: WP_Object_Cache class * * @package WordPress * @subpackage Cache * @since 5.4.0 */ /** * Core class that implements an object cache. * * The WordPress Object Cache is used to save on trips to the database. The * Object Cache stores all of the cache data to memory and makes the cache * contents available by using a key, which is used to name and later retrieve * the cache contents. * * The Object Cache can be replaced by other caching mechanisms by placing files * in the wp-content folder which is looked at in wp-settings. If that file * exists, then this file will not be included. * * @since 2.0.0 */ #[AllowDynamicProperties] class WP_Object_Cache { /** * Holds the cached objects. * * @since 2.0.0 * @var array */ private $cache = array(); /** * The amount of times the cache data was already stored in the cache. * * @since 2.5.0 * @var int */ public $cache_hits = 0; /** * Amount of times the cache did not have the request in cache. * * @since 2.0.0 * @var int */ public $cache_misses = 0; /** * List of global cache groups. * * @since 3.0.0 * @var string[] */ protected $global_groups = array(); /** * The blog prefix to prepend to keys in non-global groups. * * @since 3.5.0 * @var string */ private $blog_prefix; /** * Holds the value of is_multisite(). * * @since 3.5.0 * @var bool */ private $multisite; /** * Sets up object properties. * * @since 2.0.8 */ public function __construct() { $this->multisite = is_multisite(); $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : ''; } /** * Makes private properties readable for backward compatibility. * * @since 4.0.0 * * @param string $name Property to get. * @return mixed Property. */ public function __get( $name ) { return $this->$name; } /** * Makes private properties settable for backward compatibility. * * @since 4.0.0 * * @param string $name Property to set. * @param mixed $value Property value. */ public function __set( $name, $value ) { $this->$name = $value; } /** * Makes private properties checkable for backward compatibility. * * @since 4.0.0 * * @param string $name Property to check if set. * @return bool Whether the property is set. */ public function __isset( $name ) { return isset( $this->$name ); } /** * Makes private properties un-settable for backward compatibility. * * @since 4.0.0 * * @param string $name Property to unset. */ public function __unset( $name ) { unset( $this->$name ); } /** * Serves as a utility function to determine whether a key is valid. * * @since 6.1.0 * * @param int|string $key Cache key to check for validity. * @return bool Whether the key is valid. */ protected function is_valid_key( $key ) { if ( is_int( $key ) ) { return true; } if ( is_string( $key ) && trim( $key ) !== '' ) { return true; } $type = gettype( $key ); if ( ! function_exists( '__' ) ) { wp_load_translations_early(); } $message = is_string( $key ) ? __( 'Cache key must not be an empty string.' ) /* translators: %s: The type of the given cache key. */ : sprintf( __( 'Cache key must be an integer or a non-empty string, %s given.' ), $type ); _doing_it_wrong( sprintf( '%s::%s', __CLASS__, debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 )[1]['function'] ), $message, '6.1.0' ); return false; } /** * Serves as a utility function to determine whether a key exists in the cache. * * @since 3.4.0 * * @param int|string $key Cache key to check for existence. * @param string $group Cache group for the key existence check. * @return bool Whether the key exists in the cache for the given group. */ protected function _exists( $key, $group ) { return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) ); } /** * Adds data to the cache if it doesn't already exist. * * @since 2.0.0 * * @uses WP_Object_Cache::_exists() Checks to see if the cache already has data. * @uses WP_Object_Cache::set() Sets the data after the checking the cache * contents existence. * * @param int|string $key What to call the contents in the cache. * @param mixed $data The contents to store in the cache. * @param string $group Optional. Where to group the cache contents. Default 'default'. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool True on success, false if cache key and group already exist. */ public function add( $key, $data, $group = 'default', $expire = 0 ) { if ( wp_suspend_cache_addition() ) { return false; } if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } $id = $key; if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $id = $this->blog_prefix . $key; } if ( $this->_exists( $id, $group ) ) { return false; } return $this->set( $key, $data, $group, (int) $expire ); } /** * Adds multiple values to the cache in one call. * * @since 6.0.0 * * @param array $data Array of keys and values to be added. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool[] Array of return values, grouped by key. Each value is either * true on success, or false if cache key and group already exist. */ public function add_multiple( array $data, $group = '', $expire = 0 ) { $values = array(); foreach ( $data as $key => $value ) { $values[ $key ] = $this->add( $key, $value, $group, $expire ); } return $values; } /** * Replaces the contents in the cache, if contents already exist. * * @since 2.0.0 * * @see WP_Object_Cache::set() * * @param int|string $key What to call the contents in the cache. * @param mixed $data The contents to store in the cache. * @param string $group Optional. Where to group the cache contents. Default 'default'. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool True if contents were replaced, false if original value does not exist. */ public function replace( $key, $data, $group = 'default', $expire = 0 ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } $id = $key; if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $id = $this->blog_prefix . $key; } if ( ! $this->_exists( $id, $group ) ) { return false; } return $this->set( $key, $data, $group, (int) $expire ); } /** * Sets the data contents into the cache. * * The cache contents are grouped by the $group parameter followed by the * $key. This allows for duplicate IDs in unique groups. Therefore, naming of * the group should be used with care and should follow normal function * naming guidelines outside of core WordPress usage. * * The $expire parameter is not used, because the cache will automatically * expire for each time a page is accessed and PHP finishes. The method is * more for cache plugins which use files. * * @since 2.0.0 * @since 6.1.0 Returns false if cache key is invalid. * * @param int|string $key What to call the contents in the cache. * @param mixed $data The contents to store in the cache. * @param string $group Optional. Where to group the cache contents. Default 'default'. * @param int $expire Optional. Not used. * @return bool True if contents were set, false if key is invalid. */ public function set( $key, $data, $group = 'default', $expire = 0 ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $key = $this->blog_prefix . $key; } if ( is_object( $data ) ) { $data = clone $data; } $this->cache[ $group ][ $key ] = $data; return true; } /** * Sets multiple values to the cache in one call. * * @since 6.0.0 * * @param array $data Array of key and value to be set. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @param int $expire Optional. When to expire the cache contents, in seconds. * Default 0 (no expiration). * @return bool[] Array of return values, grouped by key. Each value is always true. */ public function set_multiple( array $data, $group = '', $expire = 0 ) { $values = array(); foreach ( $data as $key => $value ) { $values[ $key ] = $this->set( $key, $value, $group, $expire ); } return $values; } /** * Retrieves the cache contents, if it exists. * * The contents will be first attempted to be retrieved by searching by the * key in the cache group. If the cache is hit (success) then the contents * are returned. * * On failure, the number of cache misses will be incremented. * * @since 2.0.0 * * @param int|string $key The key under which the cache contents are stored. * @param string $group Optional. Where the cache contents are grouped. Default 'default'. * @param bool $force Optional. Unused. Whether to force an update of the local cache * from the persistent cache. Default false. * @param bool $found Optional. Whether the key was found in the cache (passed by reference). * Disambiguates a return of false, a storable value. Default null. * @return mixed|false The cache contents on success, false on failure to retrieve contents. */ public function get( $key, $group = 'default', $force = false, &$found = null ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $key = $this->blog_prefix . $key; } if ( $this->_exists( $key, $group ) ) { $found = true; $this->cache_hits += 1; if ( is_object( $this->cache[ $group ][ $key ] ) ) { return clone $this->cache[ $group ][ $key ]; } else { return $this->cache[ $group ][ $key ]; } } $found = false; $this->cache_misses += 1; return false; } /** * Retrieves multiple values from the cache in one call. * * @since 5.5.0 * * @param array $keys Array of keys under which the cache contents are stored. * @param string $group Optional. Where the cache contents are grouped. Default 'default'. * @param bool $force Optional. Whether to force an update of the local cache * from the persistent cache. Default false. * @return array Array of return values, grouped by key. Each value is either * the cache contents on success, or false on failure. */ public function get_multiple( $keys, $group = 'default', $force = false ) { $values = array(); foreach ( $keys as $key ) { $values[ $key ] = $this->get( $key, $group, $force ); } return $values; } /** * Removes the contents of the cache key in the group. * * If the cache key does not exist in the group, then nothing will happen. * * @since 2.0.0 * * @param int|string $key What the contents in the cache are called. * @param string $group Optional. Where the cache contents are grouped. Default 'default'. * @param bool $deprecated Optional. Unused. Default false. * @return bool True on success, false if the contents were not deleted. */ public function delete( $key, $group = 'default', $deprecated = false ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $key = $this->blog_prefix . $key; } if ( ! $this->_exists( $key, $group ) ) { return false; } unset( $this->cache[ $group ][ $key ] ); return true; } /** * Deletes multiple values from the cache in one call. * * @since 6.0.0 * * @param array $keys Array of keys to be deleted. * @param string $group Optional. Where the cache contents are grouped. Default empty. * @return bool[] Array of return values, grouped by key. Each value is either * true on success, or false if the contents were not deleted. */ public function delete_multiple( array $keys, $group = '' ) { $values = array(); foreach ( $keys as $key ) { $values[ $key ] = $this->delete( $key, $group ); } return $values; } /** * Increments numeric cache item's value. * * @since 3.3.0 * * @param int|string $key The cache key to increment. * @param int $offset Optional. The amount by which to increment the item's value. * Default 1. * @param string $group Optional. The group the key is in. Default 'default'. * @return int|false The item's new value on success, false on failure. */ public function incr( $key, $offset = 1, $group = 'default' ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $key = $this->blog_prefix . $key; } if ( ! $this->_exists( $key, $group ) ) { return false; } if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) { $this->cache[ $group ][ $key ] = 0; } $offset = (int) $offset; $this->cache[ $group ][ $key ] += $offset; if ( $this->cache[ $group ][ $key ] < 0 ) { $this->cache[ $group ][ $key ] = 0; } return $this->cache[ $group ][ $key ]; } /** * Decrements numeric cache item's value. * * @since 3.3.0 * * @param int|string $key The cache key to decrement. * @param int $offset Optional. The amount by which to decrement the item's value. * Default 1. * @param string $group Optional. The group the key is in. Default 'default'. * @return int|false The item's new value on success, false on failure. */ public function decr( $key, $offset = 1, $group = 'default' ) { if ( ! $this->is_valid_key( $key ) ) { return false; } if ( empty( $group ) ) { $group = 'default'; } if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) { $key = $this->blog_prefix . $key; } if ( ! $this->_exists( $key, $group ) ) { return false; } if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) { $this->cache[ $group ][ $key ] = 0; } $offset = (int) $offset; $this->cache[ $group ][ $key ] -= $offset; if ( $this->cache[ $group ][ $key ] < 0 ) { $this->cache[ $group ][ $key ] = 0; } return $this->cache[ $group ][ $key ]; } /** * Clears the object cache of all data. * * @since 2.0.0 * * @return true Always returns true. */ public function flush() { $this->cache = array(); return true; } /** * Removes all cache items in a group. * * @since 6.1.0 * * @param string $group Name of group to remove from cache. * @return true Always returns true. */ public function flush_group( $group ) { unset( $this->cache[ $group ] ); return true; } /** * Sets the list of global cache groups. * * @since 3.0.0 * * @param string|string[] $groups List of groups that are global. */ public function add_global_groups( $groups ) { $groups = (array) $groups; $groups = array_fill_keys( $groups, true ); $this->global_groups = array_merge( $this->global_groups, $groups ); } /** * Switches the internal blog ID. * * This changes the blog ID used to create keys in blog specific groups. * * @since 3.5.0 * * @param int $blog_id Blog ID. */ public function switch_to_blog( $blog_id ) { $blog_id = (int) $blog_id; $this->blog_prefix = $this->multisite ? $blog_id . ':' : ''; } /** * Resets cache keys. * * @since 3.0.0 * * @deprecated 3.5.0 Use WP_Object_Cache::switch_to_blog() * @see switch_to_blog() */ public function reset() { _deprecated_function( __FUNCTION__, '3.5.0', 'WP_Object_Cache::switch_to_blog()' ); // Clear out non-global caches since the blog ID has changed. foreach ( array_keys( $this->cache ) as $group ) { if ( ! isset( $this->global_groups[ $group ] ) ) { unset( $this->cache[ $group ] ); } } } /** * Echoes the stats of the caching. * * Gives the cache hits, and cache misses. Also prints every cached group, * key and the data. * * @since 2.0.0 */ public function stats() { echo '<p>'; echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />"; echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />"; echo '</p>'; echo '<ul>'; foreach ( $this->cache as $group => $cache ) { echo '<li><strong>Group:</strong> ' . esc_html( $group ) . ' - ( ' . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>'; } echo '</ul>'; } } [09-Oct-2025 10:18:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_HTTP_Response" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/class-wp-rest-response.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/class-wp-rest-response.php on line 17 [09-Oct-2025 10:19:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-format-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-format-search-handler.php on line 17 [09-Oct-2025 10:19:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-format-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-format-search-handler.php on line 17 [09-Oct-2025 10:19:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-search-handler.php on line 17 [09-Oct-2025 10:19:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-post-search-handler.php on line 17 [09-Oct-2025 10:19:43 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-term-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-term-search-handler.php on line 17 [09-Oct-2025 10:19:44 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Search_Handler" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-term-search-handler.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/search/class-wp-rest-term-search-handler.php on line 17 <?php /** * REST API: WP_REST_Post_Format_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class representing a search handler for post formats in the REST API. * * @since 5.6.0 * * @see WP_REST_Search_Handler */ class WP_REST_Post_Format_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.6.0 */ public function __construct() { $this->type = 'post-format'; } /** * Searches the post formats for a given search request. * * @since 5.6.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type string[] $ids Array containing slugs for the matching post formats. * @type int $total Total count for the matching search results. * } */ public function search_items( WP_REST_Request $request ) { $format_strings = get_post_format_strings(); $format_slugs = array_keys( $format_strings ); $query_args = array(); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } /** * Filters the query arguments for a REST API post format search request. * * Enables adding extra arguments or setting defaults for a post format search request. * * @since 5.6.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_post_format_search_query', $query_args, $request ); $found_ids = array(); foreach ( $format_slugs as $format_slug ) { if ( ! empty( $query_args['search'] ) ) { $format_string = get_post_format_string( $format_slug ); $format_slug_match = stripos( $format_slug, $query_args['search'] ) !== false; $format_string_match = stripos( $format_string, $query_args['search'] ) !== false; if ( ! $format_slug_match && ! $format_string_match ) { continue; } } $format_link = get_post_format_link( $format_slug ); if ( $format_link ) { $found_ids[] = $format_slug; } } $page = (int) $request['page']; $per_page = (int) $request['per_page']; return array( self::RESULT_IDS => array_slice( $found_ids, ( $page - 1 ) * $per_page, $per_page ), self::RESULT_TOTAL => count( $found_ids ), ); } /** * Prepares the search result for a given post format. * * @since 5.6.0 * * @param string $id Item ID, the post format slug. * @param array $fields Fields to include for the item. * @return array { * Associative array containing fields for the post format based on the `$fields` parameter. * * @type string $id Optional. Post format slug. * @type string $title Optional. Post format name. * @type string $url Optional. Post format permalink URL. * @type string $type Optional. String 'post-format'. *} */ public function prepare_item( $id, array $fields ) { $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_post_format_string( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_post_format_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } return $data; } /** * Prepares links for the search result. * * @since 5.6.0 * * @param string $id Item ID, the post format slug. * @return array Links for the given item. */ public function prepare_item_links( $id ) { return array(); } } <?php /** * REST API: WP_REST_Term_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class representing a search handler for terms in the REST API. * * @since 5.6.0 * * @see WP_REST_Search_Handler */ class WP_REST_Term_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.6.0 */ public function __construct() { $this->type = 'term'; $this->subtypes = array_values( get_taxonomies( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ); } /** * Searches terms for a given search request. * * @since 5.6.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type int[] $ids Found term IDs. * @type string|int|WP_Error $total Numeric string containing the number of terms in that * taxonomy, 0 if there are no results, or WP_Error if * the requested taxonomy does not exist. * } */ public function search_items( WP_REST_Request $request ) { $taxonomies = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $taxonomies, true ) ) { $taxonomies = $this->subtypes; } $page = (int) $request['page']; $per_page = (int) $request['per_page']; $query_args = array( 'taxonomy' => $taxonomies, 'hide_empty' => false, 'offset' => ( $page - 1 ) * $per_page, 'number' => $per_page, ); if ( ! empty( $request['search'] ) ) { $query_args['search'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['exclude'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['include'] = $request['include']; } /** * Filters the query arguments for a REST API term search request. * * Enables adding extra arguments or setting defaults for a term search request. * * @since 5.6.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_term_search_query', $query_args, $request ); $query = new WP_Term_Query(); $found_terms = $query->query( $query_args ); $found_ids = wp_list_pluck( $found_terms, 'term_id' ); unset( $query_args['offset'], $query_args['number'] ); $total = wp_count_terms( $query_args ); // wp_count_terms() can return a falsey value when the term has no children. if ( ! $total ) { $total = 0; } return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } /** * Prepares the search result for a given term ID. * * @since 5.6.0 * * @param int $id Term ID. * @param array $fields Fields to include for the term. * @return array { * Associative array containing fields for the term based on the `$fields` parameter. * * @type int $id Optional. Term ID. * @type string $title Optional. Term name. * @type string $url Optional. Term permalink URL. * @type string $type Optional. Term taxonomy name. * } */ public function prepare_item( $id, array $fields ) { $term = get_term( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $id; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TITLE ] = $term->name; } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_term_link( $id ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $term->taxonomy; } return $data; } /** * Prepares links for the search result of a given ID. * * @since 5.6.0 * * @param int $id Item ID. * @return array[] Array of link arrays for the given item. */ public function prepare_item_links( $id ) { $term = get_term( $id ); $links = array(); $item_route = rest_get_route_for_term( $term ); if ( $item_route ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $term->taxonomy ) ), ); return $links; } } <?php /** * REST API: WP_REST_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core base class representing a search handler for an object type in the REST API. * * @since 5.0.0 */ #[AllowDynamicProperties] abstract class WP_REST_Search_Handler { /** * Field containing the IDs in the search result. */ const RESULT_IDS = 'ids'; /** * Field containing the total count in the search result. */ const RESULT_TOTAL = 'total'; /** * Object type managed by this search handler. * * @since 5.0.0 * @var string */ protected $type = ''; /** * Object subtypes managed by this search handler. * * @since 5.0.0 * @var string[] */ protected $subtypes = array(); /** * Gets the object type managed by this search handler. * * @since 5.0.0 * * @return string Object type identifier. */ public function get_type() { return $this->type; } /** * Gets the object subtypes managed by this search handler. * * @since 5.0.0 * * @return string[] Array of object subtype identifiers. */ public function get_subtypes() { return $this->subtypes; } /** * Searches the object type content for a given search request. * * @since 5.0.0 * * @param WP_REST_Request $request Full REST request. * @return array Associative array containing an `WP_REST_Search_Handler::RESULT_IDS` containing * an array of found IDs and `WP_REST_Search_Handler::RESULT_TOTAL` containing the * total count for the matching search results. */ abstract public function search_items( WP_REST_Request $request ); /** * Prepares the search result for a given ID. * * @since 5.0.0 * @since 5.6.0 The `$id` parameter can accept a string. * * @param int|string $id Item ID. * @param array $fields Fields to include for the item. * @return array Associative array containing all fields for the item. */ abstract public function prepare_item( $id, array $fields ); /** * Prepares links for the search result of a given ID. * * @since 5.0.0 * @since 5.6.0 The `$id` parameter can accept a string. * * @param int|string $id Item ID. * @return array Links for the given item. */ abstract public function prepare_item_links( $id ); } <?php /** * REST API: WP_REST_Post_Search_Handler class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core class representing a search handler for posts in the REST API. * * @since 5.0.0 * * @see WP_REST_Search_Handler */ class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler { /** * Constructor. * * @since 5.0.0 */ public function __construct() { $this->type = 'post'; // Support all public post types except attachments. $this->subtypes = array_diff( array_values( get_post_types( array( 'public' => true, 'show_in_rest' => true, ), 'names' ) ), array( 'attachment' ) ); } /** * Searches posts for a given search request. * * @since 5.0.0 * * @param WP_REST_Request $request Full REST request. * @return array { * Associative array containing found IDs and total count for the matching search results. * * @type int[] $ids Array containing the matching post IDs. * @type int $total Total count for the matching search results. * } */ public function search_items( WP_REST_Request $request ) { // Get the post types to search for the current request. $post_types = $request[ WP_REST_Search_Controller::PROP_SUBTYPE ]; if ( in_array( WP_REST_Search_Controller::TYPE_ANY, $post_types, true ) ) { $post_types = $this->subtypes; } $query_args = array( 'post_type' => $post_types, 'post_status' => 'publish', 'paged' => (int) $request['page'], 'posts_per_page' => (int) $request['per_page'], 'ignore_sticky_posts' => true, ); if ( ! empty( $request['search'] ) ) { $query_args['s'] = $request['search']; } if ( ! empty( $request['exclude'] ) ) { $query_args['post__not_in'] = $request['exclude']; } if ( ! empty( $request['include'] ) ) { $query_args['post__in'] = $request['include']; } /** * Filters the query arguments for a REST API post search request. * * Enables adding extra arguments or setting defaults for a post search request. * * @since 5.1.0 * * @param array $query_args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ $query_args = apply_filters( 'rest_post_search_query', $query_args, $request ); $query = new WP_Query(); $posts = $query->query( $query_args ); // Querying the whole post object will warm the object cache, avoiding an extra query per result. $found_ids = wp_list_pluck( $posts, 'ID' ); $total = $query->found_posts; return array( self::RESULT_IDS => $found_ids, self::RESULT_TOTAL => $total, ); } /** * Prepares the search result for a given post ID. * * @since 5.0.0 * * @param int $id Post ID. * @param array $fields Fields to include for the post. * @return array { * Associative array containing fields for the post based on the `$fields` parameter. * * @type int $id Optional. Post ID. * @type string $title Optional. Post title. * @type string $url Optional. Post permalink URL. * @type string $type Optional. Post type. * } */ public function prepare_item( $id, array $fields ) { $post = get_post( $id ); $data = array(); if ( in_array( WP_REST_Search_Controller::PROP_ID, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_ID ] = (int) $post->ID; } if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) { if ( post_type_supports( $post->post_type, 'title' ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data[ WP_REST_Search_Controller::PROP_TITLE ] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } else { $data[ WP_REST_Search_Controller::PROP_TITLE ] = ''; } } if ( in_array( WP_REST_Search_Controller::PROP_URL, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_URL ] = get_permalink( $post->ID ); } if ( in_array( WP_REST_Search_Controller::PROP_TYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_TYPE ] = $this->type; } if ( in_array( WP_REST_Search_Controller::PROP_SUBTYPE, $fields, true ) ) { $data[ WP_REST_Search_Controller::PROP_SUBTYPE ] = $post->post_type; } return $data; } /** * Prepares links for the search result of a given ID. * * @since 5.0.0 * * @param int $id Item ID. * @return array Links for the given item. */ public function prepare_item_links( $id ) { $post = get_post( $id ); $links = array(); $item_route = rest_get_route_for_post( $post ); if ( ! empty( $item_route ) ) { $links['self'] = array( 'href' => rest_url( $item_route ), 'embeddable' => true, ); } $links['about'] = array( 'href' => rest_url( 'wp/v2/types/' . $post->post_type ), ); return $links; } /** * Overwrites the default protected and private title format. * * By default, WordPress will show password protected or private posts with a title of * "Protected: %s" or "Private: %s", as the REST API communicates the status of a post * in a machine-readable format, we remove the prefix. * * @since 5.0.0 * * @return string Title format. */ public function protected_title_format() { return '%s'; } /** * Attempts to detect the route to access a single item. * * @since 5.0.0 * @deprecated 5.5.0 Use rest_get_route_for_post() * @see rest_get_route_for_post() * * @param WP_Post $post Post object. * @return string REST route relative to the REST base URI, or empty string if unknown. */ protected function detect_rest_item_route( $post ) { _deprecated_function( __METHOD__, '5.5.0', 'rest_get_route_for_post()' ); return rest_get_route_for_post( $post ); } } [09-Oct-2025 10:19:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-comment-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-comment-meta-fields.php on line 17 [09-Oct-2025 10:19:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-comment-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-comment-meta-fields.php on line 17 [09-Oct-2025 10:19:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-post-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-post-meta-fields.php on line 17 [09-Oct-2025 10:19:32 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-post-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-post-meta-fields.php on line 17 [09-Oct-2025 10:19:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-term-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-term-meta-fields.php on line 17 [09-Oct-2025 10:19:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-term-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-term-meta-fields.php on line 17 [09-Oct-2025 10:19:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-user-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-user-meta-fields.php on line 17 [09-Oct-2025 10:19:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Meta_Fields" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-user-meta-fields.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/fields/class-wp-rest-user-meta-fields.php on line 17 <?php /** * REST API: WP_REST_User_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for users via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_User_Meta_Fields extends WP_REST_Meta_Fields { /** * Retrieves the user meta type. * * @since 4.7.0 * * @return string The user meta type. */ protected function get_meta_type() { return 'user'; } /** * Retrieves the user meta subtype. * * @since 4.9.8 * * @return string 'user' There are no subtypes. */ protected function get_meta_subtype() { return 'user'; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @return string The user REST field type. */ public function get_rest_field_type() { return 'user'; } } <?php /** * REST API: WP_REST_Comment_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to manage comment meta via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Comment_Meta_Fields extends WP_REST_Meta_Fields { /** * Retrieves the comment type for comment meta. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'comment'; } /** * Retrieves the comment meta subtype. * * @since 4.9.8 * * @return string 'comment' There are no subtypes. */ protected function get_meta_subtype() { return 'comment'; } /** * Retrieves the type for register_rest_field() in the context of comments. * * @since 4.7.0 * * @return string The REST field type. */ public function get_rest_field_type() { return 'comment'; } } <?php /** * REST API: WP_REST_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to manage meta values for an object via the REST API. * * @since 4.7.0 */ #[AllowDynamicProperties] abstract class WP_REST_Meta_Fields { /** * Retrieves the object meta type. * * @since 4.7.0 * * @return string One of 'post', 'comment', 'term', 'user', or anything * else supported by `_get_meta_table()`. */ abstract protected function get_meta_type(); /** * Retrieves the object meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return ''; } /** * Retrieves the object type for register_rest_field(). * * @since 4.7.0 * * @return string The REST field type, such as post type name, taxonomy name, 'comment', or `user`. */ abstract protected function get_rest_field_type(); /** * Registers the meta field. * * @since 4.7.0 * @deprecated 5.6.0 * * @see register_rest_field() */ public function register_field() { _deprecated_function( __METHOD__, '5.6.0' ); register_rest_field( $this->get_rest_field_type(), 'meta', array( 'get_callback' => array( $this, 'get_value' ), 'update_callback' => array( $this, 'update_value' ), 'schema' => $this->get_field_schema(), ) ); } /** * Retrieves the meta field value. * * @since 4.7.0 * * @param int $object_id Object ID to fetch meta for. * @param WP_REST_Request $request Full details about the request. * @return array Array containing the meta values keyed by name. */ public function get_value( $object_id, $request ) { $fields = $this->get_registered_fields(); $response = array(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; $all_values = get_metadata( $this->get_meta_type(), $object_id, $meta_key, false ); if ( $args['single'] ) { if ( empty( $all_values ) ) { $value = $args['schema']['default']; } else { $value = $all_values[0]; } $value = $this->prepare_value_for_response( $value, $request, $args ); } else { $value = array(); if ( is_array( $all_values ) ) { foreach ( $all_values as $row ) { $value[] = $this->prepare_value_for_response( $row, $request, $args ); } } } $response[ $name ] = $value; } return $response; } /** * Prepares a meta value for a response. * * This is required because some native types cannot be stored correctly * in the database, such as booleans. We need to cast back to the relevant * type before passing back to JSON. * * @since 4.7.0 * * @param mixed $value Meta value to prepare. * @param WP_REST_Request $request Current request object. * @param array $args Options for the field. * @return mixed Prepared value. */ protected function prepare_value_for_response( $value, $request, $args ) { if ( ! empty( $args['prepare_callback'] ) ) { $value = call_user_func( $args['prepare_callback'], $value, $request, $args ); } return $value; } /** * Updates meta values. * * @since 4.7.0 * * @param array $meta Array of meta parsed from the request. * @param int $object_id Object ID to fetch meta for. * @return null|WP_Error Null on success, WP_Error object on failure. */ public function update_value( $meta, $object_id ) { $fields = $this->get_registered_fields(); $error = new WP_Error(); foreach ( $fields as $meta_key => $args ) { $name = $args['name']; if ( ! array_key_exists( $name, $meta ) ) { continue; } $value = $meta[ $name ]; /* * A null value means reset the field, which is essentially deleting it * from the database and then relying on the default value. * * Non-single meta can also be removed by passing an empty array. */ if ( is_null( $value ) || ( array() === $value && ! $args['single'] ) ) { $args = $this->get_registered_fields()[ $meta_key ]; if ( $args['single'] ) { $current = get_metadata( $this->get_meta_type(), $object_id, $meta_key, true ); if ( is_wp_error( rest_validate_value_from_schema( $current, $args['schema'] ) ) ) { $error->add( 'rest_invalid_stored_value', /* translators: %s: Custom field key. */ sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } } $result = $this->delete_meta_value( $object_id, $meta_key, $name ); if ( is_wp_error( $result ) ) { $error->merge_from( $result ); } continue; } if ( ! $args['single'] && is_array( $value ) && count( array_filter( $value, 'is_null' ) ) ) { $error->add( 'rest_invalid_stored_value', /* translators: %s: Custom field key. */ sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); continue; } $is_valid = rest_validate_value_from_schema( $value, $args['schema'], 'meta.' . $name ); if ( is_wp_error( $is_valid ) ) { $is_valid->add_data( array( 'status' => 400 ) ); $error->merge_from( $is_valid ); continue; } $value = rest_sanitize_value_from_schema( $value, $args['schema'] ); if ( $args['single'] ) { $result = $this->update_meta_value( $object_id, $meta_key, $name, $value ); } else { $result = $this->update_multi_meta_value( $object_id, $meta_key, $name, $value ); } if ( is_wp_error( $result ) ) { $error->merge_from( $result ); continue; } } if ( $error->has_errors() ) { return $error; } return null; } /** * Deletes a meta value for an object. * * @since 4.7.0 * * @param int $object_id Object ID the field belongs to. * @param string $meta_key Key for the field. * @param string $name Name for the field that is exposed in the REST API. * @return true|WP_Error True if meta field is deleted, WP_Error otherwise. */ protected function delete_meta_value( $object_id, $meta_key, $name ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "delete_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_delete', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( null === get_metadata_raw( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return true; } if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ) ) ) { return new WP_Error( 'rest_meta_database_error', __( 'Could not delete meta value from database.' ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } /** * Updates multiple meta values for an object. * * Alters the list of values in the database to match the list of provided values. * * @since 4.7.0 * @since 6.7.0 Stores values into DB even if provided registered default value. * * @param int $object_id Object ID to update. * @param string $meta_key Key for the custom field. * @param string $name Name for the field that is exposed in the REST API. * @param array $values List of values to update to. * @return true|WP_Error True if meta fields are updated, WP_Error otherwise. */ protected function update_multi_meta_value( $object_id, $meta_key, $name, $values ) { $meta_type = $this->get_meta_type(); if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } $current_values = get_metadata_raw( $meta_type, $object_id, $meta_key, false ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( ! is_array( $current_values ) ) { $current_values = array(); } $to_remove = $current_values; $to_add = $values; foreach ( $to_add as $add_key => $value ) { $remove_keys = array_keys( array_filter( $current_values, function ( $stored_value ) use ( $meta_key, $subtype, $value ) { return $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $value ); } ) ); if ( empty( $remove_keys ) ) { continue; } if ( count( $remove_keys ) > 1 ) { // To remove, we need to remove first, then add, so don't touch. continue; } $remove_key = $remove_keys[0]; unset( $to_remove[ $remove_key ] ); unset( $to_add[ $add_key ] ); } /* * `delete_metadata` removes _all_ instances of the value, so only call once. Otherwise, * `delete_metadata` will return false for subsequent calls of the same value. * Use serialization to produce a predictable string that can be used by array_unique. */ $to_remove = array_map( 'maybe_unserialize', array_unique( array_map( 'maybe_serialize', $to_remove ) ) ); foreach ( $to_remove as $value ) { if ( ! delete_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } foreach ( $to_add as $value ) { if ( ! add_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } } return true; } /** * Updates a meta value for an object. * * @since 4.7.0 * @since 6.7.0 Stores values into DB even if provided registered default value. * * @param int $object_id Object ID to update. * @param string $meta_key Key for the custom field. * @param string $name Name for the field that is exposed in the REST API. * @param mixed $value Updated value. * @return true|WP_Error True if the meta field was updated, WP_Error otherwise. */ protected function update_meta_value( $object_id, $meta_key, $name, $value ) { $meta_type = $this->get_meta_type(); // Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false. $old_value = get_metadata_raw( $meta_type, $object_id, $meta_key ); $subtype = get_object_subtype( $meta_type, $object_id ); if ( is_array( $old_value ) && 1 === count( $old_value ) && $this->is_meta_value_same_as_stored_value( $meta_key, $subtype, $old_value[0], $value ) ) { return true; } if ( ! current_user_can( "edit_{$meta_type}_meta", $object_id, $meta_key ) ) { return new WP_Error( 'rest_cannot_update', /* translators: %s: Custom field key. */ sprintf( __( 'Sorry, you are not allowed to edit the %s custom field.' ), $name ), array( 'key' => $name, 'status' => rest_authorization_required_code(), ) ); } if ( ! update_metadata( $meta_type, $object_id, wp_slash( $meta_key ), wp_slash( $value ) ) ) { return new WP_Error( 'rest_meta_database_error', /* translators: %s: Custom field key. */ sprintf( __( 'Could not update the meta value of %s in database.' ), $meta_key ), array( 'key' => $name, 'status' => WP_Http::INTERNAL_SERVER_ERROR, ) ); } return true; } /** * Checks if the user provided value is equivalent to a stored value for the given meta key. * * @since 5.5.0 * * @param string $meta_key The meta key being checked. * @param string $subtype The object subtype. * @param mixed $stored_value The currently stored value retrieved from get_metadata(). * @param mixed $user_value The value provided by the user. * @return bool */ protected function is_meta_value_same_as_stored_value( $meta_key, $subtype, $stored_value, $user_value ) { $args = $this->get_registered_fields()[ $meta_key ]; $sanitized = sanitize_meta( $meta_key, $user_value, $this->get_meta_type(), $subtype ); if ( in_array( $args['type'], array( 'string', 'number', 'integer', 'boolean' ), true ) ) { // The return value of get_metadata will always be a string for scalar types. $sanitized = (string) $sanitized; } return $sanitized === $stored_value; } /** * Retrieves all the registered meta fields. * * @since 4.7.0 * * @return array Registered fields. */ protected function get_registered_fields() { $registered = array(); $meta_type = $this->get_meta_type(); $meta_subtype = $this->get_meta_subtype(); $meta_keys = get_registered_meta_keys( $meta_type ); if ( ! empty( $meta_subtype ) ) { $meta_keys = array_merge( $meta_keys, get_registered_meta_keys( $meta_type, $meta_subtype ) ); } foreach ( $meta_keys as $name => $args ) { if ( empty( $args['show_in_rest'] ) ) { continue; } $rest_args = array(); if ( is_array( $args['show_in_rest'] ) ) { $rest_args = $args['show_in_rest']; } $default_args = array( 'name' => $name, 'single' => $args['single'], 'type' => ! empty( $args['type'] ) ? $args['type'] : null, 'schema' => array(), 'prepare_callback' => array( $this, 'prepare_value' ), ); $default_schema = array( 'type' => $default_args['type'], 'title' => empty( $args['label'] ) ? '' : $args['label'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); $rest_args = array_merge( $default_args, $rest_args ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); $type = ! empty( $rest_args['type'] ) ? $rest_args['type'] : null; $type = ! empty( $rest_args['schema']['type'] ) ? $rest_args['schema']['type'] : $type; if ( null === $rest_args['schema']['default'] ) { $rest_args['schema']['default'] = static::get_empty_value_for_type( $type ); } $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); if ( ! in_array( $type, array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { continue; } if ( empty( $rest_args['single'] ) ) { $rest_args['schema'] = array( 'type' => 'array', 'items' => $rest_args['schema'], ); } $registered[ $name ] = $rest_args; } return $registered; } /** * Retrieves the object's meta schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Field schema data. */ public function get_field_schema() { $fields = $this->get_registered_fields(); $schema = array( 'description' => __( 'Meta fields.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'properties' => array(), 'arg_options' => array( 'sanitize_callback' => null, 'validate_callback' => array( $this, 'check_meta_is_array' ), ), ); foreach ( $fields as $args ) { $schema['properties'][ $args['name'] ] = $args['schema']; } return $schema; } /** * Prepares a meta value for output. * * Default preparation for meta fields. Override by passing the * `prepare_callback` in your `show_in_rest` options. * * @since 4.7.0 * * @param mixed $value Meta value from the database. * @param WP_REST_Request $request Request object. * @param array $args REST-specific options for the meta key. * @return mixed Value prepared for output. If a non-JsonSerializable object, null. */ public static function prepare_value( $value, $request, $args ) { if ( $args['single'] ) { $schema = $args['schema']; } else { $schema = $args['schema']['items']; } if ( '' === $value && in_array( $schema['type'], array( 'boolean', 'integer', 'number' ), true ) ) { $value = static::get_empty_value_for_type( $schema['type'] ); } if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { return null; } return rest_sanitize_value_from_schema( $value, $schema ); } /** * Check the 'meta' value of a request is an associative array. * * @since 4.7.0 * * @param mixed $value The meta value submitted in the request. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter name. * @return array|false The meta array, if valid, false otherwise. */ public function check_meta_is_array( $value, $request, $param ) { if ( ! is_array( $value ) ) { return false; } return $value; } /** * Recursively add additionalProperties = false to all objects in a schema if no additionalProperties setting * is specified. * * This is needed to restrict properties of objects in meta values to only * registered items, as the REST API will allow additional properties by * default. * * @since 5.3.0 * @deprecated 5.6.0 Use rest_default_additional_properties_to_false() instead. * * @param array $schema The schema array. * @return array */ protected function default_additional_properties_to_false( $schema ) { _deprecated_function( __METHOD__, '5.6.0', 'rest_default_additional_properties_to_false()' ); return rest_default_additional_properties_to_false( $schema ); } /** * Gets the empty value for a schema type. * * @since 5.3.0 * * @param string $type The schema type. * @return mixed */ protected static function get_empty_value_for_type( $type ) { switch ( $type ) { case 'string': return ''; case 'boolean': return false; case 'integer': return 0; case 'number': return 0.0; case 'array': case 'object': return array(); default: return null; } } } <?php /** * REST API: WP_REST_Post_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for posts via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Post_Meta_Fields extends WP_REST_Meta_Fields { /** * Post type to register fields for. * * @since 4.7.0 * @var string */ protected $post_type; /** * Constructor. * * @since 4.7.0 * * @param string $post_type Post type to register fields for. */ public function __construct( $post_type ) { $this->post_type = $post_type; } /** * Retrieves the post meta type. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'post'; } /** * Retrieves the post meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return $this->post_type; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @see register_rest_field() * * @return string The REST field type. */ public function get_rest_field_type() { return $this->post_type; } } <?php /** * REST API: WP_REST_Term_Meta_Fields class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage meta values for terms via the REST API. * * @since 4.7.0 * * @see WP_REST_Meta_Fields */ class WP_REST_Term_Meta_Fields extends WP_REST_Meta_Fields { /** * Taxonomy to register fields for. * * @since 4.7.0 * @var string */ protected $taxonomy; /** * Constructor. * * @since 4.7.0 * * @param string $taxonomy Taxonomy to register fields for. */ public function __construct( $taxonomy ) { $this->taxonomy = $taxonomy; } /** * Retrieves the term meta type. * * @since 4.7.0 * * @return string The meta type. */ protected function get_meta_type() { return 'term'; } /** * Retrieves the term meta subtype. * * @since 4.9.8 * * @return string Subtype for the meta type, or empty string if no specific subtype. */ protected function get_meta_subtype() { return $this->taxonomy; } /** * Retrieves the type for register_rest_field(). * * @since 4.7.0 * * @return string The REST field type. */ public function get_rest_field_type() { return 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy; } } <?php /** * REST API: WP_REST_Block_Types_Controller class * * @package WordPress * @subpackage REST_API * @since 5.5.0 */ /** * Core class used to access block types via the REST API. * * @since 5.5.0 * * @see WP_REST_Controller */ class WP_REST_Block_Types_Controller extends WP_REST_Controller { const NAME_PATTERN = '^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$'; /** * Instance of WP_Block_Type_Registry. * * @since 5.5.0 * @var WP_Block_Type_Registry */ protected $block_registry; /** * Instance of WP_Block_Styles_Registry. * * @since 5.5.0 * @var WP_Block_Styles_Registry */ protected $style_registry; /** * Constructor. * * @since 5.5.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-types'; $this->block_registry = WP_Block_Type_Registry::get_instance(); $this->style_registry = WP_Block_Styles_Registry::get_instance(); } /** * Registers the routes for block types. * * @since 5.5.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<namespace>[a-zA-Z0-9_-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<namespace>[a-zA-Z0-9_-]+)/(?P<name>[a-zA-Z0-9_-]+)', array( 'args' => array( 'name' => array( 'description' => __( 'Block name.' ), 'type' => 'string', ), 'namespace' => array( 'description' => __( 'Block namespace.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read post block types. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { return $this->check_read_permission(); } /** * Retrieves all post block types, depending on user context. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $data = array(); $block_types = $this->block_registry->get_all_registered(); // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); $namespace = ''; if ( isset( $registered['namespace'] ) && ! empty( $request['namespace'] ) ) { $namespace = $request['namespace']; } foreach ( $block_types as $obj ) { if ( $namespace ) { list ( $block_namespace ) = explode( '/', $obj->name ); if ( $namespace !== $block_namespace ) { continue; } } $block_type = $this->prepare_item_for_response( $obj, $request ); $data[] = $this->prepare_response_for_collection( $block_type ); } return rest_ensure_response( $data ); } /** * Checks if a given request has access to read a block type. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $check = $this->check_read_permission(); if ( is_wp_error( $check ) ) { return $check; } $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); $block_type = $this->get_block( $block_name ); if ( is_wp_error( $block_type ) ) { return $block_type; } return true; } /** * Checks whether a given block type should be visible. * * @since 5.5.0 * * @return true|WP_Error True if the block type is visible, WP_Error otherwise. */ protected function check_read_permission() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_block_type_cannot_view', __( 'Sorry, you are not allowed to manage block types.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Get the block, if the name is valid. * * @since 5.5.0 * * @param string $name Block name. * @return WP_Block_Type|WP_Error Block type object if name is valid, WP_Error otherwise. */ protected function get_block( $name ) { $block_type = $this->block_registry->get_registered( $name ); if ( empty( $block_type ) ) { return new WP_Error( 'rest_block_type_invalid', __( 'Invalid block type.' ), array( 'status' => 404 ) ); } return $block_type; } /** * Retrieves a specific block type. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $block_name = sprintf( '%s/%s', $request['namespace'], $request['name'] ); $block_type = $this->get_block( $block_name ); if ( is_wp_error( $block_type ) ) { return $block_type; } $data = $this->prepare_item_for_response( $block_type, $request ); return rest_ensure_response( $data ); } /** * Prepares a block type object for serialization. * * @since 5.5.0 * @since 5.9.0 Renamed `$block_type` to `$item` to match parent class for PHP 8 named parameter support. * @since 6.3.0 Added `selectors` field. * @since 6.5.0 Added `view_script_module_ids` field. * * @param WP_Block_Type $item Block type data. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Block type data. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $block_type = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php */ return apply_filters( 'rest_prepare_block_type', new WP_REST_Response( array() ), $block_type, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'attributes', $fields ) ) { $data['attributes'] = $block_type->get_attributes(); } if ( rest_is_field_included( 'is_dynamic', $fields ) ) { $data['is_dynamic'] = $block_type->is_dynamic(); } $schema = $this->get_item_schema(); // Fields deprecated in WordPress 6.1, but left in the schema for backwards compatibility. $deprecated_fields = array( 'editor_script', 'script', 'view_script', 'editor_style', 'style', ); $extra_fields = array_merge( array( 'api_version', 'name', 'title', 'description', 'icon', 'category', 'keywords', 'parent', 'ancestor', 'allowed_blocks', 'provides_context', 'uses_context', 'selectors', 'supports', 'styles', 'textdomain', 'example', 'editor_script_handles', 'script_handles', 'view_script_handles', 'view_script_module_ids', 'editor_style_handles', 'style_handles', 'view_style_handles', 'variations', 'block_hooks', ), $deprecated_fields ); foreach ( $extra_fields as $extra_field ) { if ( rest_is_field_included( $extra_field, $fields ) ) { if ( isset( $block_type->$extra_field ) ) { $field = $block_type->$extra_field; if ( in_array( $extra_field, $deprecated_fields, true ) && is_array( $field ) ) { // Since the schema only allows strings or null (but no arrays), we return the first array item. $field = ! empty( $field ) ? array_shift( $field ) : ''; } } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) { $field = $schema['properties'][ $extra_field ]['default']; } else { $field = ''; } $data[ $extra_field ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $extra_field ] ); } } if ( rest_is_field_included( 'styles', $fields ) ) { $styles = $this->style_registry->get_registered_styles_for_block( $block_type->name ); $styles = array_values( $styles ); $data['styles'] = wp_parse_args( $styles, $data['styles'] ); $data['styles'] = array_filter( $data['styles'] ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $block_type ) ); } /** * Filters a block type returned from the REST API. * * Allows modification of the block type data right before it is returned. * * @since 5.5.0 * * @param WP_REST_Response $response The response object. * @param WP_Block_Type $block_type The original block type object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_block_type', $response, $block_type, $request ); } /** * Prepares links for the request. * * @since 5.5.0 * * @param WP_Block_Type $block_type Block type data. * @return array Links for the given block type. */ protected function prepare_links( $block_type ) { list( $namespace ) = explode( '/', $block_type->name ); $links = array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $block_type->name ) ), ), 'up' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $namespace ) ), ), ); if ( $block_type->is_dynamic() ) { $links['https://api.w.org/render-block'] = array( 'href' => add_query_arg( 'context', 'edit', rest_url( sprintf( '%s/%s/%s', 'wp/v2', 'block-renderer', $block_type->name ) ) ), ); } return $links; } /** * Retrieves the block type' schema, conforming to JSON Schema. * * @since 5.5.0 * @since 6.3.0 Added `selectors` field. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } // rest_validate_value_from_schema doesn't understand $refs, pull out reused definitions for readability. $inner_blocks_definition = array( 'description' => __( 'The list of inner blocks used in the example.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The name of the inner block.' ), 'type' => 'string', 'pattern' => self::NAME_PATTERN, 'required' => true, ), 'attributes' => array( 'description' => __( 'The attributes of the inner block.' ), 'type' => 'object', ), 'innerBlocks' => array( 'description' => __( "A list of the inner block's own inner blocks. This is a recursive definition following the parent innerBlocks schema." ), 'type' => 'array', ), ), ), ); $example_definition = array( 'description' => __( 'Block example.' ), 'type' => array( 'object', 'null' ), 'default' => null, 'properties' => array( 'attributes' => array( 'description' => __( 'The attributes used in the example.' ), 'type' => 'object', ), 'innerBlocks' => $inner_blocks_definition, ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $keywords_definition = array( 'description' => __( 'Block keywords.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $icon_definition = array( 'description' => __( 'Icon of block type.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $category_definition = array( 'description' => __( 'Block category.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-type', 'type' => 'object', 'properties' => array( 'api_version' => array( 'description' => __( 'Version of block API.' ), 'type' => 'integer', 'default' => 1, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'title' => array( 'description' => __( 'Title of block type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Unique name identifying the block type.' ), 'type' => 'string', 'pattern' => self::NAME_PATTERN, 'required' => true, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of block type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'icon' => $icon_definition, 'attributes' => array( 'description' => __( 'Block attributes.' ), 'type' => array( 'object', 'null' ), 'properties' => array(), 'default' => null, 'additionalProperties' => array( 'type' => 'object', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'provides_context' => array( 'description' => __( 'Context provided by blocks of this type.' ), 'type' => 'object', 'properties' => array(), 'additionalProperties' => array( 'type' => 'string', ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'uses_context' => array( 'description' => __( 'Context values inherited by blocks of this type.' ), 'type' => 'array', 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'selectors' => array( 'description' => __( 'Custom CSS selectors.' ), 'type' => 'object', 'default' => array(), 'properties' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'supports' => array( 'description' => __( 'Block supports.' ), 'type' => 'object', 'default' => array(), 'properties' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'category' => $category_definition, 'is_dynamic' => array( 'description' => __( 'Is the block dynamically rendered.' ), 'type' => 'boolean', 'default' => false, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_script_handles' => array( 'description' => __( 'Editor script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'script_handles' => array( 'description' => __( 'Public facing and editor script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script_handles' => array( 'description' => __( 'Public facing script handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script_module_ids' => array( 'description' => __( 'Public facing script module IDs.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_style_handles' => array( 'description' => __( 'Editor style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'style_handles' => array( 'description' => __( 'Public facing and editor style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_style_handles' => array( 'description' => __( 'Public facing style handles.' ), 'type' => array( 'array' ), 'default' => array(), 'items' => array( 'type' => 'string', ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'styles' => array( 'description' => __( 'Block style variations.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'Unique name identifying the style.' ), 'type' => 'string', 'required' => true, ), 'label' => array( 'description' => __( 'The human-readable label for the style.' ), 'type' => 'string', ), 'inline_style' => array( 'description' => __( 'Inline CSS code that registers the CSS class required for the style.' ), 'type' => 'string', ), 'style_handle' => array( 'description' => __( 'Contains the handle that defines the block style.' ), 'type' => 'string', ), ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'variations' => array( 'description' => __( 'Block variations.' ), 'type' => 'array', 'items' => array( 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The unique and machine-readable name.' ), 'type' => 'string', 'required' => true, ), 'title' => array( 'description' => __( 'A human-readable variation title.' ), 'type' => 'string', 'required' => true, ), 'description' => array( 'description' => __( 'A detailed variation description.' ), 'type' => 'string', 'required' => false, ), 'category' => $category_definition, 'icon' => $icon_definition, 'isDefault' => array( 'description' => __( 'Indicates whether the current variation is the default one.' ), 'type' => 'boolean', 'required' => false, 'default' => false, ), 'attributes' => array( 'description' => __( 'The initial values for attributes.' ), 'type' => 'object', ), 'innerBlocks' => $inner_blocks_definition, 'example' => $example_definition, 'scope' => array( 'description' => __( 'The list of scopes where the variation is applicable. When not provided, it assumes all available scopes.' ), 'type' => array( 'array', 'null' ), 'default' => null, 'items' => array( 'type' => 'string', 'enum' => array( 'block', 'inserter', 'transform' ), ), 'readonly' => true, ), 'keywords' => $keywords_definition, ), ), 'readonly' => true, 'context' => array( 'embed', 'view', 'edit' ), 'default' => null, ), 'textdomain' => array( 'description' => __( 'Public text domain.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'parent' => array( 'description' => __( 'Parent blocks.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'ancestor' => array( 'description' => __( 'Ancestor blocks.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'allowed_blocks' => array( 'description' => __( 'Allowed child block types.' ), 'type' => array( 'array', 'null' ), 'items' => array( 'type' => 'string', 'pattern' => self::NAME_PATTERN, ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'keywords' => $keywords_definition, 'example' => $example_definition, 'block_hooks' => array( 'description' => __( 'This block is automatically inserted near any occurrence of the block types used as keys of this map, into a relative position given by the corresponding value.' ), 'type' => 'object', 'patternProperties' => array( self::NAME_PATTERN => array( 'type' => 'string', 'enum' => array( 'before', 'after', 'first_child', 'last_child' ), ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); // Properties deprecated in WordPress 6.1, but left in the schema for backwards compatibility. $deprecated_properties = array( 'editor_script' => array( 'description' => __( 'Editor script handle. DEPRECATED: Use `editor_script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'script' => array( 'description' => __( 'Public facing and editor script handle. DEPRECATED: Use `script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'view_script' => array( 'description' => __( 'Public facing script handle. DEPRECATED: Use `view_script_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'editor_style' => array( 'description' => __( 'Editor style handle. DEPRECATED: Use `editor_style_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'style' => array( 'description' => __( 'Public facing and editor style handle. DEPRECATED: Use `style_handles` instead.' ), 'type' => array( 'string', 'null' ), 'default' => null, 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ); $this->schema['properties'] = array_merge( $this->schema['properties'], $deprecated_properties ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 5.5.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'namespace' => array( 'description' => __( 'Block namespace.' ), 'type' => 'string', ), ); } } [09-Oct-2025 10:18:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php on line 17 [09-Oct-2025 10:18:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php on line 17 [09-Oct-2025 10:18:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php on line 17 [09-Oct-2025 10:18:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php on line 17 [09-Oct-2025 10:18:18 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php on line 18 [09-Oct-2025 10:18:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php on line 18 [09-Oct-2025 10:18:20 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php on line 17 [09-Oct-2025 10:18:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-directory-controller.php on line 17 [09-Oct-2025 10:18:22 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php on line 17 [09-Oct-2025 10:18:22 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php on line 17 [09-Oct-2025 10:18:23 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php on line 17 [09-Oct-2025 10:18:24 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php on line 17 [09-Oct-2025 10:18:25 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php on line 17 [09-Oct-2025 10:18:26 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php on line 17 [09-Oct-2025 10:18:27 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php on line 17 [09-Oct-2025 10:18:28 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php on line 17 [09-Oct-2025 10:18:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php on line 20 [09-Oct-2025 10:18:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php on line 20 [09-Oct-2025 10:18:30 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php on line 17 [09-Oct-2025 10:18:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php on line 17 [09-Oct-2025 10:18:34 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php on line 17 [09-Oct-2025 10:18:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-edit-site-export-controller.php on line 17 [09-Oct-2025 10:18:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php on line 17 [09-Oct-2025 10:18:37 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php on line 17 [09-Oct-2025 10:18:38 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php:13 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php on line 13 [09-Oct-2025 10:18:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php:13 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php on line 13 [09-Oct-2025 10:18:39 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-families-controller.php:15 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-families-controller.php on line 15 [09-Oct-2025 10:18:40 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-families-controller.php:15 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-font-families-controller.php on line 15 [09-Oct-2025 10:18:41 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php:13 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php on line 13 [09-Oct-2025 10:18:42 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php:13 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php on line 13 [09-Oct-2025 10:18:43 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php on line 17 [09-Oct-2025 10:18:44 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php on line 17 [09-Oct-2025 10:18:45 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php on line 17 [09-Oct-2025 10:18:45 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Posts_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php on line 17 [09-Oct-2025 10:18:46 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-locations-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-locations-controller.php on line 17 [09-Oct-2025 10:18:47 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-locations-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menu-locations-controller.php on line 17 [09-Oct-2025 10:18:48 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Terms_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menus-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menus-controller.php on line 17 [09-Oct-2025 10:18:49 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Terms_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menus-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-menus-controller.php on line 17 [09-Oct-2025 10:18:50 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php on line 17 [09-Oct-2025 10:18:51 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-navigation-fallback-controller.php on line 17 [09-Oct-2025 10:18:51 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php on line 20 [09-Oct-2025 10:18:52 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php:20 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php on line 20 [09-Oct-2025 10:18:53 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php on line 17 [09-Oct-2025 10:18:54 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-plugins-controller.php on line 17 [09-Oct-2025 10:18:55 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-statuses-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-statuses-controller.php on line 17 [09-Oct-2025 10:18:56 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-statuses-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-statuses-controller.php on line 17 [09-Oct-2025 10:18:57 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php on line 17 [09-Oct-2025 10:18:58 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php on line 17 [09-Oct-2025 10:18:58 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php on line 17 [09-Oct-2025 10:18:59 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php on line 17 [09-Oct-2025 10:19:00 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php on line 17 [09-Oct-2025 10:19:01 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php on line 17 [09-Oct-2025 10:19:02 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php on line 17 [09-Oct-2025 10:19:03 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php on line 17 [09-Oct-2025 10:19:04 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php on line 17 [09-Oct-2025 10:19:04 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php on line 17 [09-Oct-2025 10:19:05 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php on line 19 [09-Oct-2025 10:19:07 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php:19 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php on line 19 [09-Oct-2025 10:19:08 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php on line 17 [09-Oct-2025 10:19:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php on line 17 [09-Oct-2025 10:19:09 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php on line 17 [09-Oct-2025 10:19:10 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php on line 17 [09-Oct-2025 10:19:11 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Autosaves_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php on line 17 [09-Oct-2025 10:19:12 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Autosaves_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php on line 17 [09-Oct-2025 10:19:13 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php on line 17 [09-Oct-2025 10:19:14 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Revisions_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php on line 17 [09-Oct-2025 10:19:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php on line 17 [09-Oct-2025 10:19:15 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php on line 17 [09-Oct-2025 10:19:16 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php on line 17 [09-Oct-2025 10:19:17 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php on line 17 [09-Oct-2025 10:19:18 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php on line 17 [09-Oct-2025 10:19:19 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php on line 17 [09-Oct-2025 10:19:20 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php on line 18 [09-Oct-2025 10:19:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php:18 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php on line 18 [09-Oct-2025 10:19:21 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php on line 17 [09-Oct-2025 10:19:22 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php on line 17 [09-Oct-2025 10:19:23 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php on line 17 [09-Oct-2025 10:19:24 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php on line 17 [09-Oct-2025 10:19:25 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php on line 17 [09-Oct-2025 10:19:26 UTC] PHP Fatal error: Uncaught Error: Class "WP_REST_Controller" not found in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php:17 Stack trace: #0 {main} thrown in /home/fresvfqn/emergencywaterdamagenyc.com/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php on line 17 <?php /** * REST API: WP_REST_Block_Directory_Controller class * * @package WordPress * @subpackage REST_API * @since 5.5.0 */ /** * Controller which provides REST endpoint for the blocks. * * @since 5.5.0 * * @see WP_REST_Controller */ class WP_REST_Block_Directory_Controller extends WP_REST_Controller { /** * Constructs the controller. */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-directory'; } /** * Registers the necessary REST API routes. */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/search', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to install and activate plugins. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has permission, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) || ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_block_directory_cannot_view', __( 'Sorry, you are not allowed to browse the block directory.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Search and retrieve blocks metadata * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; $response = plugins_api( 'query_plugins', array( 'block' => $request['term'], 'per_page' => $request['per_page'], 'page' => $request['page'], ) ); if ( is_wp_error( $response ) ) { $response->add_data( array( 'status' => 500 ) ); return $response; } $result = array(); foreach ( $response->plugins as $plugin ) { // If the API returned a plugin with empty data for 'blocks', skip it. if ( empty( $plugin['blocks'] ) ) { continue; } $data = $this->prepare_item_for_response( $plugin, $request ); $result[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $result ); } /** * Parse block metadata for a block, and prepare it for an API response. * * @since 5.5.0 * @since 5.9.0 Renamed `$plugin` to `$item` to match parent class for PHP 8 named parameter support. * * @param array $item The plugin metadata. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $plugin = $item; $fields = $this->get_fields_for_response( $request ); // There might be multiple blocks in a plugin. Only the first block is mapped. $block_data = reset( $plugin['blocks'] ); // A data array containing the properties we'll return. $block = array( 'name' => $block_data['name'], 'title' => ( $block_data['title'] ? $block_data['title'] : $plugin['name'] ), 'description' => wp_trim_words( $plugin['short_description'], 30, '...' ), 'id' => $plugin['slug'], 'rating' => $plugin['rating'] / 20, 'rating_count' => (int) $plugin['num_ratings'], 'active_installs' => (int) $plugin['active_installs'], 'author_block_rating' => $plugin['author_block_rating'] / 20, 'author_block_count' => (int) $plugin['author_block_count'], 'author' => wp_strip_all_tags( $plugin['author'] ), 'icon' => ( isset( $plugin['icons']['1x'] ) ? $plugin['icons']['1x'] : 'block-default' ), 'last_updated' => gmdate( 'Y-m-d\TH:i:s', strtotime( $plugin['last_updated'] ) ), 'humanized_updated' => sprintf( /* translators: %s: Human-readable time difference. */ __( '%s ago' ), human_time_diff( strtotime( $plugin['last_updated'] ) ) ), ); $this->add_additional_fields_to_object( $block, $request ); $response = new WP_REST_Response( $block ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $plugin ) ); } return $response; } /** * Generates a list of links to include in the response for the plugin. * * @since 5.5.0 * * @param array $plugin The plugin data from WordPress.org. * @return array */ protected function prepare_links( $plugin ) { $links = array( 'https://api.w.org/install-plugin' => array( 'href' => add_query_arg( 'slug', urlencode( $plugin['slug'] ), rest_url( 'wp/v2/plugins' ) ), ), ); $plugin_file = $this->find_plugin_for_slug( $plugin['slug'] ); if ( $plugin_file ) { $links['https://api.w.org/plugin'] = array( 'href' => rest_url( 'wp/v2/plugins/' . substr( $plugin_file, 0, - 4 ) ), 'embeddable' => true, ); } return $links; } /** * Finds an installed plugin for the given slug. * * @since 5.5.0 * * @param string $slug The WordPress.org directory slug for a plugin. * @return string The plugin file found matching it. */ protected function find_plugin_for_slug( $slug ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $plugin_files = get_plugins( '/' . $slug ); if ( ! $plugin_files ) { return ''; } $plugin_files = array_keys( $plugin_files ); return $slug . '/' . reset( $plugin_files ); } /** * Retrieves the theme's schema, conforming to JSON Schema. * * @since 5.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-directory-item', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The block name, in namespace/block-name format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'title' => array( 'description' => __( 'The block title, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'description' => array( 'description' => __( 'A short description of the block, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'id' => array( 'description' => __( 'The block slug.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'rating' => array( 'description' => __( 'The star rating of the block.' ), 'type' => 'number', 'context' => array( 'view' ), ), 'rating_count' => array( 'description' => __( 'The number of ratings.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'active_installs' => array( 'description' => __( 'The number sites that have activated this block.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'author_block_rating' => array( 'description' => __( 'The average rating of blocks published by the same author.' ), 'type' => 'number', 'context' => array( 'view' ), ), 'author_block_count' => array( 'description' => __( 'The number of blocks published by the same author.' ), 'type' => 'integer', 'context' => array( 'view' ), ), 'author' => array( 'description' => __( 'The WordPress.org username of the block author.' ), 'type' => 'string', 'context' => array( 'view' ), ), 'icon' => array( 'description' => __( 'The block icon.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view' ), ), 'last_updated' => array( 'description' => __( 'The date when the block was last updated.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view' ), ), 'humanized_updated' => array( 'description' => __( 'The date when the block was last updated, in human readable format.' ), 'type' => 'string', 'context' => array( 'view' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the search params for the blocks collection. * * @since 5.5.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['term'] = array( 'description' => __( 'Limit result set to blocks matching the search term.' ), 'type' => 'string', 'required' => true, 'minLength' => 1, ); unset( $query_params['search'] ); /** * Filters REST API collection parameters for the block directory controller. * * @since 5.5.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_block_directory_collection_params', $query_params ); } } <?php /** * REST API: WP_REST_Widget_Types_Controller class * * @package WordPress * @subpackage REST_API * @since 5.8.0 */ /** * Core class to access widget types via the REST API. * * @since 5.8.0 * * @see WP_REST_Controller */ class WP_REST_Widget_Types_Controller extends WP_REST_Controller { /** * Constructor. * * @since 5.8.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'widget-types'; } /** * Registers the widget type routes. * * @since 5.8.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)', array( 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/encode', array( 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', 'required' => true, ), 'instance' => array( 'description' => __( 'Current instance settings of the widget.' ), 'type' => 'object', ), 'form_data' => array( 'description' => __( 'Serialized widget form data to encode into instance settings.' ), 'type' => 'string', 'sanitize_callback' => static function ( $form_data ) { $array = array(); wp_parse_str( $form_data, $array ); return $array; }, ), ), array( 'methods' => WP_REST_Server::CREATABLE, 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'callback' => array( $this, 'encode_form_data' ), ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9_-]+)/render', array( array( 'methods' => WP_REST_Server::CREATABLE, 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'callback' => array( $this, 'render' ), 'args' => array( 'id' => array( 'description' => __( 'The widget type id.' ), 'type' => 'string', 'required' => true, ), 'instance' => array( 'description' => __( 'Current instance settings of the widget.' ), 'type' => 'object', ), ), ), ) ); } /** * Checks whether a given request has permission to read widget types. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { return $this->check_read_permission(); } /** * Retrieves the list of all widget types. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $data = array(); foreach ( $this->get_widgets() as $widget ) { $widget_type = $this->prepare_item_for_response( $widget, $request ); $data[] = $this->prepare_response_for_collection( $widget_type ); } return rest_ensure_response( $data ); } /** * Checks if a given request has access to read a widget type. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $check = $this->check_read_permission(); if ( is_wp_error( $check ) ) { return $check; } $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { return $widget_type; } return true; } /** * Checks whether the user can read widget types. * * @since 5.8.0 * * @return true|WP_Error True if the widget type is visible, WP_Error otherwise. */ protected function check_read_permission() { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } /** * Gets the details about the requested widget. * * @since 5.8.0 * * @param string $id The widget type id. * @return array|WP_Error The array of widget data if the name is valid, WP_Error otherwise. */ public function get_widget( $id ) { foreach ( $this->get_widgets() as $widget ) { if ( $id === $widget['id'] ) { return $widget; } } return new WP_Error( 'rest_widget_type_invalid', __( 'Invalid widget type.' ), array( 'status' => 404 ) ); } /** * Normalize array of widgets. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * @global array $wp_registered_widgets The list of registered widgets. * * @return array Array of widgets. */ protected function get_widgets() { global $wp_widget_factory, $wp_registered_widgets; $widgets = array(); foreach ( $wp_registered_widgets as $widget ) { $parsed_id = wp_parse_widget_id( $widget['id'] ); $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); $widget['id'] = $parsed_id['id_base']; $widget['is_multi'] = (bool) $widget_object; if ( isset( $widget['name'] ) ) { $widget['name'] = html_entity_decode( $widget['name'], ENT_QUOTES, get_bloginfo( 'charset' ) ); } if ( isset( $widget['description'] ) ) { $widget['description'] = html_entity_decode( $widget['description'], ENT_QUOTES, get_bloginfo( 'charset' ) ); } unset( $widget['callback'] ); $classname = ''; foreach ( (array) $widget['classname'] as $cn ) { if ( is_string( $cn ) ) { $classname .= '_' . $cn; } elseif ( is_object( $cn ) ) { $classname .= '_' . get_class( $cn ); } } $widget['classname'] = ltrim( $classname, '_' ); $widgets[ $widget['id'] ] = $widget; } ksort( $widgets ); return $widgets; } /** * Retrieves a single widget type from the collection. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $widget_id = $request['id']; $widget_type = $this->get_widget( $widget_id ); if ( is_wp_error( $widget_type ) ) { return $widget_type; } $data = $this->prepare_item_for_response( $widget_type, $request ); return rest_ensure_response( $data ); } /** * Prepares a widget type object for serialization. * * @since 5.8.0 * @since 5.9.0 Renamed `$widget_type` to `$item` to match parent class for PHP 8 named parameter support. * * @param array $item Widget type data. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Widget type data. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $widget_type = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php */ return apply_filters( 'rest_prepare_widget_type', new WP_REST_Response( array() ), $widget_type, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array( 'id' => $widget_type['id'], ); $schema = $this->get_item_schema(); $extra_fields = array( 'name', 'description', 'is_multi', 'classname', 'widget_class', 'option_name', 'customize_selective_refresh', ); foreach ( $extra_fields as $extra_field ) { if ( ! rest_is_field_included( $extra_field, $fields ) ) { continue; } if ( isset( $widget_type[ $extra_field ] ) ) { $field = $widget_type[ $extra_field ]; } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) { $field = $schema['properties'][ $extra_field ]['default']; } else { $field = ''; } $data[ $extra_field ] = rest_sanitize_value_from_schema( $field, $schema['properties'][ $extra_field ] ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $widget_type ) ); } /** * Filters the REST API response for a widget type. * * @since 5.8.0 * * @param WP_REST_Response $response The response object. * @param array $widget_type The array of widget data. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_widget_type', $response, $widget_type, $request ); } /** * Prepares links for the widget type. * * @since 5.8.0 * * @param array $widget_type Widget type data. * @return array Links for the given widget type. */ protected function prepare_links( $widget_type ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $widget_type['id'] ) ), ), ); } /** * Retrieves the widget type's schema, conforming to JSON Schema. * * @since 5.8.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'widget-type', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique slug identifying the widget type.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Human-readable name identifying the widget type.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of the widget.' ), 'type' => 'string', 'default' => '', 'context' => array( 'view', 'edit', 'embed' ), ), 'is_multi' => array( 'description' => __( 'Whether the widget supports multiple instances' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'classname' => array( 'description' => __( 'Class name' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * An RPC-style endpoint which can be used by clients to turn user input in * a widget admin form into an encoded instance object. * * Accepts: * * - id: A widget type ID. * - instance: A widget's encoded instance object. Optional. * - form_data: Form data from submitting a widget's admin form. Optional. * * Returns: * - instance: The encoded instance object after updating the widget with * the given form data. * - form: The widget's admin form after updating the widget with the * given form data. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function encode_form_data( $request ) { global $wp_widget_factory; $id = $request['id']; $widget_object = $wp_widget_factory->get_widget_object( $id ); if ( ! $widget_object ) { return new WP_Error( 'rest_invalid_widget', __( 'Cannot preview a widget that does not extend WP_Widget.' ), array( 'status' => 400 ) ); } /* * Set the widget's number so that the id attributes in the HTML that we * return are predictable. */ if ( isset( $request['number'] ) && is_numeric( $request['number'] ) ) { $widget_object->_set( (int) $request['number'] ); } else { $widget_object->_set( -1 ); } if ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { $serialized_instance = base64_decode( $request['instance']['encoded'] ); if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is malformed.' ), array( 'status' => 400 ) ); } $instance = unserialize( $serialized_instance ); } else { $instance = array(); } if ( isset( $request['form_data'][ "widget-$id" ] ) && is_array( $request['form_data'][ "widget-$id" ] ) ) { $new_instance = array_values( $request['form_data'][ "widget-$id" ] )[0]; $old_instance = $instance; $instance = $widget_object->update( $new_instance, $old_instance ); /** This filter is documented in wp-includes/class-wp-widget.php */ $instance = apply_filters( 'widget_update_callback', $instance, $new_instance, $old_instance, $widget_object ); } $serialized_instance = serialize( $instance ); $widget_key = $wp_widget_factory->get_widget_key( $id ); $response = array( 'form' => trim( $this->get_widget_form( $widget_object, $instance ) ), 'preview' => trim( $this->get_widget_preview( $widget_key, $instance ) ), 'instance' => array( 'encoded' => base64_encode( $serialized_instance ), 'hash' => wp_hash( $serialized_instance ), ), ); if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { // Use new stdClass so that JSON result is {} and not []. $response['instance']['raw'] = empty( $instance ) ? new stdClass() : $instance; } return rest_ensure_response( $response ); } /** * Returns the output of WP_Widget::widget() when called with the provided * instance. Used by encode_form_data() to preview a widget. * @since 5.8.0 * * @param string $widget The widget's PHP class name (see class-wp-widget.php). * @param array $instance Widget instance settings. * @return string */ private function get_widget_preview( $widget, $instance ) { ob_start(); the_widget( $widget, $instance ); return ob_get_clean(); } /** * Returns the output of WP_Widget::form() when called with the provided * instance. Used by encode_form_data() to preview a widget's form. * * @since 5.8.0 * * @param WP_Widget $widget_object Widget object to call widget() on. * @param array $instance Widget instance settings. * @return string */ private function get_widget_form( $widget_object, $instance ) { ob_start(); /** This filter is documented in wp-includes/class-wp-widget.php */ $instance = apply_filters( 'widget_form_callback', $instance, $widget_object ); if ( false !== $instance ) { $return = $widget_object->form( $instance ); /** This filter is documented in wp-includes/class-wp-widget.php */ do_action_ref_array( 'in_widget_form', array( &$widget_object, &$return, $instance ) ); } return ob_get_clean(); } /** * Renders a single Legacy Widget and wraps it in a JSON-encodable array. * * @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 ) { return array( 'preview' => $this->render_legacy_widget_preview_iframe( $request['id'], isset( $request['instance'] ) ? $request['instance'] : null ), ); } /** * Renders a page containing a preview of the requested Legacy Widget block. * * @since 5.9.0 * * @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 ) { if ( ! defined( 'IFRAME_REQUEST' ) ) { define( 'IFRAME_REQUEST', true ); } ob_start(); ?> <!doctype html> <html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="profile" href="https://gmpg.org/xfn/11" /> <?php wp_head(); ?> <style> /* Reset theme styles */ html, body, #page, #content { padding: 0 !important; margin: 0 !important; } </style> </head> <body <?php body_class(); ?>> <div id="page" class="site"> <div id="content" class="site-content"> <?php $registry = WP_Block_Type_Registry::get_instance(); $block = $registry->get_registered( 'core/legacy-widget' ); echo $block->render( array( 'idBase' => $id_base, 'instance' => $instance, ) ); ?> </div><!-- #content --> </div><!-- #page --> <?php wp_footer(); ?> </body> </html> <?php return ob_get_clean(); } /** * Retrieves the query params for collections. * * @since 5.8.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } } <?php /** * REST API: WP_REST_Terms_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to managed terms associated with a taxonomy via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Terms_Controller extends WP_REST_Controller { /** * Taxonomy key. * * @since 4.7.0 * @var string */ protected $taxonomy; /** * Instance of a term meta fields object. * * @since 4.7.0 * @var WP_REST_Term_Meta_Fields */ protected $meta; /** * Column to have the terms be sorted by. * * @since 4.7.0 * @var string */ protected $sort_column; /** * Number of terms that were found. * * @since 4.7.0 * @var int */ protected $total_terms; /** * Whether the controller supports batching. * * @since 5.9.0 * @var array */ protected $allow_batch = array( 'v1' => true ); /** * Constructor. * * @since 4.7.0 * * @param string $taxonomy Taxonomy key. */ public function __construct( $taxonomy ) { $this->taxonomy = $taxonomy; $tax_obj = get_taxonomy( $taxonomy ); $this->rest_base = ! empty( $tax_obj->rest_base ) ? $tax_obj->rest_base : $tax_obj->name; $this->namespace = ! empty( $tax_obj->rest_namespace ) ? $tax_obj->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Term_Meta_Fields( $taxonomy ); } /** * Registers the routes for terms. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the term.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as terms do not support trashing.' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if the terms for a post can be read. * * @since 6.0.3 * * @param WP_Post $post Post object. * @param WP_REST_Request $request Full details about the request. * @return bool Whether the terms for the post can be read. */ public function check_read_terms_permission_for_post( $post, $request ) { // If the requested post isn't associated with this taxonomy, deny access. if ( ! is_object_in_taxonomy( $post->post_type, $this->taxonomy ) ) { return false; } // Grant access if the post is publicly viewable. if ( is_post_publicly_viewable( $post ) ) { return true; } // Otherwise grant access if the post is readable by the logged-in user. if ( current_user_can( 'read_post', $post->ID ) ) { return true; } // Otherwise, deny access. return false; } /** * Checks if a request has access to read terms in the specified taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has read access, otherwise false or WP_Error object. */ public function get_items_permissions_check( $request ) { $tax_obj = get_taxonomy( $this->taxonomy ); if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return false; } if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->edit_terms ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['post'] ) ) { $post = get_post( $request['post'] ); if ( ! $post ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 400, ) ); } if ( ! $this->check_read_terms_permission_for_post( $post, $request ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view terms for this post.' ), array( 'status' => rest_authorization_required_code(), ) ); } } return true; } /** * Retrieves terms associated with a taxonomy. * * @since 4.7.0 * @since 6.8.0 Respect default query arguments set for the taxonomy upon registration. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); /* * This array defines mappings between public API query parameters whose * values are accepted as-passed, and their internal WP_Query parameter * name equivalents (some are the same). Only values which are also * present in $registered will be set. */ $parameter_mappings = array( 'exclude' => 'exclude', 'include' => 'include', 'order' => 'order', 'orderby' => 'orderby', 'post' => 'post', 'hide_empty' => 'hide_empty', 'per_page' => 'number', 'search' => 'search', 'slug' => 'slug', ); $prepared_args = array( 'taxonomy' => $this->taxonomy ); /* * For each known parameter which is both registered and present in the request, * set the parameter's value on the query $prepared_args. */ foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } if ( isset( $prepared_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'include_slugs' => 'slug__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $prepared_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { $prepared_args['offset'] = $request['offset']; } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } $taxonomy_obj = get_taxonomy( $this->taxonomy ); if ( $taxonomy_obj->hierarchical && isset( $registered['parent'], $request['parent'] ) ) { if ( 0 === $request['parent'] ) { // Only query top-level terms. $prepared_args['parent'] = 0; } else { if ( $request['parent'] ) { $prepared_args['parent'] = $request['parent']; } } } /* * When a taxonomy is registered with an 'args' array, * those params override the `$args` passed to this function. * * We only need to do this if no `post` argument is provided. * Otherwise, terms will be fetched using `wp_get_object_terms()`, * which respects the default query arguments set for the taxonomy. */ if ( empty( $prepared_args['post'] ) && isset( $taxonomy_obj->args ) && is_array( $taxonomy_obj->args ) ) { $prepared_args = array_merge( $prepared_args, $taxonomy_obj->args ); } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only term IDs are required. $prepared_args['fields'] = 'ids'; // Disable priming term meta for HEAD requests to improve performance. $prepared_args['update_term_meta_cache'] = false; } /** * Filters get_terms() arguments when querying terms via the REST API. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_category_query` * - `rest_post_tag_query` * * Enables adding extra arguments or setting defaults for a terms * collection request. * * @since 4.7.0 * * @link https://developer.wordpress.org/reference/functions/get_terms/ * * @param array $prepared_args Array of arguments for get_terms(). * @param WP_REST_Request $request The REST API request. */ $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request ); if ( ! empty( $prepared_args['post'] ) ) { $query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $prepared_args ); // Used when calling wp_count_terms() below. $prepared_args['object_ids'] = $prepared_args['post']; } else { $query_result = get_terms( $prepared_args ); } $count_args = $prepared_args; unset( $count_args['number'], $count_args['offset'] ); $total_terms = wp_count_terms( $count_args ); // wp_count_terms() can return a falsey value when the term has no children. if ( ! $total_terms ) { $total_terms = 0; } if ( ! $is_head_request ) { $response = array(); foreach ( $query_result as $term ) { if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { continue; } $data = $this->prepare_item_for_response( $term, $request ); $response[] = $this->prepare_response_for_collection( $data ); } } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $response ); // Store pagination values for headers. $per_page = (int) $prepared_args['number']; $page = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); $response->header( 'X-WP-Total', (int) $total_terms ); $max_pages = (int) ceil( $total_terms / $per_page ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( rest_get_route_for_taxonomy_items( $this->taxonomy ) ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Get the term, if the ID is valid. * * @since 4.7.2 * * @param int $id Supplied ID. * @return WP_Term|WP_Error Term object if ID is valid, WP_Error otherwise. */ protected function get_term( $id ) { $error = new WP_Error( 'rest_term_invalid', __( 'Term does not exist.' ), array( 'status' => 404 ) ); if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return $error; } if ( (int) $id <= 0 ) { return $error; } $term = get_term( (int) $id, $this->taxonomy ); if ( empty( $term ) || $term->taxonomy !== $this->taxonomy ) { return $error; } return $term; } /** * Checks if a request has access to read or edit the specified term. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. */ public function get_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Gets a single term from a taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } /** * Checks if a request has access to create a term. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has access to create items, otherwise false or WP_Error object. */ public function create_item_permissions_check( $request ) { if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return false; } $taxonomy_obj = get_taxonomy( $this->taxonomy ); if ( ( is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) || ( ! is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Creates a single term in a taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); $term = wp_insert_term( wp_slash( $prepared_term->name ), $this->taxonomy, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $term ) ) { /* * If we're going to inform the client that the term already exists, * give them the identifier for future use. */ $term_id = $term->get_error_data( 'term_exists' ); if ( $term_id ) { $existing_term = get_term( $term_id, $this->taxonomy ); $term->add_data( $existing_term->term_id, 'term_exists' ); $term->add_data( array( 'status' => 400, 'term_id' => $term_id, ) ); } return $term; } $term = get_term( $term['term_id'], $this->taxonomy ); /** * Fires after a single term is created or updated via the REST API. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_insert_category` * - `rest_insert_post_tag` * * @since 4.7.0 * * @param WP_Term $term Inserted or updated term object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a term, false when updating. */ do_action( "rest_insert_{$this->taxonomy}", $term, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** * Fires after a single term is completely created or updated via the REST API. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_after_insert_category` * - `rest_after_insert_post_tag` * * @since 5.0.0 * * @param WP_Term $term Inserted or updated term object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a term, false when updating. */ do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, true ); $response = $this->prepare_item_for_response( $term, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( $this->namespace . '/' . $this->rest_base . '/' . $term->term_id ) ); return $response; } /** * Checks if a request has access to update the specified term. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, false or WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'edit_term', $term->term_id ) ) { return new WP_Error( 'rest_cannot_update', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates a single term from a taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); // Only update the term if we have something to update. if ( ! empty( $prepared_term ) ) { $update = wp_update_term( $term->term_id, $term->taxonomy, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $update ) ) { return $update; } } $term = get_term( $term->term_id, $this->taxonomy ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_insert_{$this->taxonomy}", $term, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, false ); $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } /** * Checks if a request has access to delete the specified term. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, otherwise false or WP_Error object. */ public function delete_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'delete_term', $term->term_id ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this term.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes a single term from a taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for terms. if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( "Terms do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $request->set_param( 'context', 'view' ); $previous = $this->prepare_item_for_response( $term, $request ); $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { return new WP_Error( 'rest_cannot_delete', __( 'The term cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); /** * Fires after a single term is deleted via the REST API. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_delete_category` * - `rest_delete_post_tag` * * @since 4.7.0 * * @param WP_Term $term The deleted term. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action( "rest_delete_{$this->taxonomy}", $term, $response, $request ); return $response; } /** * Prepares a single term for create or update. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return object Term object. */ public function prepare_item_for_database( $request ) { $prepared_term = new stdClass(); $schema = $this->get_item_schema(); if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_term->name = $request['name']; } if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { $prepared_term->slug = $request['slug']; } if ( isset( $request['taxonomy'] ) && ! empty( $schema['properties']['taxonomy'] ) ) { $prepared_term->taxonomy = $request['taxonomy']; } if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { $prepared_term->description = $request['description']; } if ( isset( $request['parent'] ) && ! empty( $schema['properties']['parent'] ) ) { $parent_term_id = 0; $requested_parent = (int) $request['parent']; if ( $requested_parent ) { $parent_term = get_term( $requested_parent, $this->taxonomy ); if ( $parent_term instanceof WP_Term ) { $parent_term_id = $parent_term->term_id; } } $prepared_term->parent = $parent_term_id; } /** * Filters term data before inserting term via the REST API. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_pre_insert_category` * - `rest_pre_insert_post_tag` * * @since 4.7.0 * * @param object $prepared_term Term object. * @param WP_REST_Request $request Request object. */ return apply_filters( "rest_pre_insert_{$this->taxonomy}", $prepared_term, $request ); } /** * Prepares a single term output for response. * * @since 4.7.0 * * @param WP_Term $item Term object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response( array() ), $item, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = (int) $item->term_id; } if ( in_array( 'count', $fields, true ) ) { $data['count'] = (int) $item->count; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $item->description; } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_term_link( $item ); } if ( in_array( 'name', $fields, true ) ) { $data['name'] = $item->name; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $item->slug; } if ( in_array( 'taxonomy', $fields, true ) ) { $data['taxonomy'] = $item->taxonomy; } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->parent; } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $item->term_id, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $item ) ); } /** * Filters the term data for a REST API response. * * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug. * * Possible hook names include: * * - `rest_prepare_category` * - `rest_prepare_post_tag` * * Allows modification of the term data right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Term $item The original term object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $item, $request ); } /** * Prepares links for the request. * * @since 4.7.0 * * @param WP_Term $term Term object. * @return array Links for the given term. */ protected function prepare_links( $term ) { $links = array( 'self' => array( 'href' => rest_url( rest_get_route_for_term( $term ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_taxonomy_items( $this->taxonomy ) ), ), 'about' => array( 'href' => rest_url( sprintf( 'wp/v2/taxonomies/%s', $this->taxonomy ) ), ), ); if ( $term->parent ) { $parent_term = get_term( (int) $term->parent, $term->taxonomy ); if ( $parent_term ) { $links['up'] = array( 'href' => rest_url( rest_get_route_for_term( $parent_term ) ), 'embeddable' => true, ); } } $taxonomy_obj = get_taxonomy( $term->taxonomy ); if ( empty( $taxonomy_obj->object_type ) ) { return $links; } $post_type_links = array(); foreach ( $taxonomy_obj->object_type as $type ) { $rest_path = rest_get_route_for_post_type_items( $type ); if ( empty( $rest_path ) ) { continue; } $post_type_links[] = array( 'href' => add_query_arg( $this->rest_base, $term->term_id, rest_url( $rest_path ) ), ); } if ( ! empty( $post_type_links ) ) { $links['https://api.w.org/post_type'] = $post_type_links; } return $links; } /** * Retrieves the term's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the term.' ), 'type' => 'integer', 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), 'count' => array( 'description' => __( 'Number of published posts for the term.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'HTML description of the term.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'link' => array( 'description' => __( 'URL of the term.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'HTML title for the term.' ), 'type' => 'string', 'context' => array( 'view', 'embed', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), 'required' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the term unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'embed', 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'taxonomy' => array( 'description' => __( 'Type attribution for the term.' ), 'type' => 'string', 'enum' => array( $this->taxonomy ), 'context' => array( 'view', 'embed', 'edit' ), 'readonly' => true, ), ), ); $taxonomy = get_taxonomy( $this->taxonomy ); if ( $taxonomy->hierarchical ) { $schema['properties']['parent'] = array( 'description' => __( 'The parent term ID.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $taxonomy = get_taxonomy( $this->taxonomy ); $query_params['context']['default'] = 'view'; $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); if ( ! $taxonomy->hierarchical ) { $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); } $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'asc', 'enum' => array( 'asc', 'desc', ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by term attribute.' ), 'type' => 'string', 'default' => 'name', 'enum' => array( 'id', 'include', 'name', 'slug', 'include_slugs', 'term_group', 'description', 'count', ), ); $query_params['hide_empty'] = array( 'description' => __( 'Whether to hide terms not assigned to any posts.' ), 'type' => 'boolean', 'default' => false, ); if ( $taxonomy->hierarchical ) { $query_params['parent'] = array( 'description' => __( 'Limit result set to terms assigned to a specific parent.' ), 'type' => 'integer', ); } $query_params['post'] = array( 'description' => __( 'Limit result set to terms assigned to a specific post.' ), 'type' => 'integer', 'default' => null, ); $query_params['slug'] = array( 'description' => __( 'Limit result set to terms with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); /** * Filters collection parameters for the terms controller. * * The dynamic part of the filter `$this->taxonomy` refers to the taxonomy * slug for the controller. * * This filter registers the collection parameter, but does not map the * collection parameter to an internal WP_Term_Query parameter. Use the * `rest_{$this->taxonomy}_query` filter to set WP_Term_Query parameters. * * @since 4.7.0 * * @param array $query_params JSON Schema-formatted collection parameters. * @param WP_Taxonomy $taxonomy Taxonomy object. */ return apply_filters( "rest_{$this->taxonomy}_collection_params", $query_params, $taxonomy ); } /** * Checks that the taxonomy is valid. * * @since 4.7.0 * * @param string $taxonomy Taxonomy to check. * @return bool Whether the taxonomy is allowed for REST management. */ protected function check_is_taxonomy_allowed( $taxonomy ) { $taxonomy_obj = get_taxonomy( $taxonomy ); if ( $taxonomy_obj && ! empty( $taxonomy_obj->show_in_rest ) ) { return true; } return false; } } <?php /** * REST API: WP_REST_Search_Controller class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core class to search through all WordPress content via the REST API. * * @since 5.0.0 * * @see WP_REST_Controller */ class WP_REST_Search_Controller extends WP_REST_Controller { /** * ID property name. */ const PROP_ID = 'id'; /** * Title property name. */ const PROP_TITLE = 'title'; /** * URL property name. */ const PROP_URL = 'url'; /** * Type property name. */ const PROP_TYPE = 'type'; /** * Subtype property name. */ const PROP_SUBTYPE = 'subtype'; /** * Identifier for the 'any' type. */ const TYPE_ANY = 'any'; /** * Search handlers used by the controller. * * @since 5.0.0 * @var WP_REST_Search_Handler[] */ protected $search_handlers = array(); /** * Constructor. * * @since 5.0.0 * * @param array $search_handlers List of search handlers to use in the controller. Each search * handler instance must extend the `WP_REST_Search_Handler` class. */ public function __construct( array $search_handlers ) { $this->namespace = 'wp/v2'; $this->rest_base = 'search'; foreach ( $search_handlers as $search_handler ) { if ( ! $search_handler instanceof WP_REST_Search_Handler ) { _doing_it_wrong( __METHOD__, /* translators: %s: PHP class name. */ sprintf( __( 'REST search handlers must extend the %s class.' ), 'WP_REST_Search_Handler' ), '5.0.0' ); continue; } $this->search_handlers[ $search_handler->get_type() ] = $search_handler; } } /** * Registers the routes for the search controller. * * @since 5.0.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permission_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to search content. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has search access, WP_Error object otherwise. */ public function get_items_permission_check( $request ) { return true; } /** * Retrieves a collection of search results. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return $handler; } $result = $handler->search_items( $request ); if ( ! isset( $result[ WP_REST_Search_Handler::RESULT_IDS ] ) || ! is_array( $result[ WP_REST_Search_Handler::RESULT_IDS ] ) || ! isset( $result[ WP_REST_Search_Handler::RESULT_TOTAL ] ) ) { return new WP_Error( 'rest_search_handler_error', __( 'Internal search handler error.' ), array( 'status' => 500 ) ); } $ids = $result[ WP_REST_Search_Handler::RESULT_IDS ]; $is_head_request = $request->is_method( 'HEAD' ); if ( ! $is_head_request ) { $results = array(); foreach ( $ids as $id ) { $data = $this->prepare_item_for_response( $id, $request ); $results[] = $this->prepare_response_for_collection( $data ); } } $total = (int) $result[ WP_REST_Search_Handler::RESULT_TOTAL ]; $page = (int) $request['page']; $per_page = (int) $request['per_page']; $max_pages = (int) ceil( $total / $per_page ); if ( $page > $max_pages && $total > 0 ) { return new WP_Error( 'rest_search_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $results ); $response->header( 'X-WP-Total', $total ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $base = add_query_arg( urlencode_deep( $request_params ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_link = add_query_arg( 'page', $page - 1, $base ); $response->link_header( 'prev', $prev_link ); } if ( $page < $max_pages ) { $next_link = add_query_arg( 'page', $page + 1, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Prepares a single search result for response. * * @since 5.0.0 * @since 5.6.0 The `$id` parameter can accept a string. * @since 5.9.0 Renamed `$id` to `$item` to match parent class for PHP 8 named parameter support. * * @param int|string $item ID of the item to prepare. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $item_id = $item; $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return new WP_REST_Response(); } $fields = $this->get_fields_for_response( $request ); $data = $handler->prepare_item( $item_id, $fields ); $data = $this->add_additional_fields_to_object( $data, $request ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $handler->prepare_item_links( $item_id ); $links['collection'] = array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ); $response->add_links( $links ); } return $response; } /** * Retrieves the item schema, conforming to JSON Schema. * * @since 5.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $types = array(); $subtypes = array(); foreach ( $this->search_handlers as $search_handler ) { $types[] = $search_handler->get_type(); $subtypes = array_merge( $subtypes, $search_handler->get_subtypes() ); } $types = array_unique( $types ); $subtypes = array_unique( $subtypes ); $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'search-result', 'type' => 'object', 'properties' => array( self::PROP_ID => array( 'description' => __( 'Unique identifier for the object.' ), 'type' => array( 'integer', 'string' ), 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_TITLE => array( 'description' => __( 'The title for the object.' ), 'type' => 'string', 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_URL => array( 'description' => __( 'URL to the object.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_TYPE => array( 'description' => __( 'Object type.' ), 'type' => 'string', 'enum' => $types, 'context' => array( 'view', 'embed' ), 'readonly' => true, ), self::PROP_SUBTYPE => array( 'description' => __( 'Object subtype.' ), 'type' => 'string', 'enum' => $subtypes, 'context' => array( 'view', 'embed' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for the search results collection. * * @since 5.0.0 * * @return array Collection parameters. */ public function get_collection_params() { $types = array(); $subtypes = array(); foreach ( $this->search_handlers as $search_handler ) { $types[] = $search_handler->get_type(); $subtypes = array_merge( $subtypes, $search_handler->get_subtypes() ); } $types = array_unique( $types ); $subtypes = array_unique( $subtypes ); $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params[ self::PROP_TYPE ] = array( 'default' => $types[0], 'description' => __( 'Limit results to items of an object type.' ), 'type' => 'string', 'enum' => $types, ); $query_params[ self::PROP_SUBTYPE ] = array( 'default' => self::TYPE_ANY, 'description' => __( 'Limit results to items of one or more object subtypes.' ), 'type' => 'array', 'items' => array( 'enum' => array_merge( $subtypes, array( self::TYPE_ANY ) ), 'type' => 'string', ), 'sanitize_callback' => array( $this, 'sanitize_subtypes' ), ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); return $query_params; } /** * Sanitizes the list of subtypes, to ensure only subtypes of the passed type are included. * * @since 5.0.0 * * @param string|array $subtypes One or more subtypes. * @param WP_REST_Request $request Full details about the request. * @param string $parameter Parameter name. * @return string[]|WP_Error List of valid subtypes, or WP_Error object on failure. */ public function sanitize_subtypes( $subtypes, $request, $parameter ) { $subtypes = wp_parse_slug_list( $subtypes ); $subtypes = rest_parse_request_arg( $subtypes, $request, $parameter ); if ( is_wp_error( $subtypes ) ) { return $subtypes; } // 'any' overrides any other subtype. if ( in_array( self::TYPE_ANY, $subtypes, true ) ) { return array( self::TYPE_ANY ); } $handler = $this->get_search_handler( $request ); if ( is_wp_error( $handler ) ) { return $handler; } return array_intersect( $subtypes, $handler->get_subtypes() ); } /** * Gets the search handler to handle the current request. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Search_Handler|WP_Error Search handler for the request type, or WP_Error object on failure. */ protected function get_search_handler( $request ) { $type = $request->get_param( self::PROP_TYPE ); if ( ! $type || ! is_string( $type ) || ! isset( $this->search_handlers[ $type ] ) ) { return new WP_Error( 'rest_search_invalid_type', __( 'Invalid type parameter.' ), array( 'status' => 400 ) ); } return $this->search_handlers[ $type ]; } } <?php /** * Block Pattern Directory REST API: WP_REST_Pattern_Directory_Controller class * * @package WordPress * @subpackage REST_API * @since 5.8.0 */ /** * Controller which provides REST endpoint for block patterns. * * This simply proxies the endpoint at http://api.wordpress.org/patterns/1.0/. That isn't necessary for * functionality, but is desired for privacy. It prevents api.wordpress.org from knowing the user's IP address. * * @since 5.8.0 * * @see WP_REST_Controller */ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller { /** * Constructs the controller. * * @since 5.8.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'pattern-directory'; } /** * Registers the necessary REST API routes. * * @since 5.8.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/patterns', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to view the local block pattern directory. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has permission, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_pattern_directory_cannot_view', __( 'Sorry, you are not allowed to browse the local block pattern directory.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Search and retrieve block patterns metadata * * @since 5.8.0 * @since 6.0.0 Added 'slug' to request. * @since 6.2.0 Added 'per_page', 'page', 'offset', 'order', and 'orderby' to request. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $valid_query_args = array( 'offset' => true, 'order' => true, 'orderby' => true, 'page' => true, 'per_page' => true, 'search' => true, 'slug' => true, ); $query_args = array_intersect_key( $request->get_params(), $valid_query_args ); $query_args['locale'] = get_user_locale(); $query_args['wp-version'] = wp_get_wp_version(); $query_args['pattern-categories'] = isset( $request['category'] ) ? $request['category'] : false; $query_args['pattern-keywords'] = isset( $request['keyword'] ) ? $request['keyword'] : false; $query_args = array_filter( $query_args ); $transient_key = $this->get_transient_key( $query_args ); /* * Use network-wide transient to improve performance. The locale is the only site * configuration that affects the response, and it's included in the transient key. */ $raw_patterns = get_site_transient( $transient_key ); if ( ! $raw_patterns ) { $api_url = 'http://api.wordpress.org/patterns/1.0/?' . build_query( $query_args ); if ( wp_http_supports( array( 'ssl' ) ) ) { $api_url = set_url_scheme( $api_url, 'https' ); } /* * Default to a short TTL, to mitigate cache stampedes on high-traffic sites. * This assumes that most errors will be short-lived, e.g., packet loss that causes the * first request to fail, but a follow-up one will succeed. The value should be high * enough to avoid stampedes, but low enough to not interfere with users manually * re-trying a failed request. */ $cache_ttl = 5; $wporg_response = wp_remote_get( $api_url ); $raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) ); if ( is_wp_error( $wporg_response ) ) { $raw_patterns = $wporg_response; } elseif ( ! is_array( $raw_patterns ) ) { // HTTP request succeeded, but response data is invalid. $raw_patterns = new WP_Error( 'pattern_api_failed', sprintf( /* translators: %s: Support forums URL. */ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ), __( 'https://wordpress.org/support/forums/' ) ), array( 'response' => wp_remote_retrieve_body( $wporg_response ), ) ); } else { // Response has valid data. $cache_ttl = HOUR_IN_SECONDS; } set_site_transient( $transient_key, $raw_patterns, $cache_ttl ); } if ( is_wp_error( $raw_patterns ) ) { $raw_patterns->add_data( array( 'status' => 500 ) ); return $raw_patterns; } if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $response = array(); if ( $raw_patterns ) { foreach ( $raw_patterns as $pattern ) { $response[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $pattern, $request ) ); } } return new WP_REST_Response( $response ); } /** * Prepare a raw block pattern before it gets output in a REST API response. * * @since 5.8.0 * @since 5.9.0 Renamed `$raw_pattern` to `$item` to match parent class for PHP 8 named parameter support. * * @param object $item Raw pattern from api.wordpress.org, before any changes. * @param WP_REST_Request $request Request object. * @return WP_REST_Response */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $raw_pattern = $item; $prepared_pattern = array( 'id' => absint( $raw_pattern->id ), 'title' => sanitize_text_field( $raw_pattern->title->rendered ), 'content' => wp_kses_post( $raw_pattern->pattern_content ), 'categories' => array_map( 'sanitize_title', $raw_pattern->category_slugs ), 'keywords' => array_map( 'sanitize_text_field', explode( ',', $raw_pattern->meta->wpop_keywords ) ), 'description' => sanitize_text_field( $raw_pattern->meta->wpop_description ), 'viewport_width' => absint( $raw_pattern->meta->wpop_viewport_width ), 'block_types' => array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ), ); $prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request ); $response = new WP_REST_Response( $prepared_pattern ); /** * Filters the REST API response for a block pattern. * * @since 5.8.0 * * @param WP_REST_Response $response The response object. * @param object $raw_pattern The unprepared block pattern. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_block_pattern', $response, $raw_pattern, $request ); } /** * Retrieves the block pattern's schema, conforming to JSON Schema. * * @since 5.8.0 * @since 6.2.0 Added `'block_types'` to schema. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'pattern-directory-item', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'The pattern ID.' ), 'type' => 'integer', 'minimum' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'title' => array( 'description' => __( 'The pattern title, in human readable format.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'content' => array( 'description' => __( 'The pattern content.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( "The pattern's category slugs." ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'keywords' => array( 'description' => __( "The pattern's keywords." ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'A description of the pattern.' ), 'type' => 'string', 'minLength' => 1, 'context' => array( 'view', 'edit', 'embed' ), ), 'viewport_width' => array( 'description' => __( 'The preferred width of the viewport when previewing a pattern, in pixels.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'block_types' => array( 'description' => __( 'The block types which can use this pattern.' ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'type' => 'string' ), 'context' => array( 'view', 'embed' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the search parameters for the block pattern's collection. * * @since 5.8.0 * @since 6.2.0 Added 'per_page', 'page', 'offset', 'order', and 'orderby' to request. * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['per_page']['default'] = 100; $query_params['search']['minLength'] = 1; $query_params['context']['default'] = 'view'; $query_params['category'] = array( 'description' => __( 'Limit results to those matching a category ID.' ), 'type' => 'integer', 'minimum' => 1, ); $query_params['keyword'] = array( 'description' => __( 'Limit results to those matching a keyword ID.' ), 'type' => 'integer', 'minimum' => 1, ); $query_params['slug'] = array( 'description' => __( 'Limit results to those matching a pattern (slug).' ), 'type' => 'array', ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by post attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', 'favorite_count', ), ); /** * Filter collection parameters for the block pattern directory controller. * * @since 5.8.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_pattern_directory_collection_params', $query_params ); } /** * Include a hash of the query args, so that different requests are stored in * separate caches. * * MD5 is chosen for its speed, low-collision rate, universal availability, and to stay * under the character limit for `_site_transient_timeout_{...}` keys. * * @link https://stackoverflow.com/questions/3665247/fastest-hash-for-non-cryptographic-uses * * @since 6.0.0 * * @param array $query_args Query arguments to generate a transient key from. * @return string Transient key. */ protected function get_transient_key( $query_args ) { if ( isset( $query_args['slug'] ) ) { // This is an additional precaution because the "sort" function expects an array. $query_args['slug'] = wp_parse_list( $query_args['slug'] ); // Empty arrays should not affect the transient key. if ( empty( $query_args['slug'] ) ) { unset( $query_args['slug'] ); } else { // Sort the array so that the transient key doesn't depend on the order of slugs. sort( $query_args['slug'] ); } } return 'wp_remote_block_patterns_' . md5( serialize( $query_args ) ); } } <?php /** * REST API: WP_REST_Global_Styles_Revisions_Controller class * * @package WordPress * @subpackage REST_API * @since 6.3.0 */ /** * Core class used to access global styles revisions via the REST API. * * @since 6.3.0 * * @see WP_REST_Controller */ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Controller { /** * Parent controller. * * @since 6.6.0 * @var WP_REST_Controller */ private $parent_controller; /** * The base of the parent controller's route. * * @since 6.3.0 * @var string */ protected $parent_base; /** * Parent post type. * * @since 6.6.0 * @var string */ protected $parent_post_type; /** * Constructor. * * @since 6.3.0 * @since 6.6.0 Extends class from WP_REST_Revisions_Controller. * * @param string $parent_post_type Post type of the parent. */ public function __construct( $parent_post_type = 'wp_global_styles' ) { parent::__construct( $parent_post_type ); $post_type_object = get_post_type_object( $parent_post_type ); $parent_controller = $post_type_object->get_rest_controller(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Global_Styles_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** * Registers the controller's routes. * * @since 6.3.0 * @since 6.6.0 Added route to fetch individual global styles revisions. */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the global styles revision.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'Unique identifier for the global styles revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Returns decoded JSON from post content string, * or a 404 if not found. * * @since 6.3.0 * * @param string $raw_json Encoded JSON from global styles custom post content. * @return Array|WP_Error */ protected function get_decoded_global_styles_json( $raw_json ) { $decoded_json = json_decode( $raw_json, true ); if ( is_array( $decoded_json ) && isset( $decoded_json['isGlobalStylesUserThemeJSON'] ) && true === $decoded_json['isGlobalStylesUserThemeJSON'] ) { return $decoded_json; } return new WP_Error( 'rest_global_styles_not_found', __( 'Cannot find user global styles revisions.' ), array( 'status' => 404 ) ); } /** * Returns paginated revisions of the given global styles config custom post type. * * The bulk of the body is taken from WP_REST_Revisions_Controller->get_items, * but global styles does not require as many parameters. * * @since 6.3.0 * * @param WP_REST_Request $request The request instance. * @return WP_REST_Response|WP_Error */ public function get_items( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $global_styles_config = $this->get_decoded_global_styles_json( $parent->post_content ); if ( is_wp_error( $global_styles_config ) ) { return $global_styles_config; } $is_head_request = $request->is_method( 'HEAD' ); if ( wp_revisions_enabled( $parent ) ) { $registered = $this->get_collection_params(); $query_args = array( 'post_parent' => $parent->ID, 'post_type' => 'revision', 'post_status' => 'inherit', 'posts_per_page' => -1, 'orderby' => 'date ID', 'order' => 'DESC', ); $parameter_mappings = array( 'offset' => 'offset', 'page' => 'paged', 'per_page' => 'posts_per_page', ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $query_args[ $wp_param ] = $request[ $api_param ]; } } if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. $query_args['fields'] = 'ids'; // Disable priming post meta for HEAD requests to improve performance. $query_args['update_post_term_cache'] = false; $query_args['update_post_meta_cache'] = false; } $revisions_query = new WP_Query(); $revisions = $revisions_query->query( $query_args ); $offset = isset( $query_args['offset'] ) ? (int) $query_args['offset'] : 0; $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_revisions = $revisions_query->found_posts; if ( $total_revisions < 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $query_args['paged'], $query_args['offset'] ); $count_query = new WP_Query(); $count_query->query( $query_args ); $total_revisions = $count_query->found_posts; } if ( $revisions_query->query_vars['posts_per_page'] > 0 ) { $max_pages = (int) ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] ); } else { $max_pages = $total_revisions > 0 ? 1 : 0; } if ( $total_revisions > 0 ) { if ( $offset >= $total_revisions ) { return new WP_Error( 'rest_revision_invalid_offset_number', __( 'The offset number requested is larger than or equal to the number of available revisions.' ), array( 'status' => 400 ) ); } elseif ( ! $offset && $page > $max_pages ) { return new WP_Error( 'rest_revision_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } } } else { $revisions = array(); $total_revisions = 0; $max_pages = 0; $page = (int) $request['page']; } if ( ! $is_head_request ) { $response = array(); foreach ( $revisions as $revision ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } $response = rest_ensure_response( $response ); } else { $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $base_path = rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ); $base = add_query_arg( urlencode_deep( $request_params ), $base_path ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Prepares the revision for the REST response. * * @since 6.3.0 * @since 6.6.0 Added resolved URI links to the response. * * @param WP_Post $post Post revision object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object. */ public function prepare_item_for_response( $post, $request ) { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } $parent = $this->get_parent( $request['parent'] ); $global_styles_config = $this->get_decoded_global_styles_json( $post->post_content ); if ( is_wp_error( $global_styles_config ) ) { return $global_styles_config; } $fields = $this->get_fields_for_response( $request ); $data = array(); $theme_json = null; if ( ! empty( $global_styles_config['styles'] ) || ! empty( $global_styles_config['settings'] ) ) { $theme_json = new WP_Theme_JSON( $global_styles_config, 'custom' ); $global_styles_config = $theme_json->get_raw_data(); if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = ! empty( $global_styles_config['settings'] ) ? $global_styles_config['settings'] : new stdClass(); } if ( rest_is_field_included( 'styles', $fields ) ) { $data['styles'] = ! empty( $global_styles_config['styles'] ) ? $global_styles_config['styles'] : new stdClass(); } } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $post->post_author; } if ( rest_is_field_included( 'date', $fields ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( rest_is_field_included( 'date_gmt', $fields ) ) { $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt ); } if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = (int) $post->ID; } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( rest_is_field_included( 'modified_gmt', $fields ) ) { $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt ); } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = (int) $parent->ID; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json ); if ( ! empty( $resolved_theme_uris ) ) { $response->add_links( array( 'https://api.w.org/theme-file' => $resolved_theme_uris, ) ); } return $response; } /** * Retrieves the revision's schema, conforming to JSON Schema. * * @since 6.3.0 * @since 6.6.0 Merged parent and parent controller schema data. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); $parent_schema = $this->parent_controller->get_item_schema(); $schema['properties'] = array_merge( $schema['properties'], $parent_schema['properties'] ); unset( $schema['properties']['guid'], $schema['properties']['slug'], $schema['properties']['meta'], $schema['properties']['content'], $schema['properties']['title'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * Removes params that are not supported by global styles revisions. * * @since 6.6.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); unset( $query_params['exclude'], $query_params['include'], $query_params['search'], $query_params['order'], $query_params['orderby'] ); return $query_params; } } <?php /** * REST API: WP_REST_Block_Patterns_Controller class * * @package WordPress * @subpackage REST_API * @since 6.0.0 */ /** * Core class used to access block patterns via the REST API. * * @since 6.0.0 * * @see WP_REST_Controller */ class WP_REST_Block_Patterns_Controller extends WP_REST_Controller { /** * Defines whether remote patterns should be loaded. * * @since 6.0.0 * @var bool */ private $remote_patterns_loaded; /** * An array that maps old categories names to new ones. * * @since 6.2.0 * @var array */ protected static $categories_migration = array( 'buttons' => 'call-to-action', 'columns' => 'text', 'query' => 'posts', ); /** * Constructs the controller. * * @since 6.0.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-patterns/patterns'; } /** * Registers the routes for the objects of the controller. * * @since 6.0.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read block patterns. * * @since 6.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view the registered block patterns.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Retrieves all block patterns. * * @since 6.0.0 * @since 6.2.0 Added migration for old core pattern categories to the new ones. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( ! $this->remote_patterns_loaded ) { // Load block patterns from w.org. _load_remote_block_patterns(); // Patterns with the `core` keyword. _load_remote_featured_patterns(); // Patterns in the `featured` category. _register_remote_theme_patterns(); // Patterns requested by current theme. $this->remote_patterns_loaded = true; } $response = array(); $patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered(); foreach ( $patterns as $pattern ) { $migrated_pattern = $this->migrate_pattern_categories( $pattern ); $prepared_pattern = $this->prepare_item_for_response( $migrated_pattern, $request ); $response[] = $this->prepare_response_for_collection( $prepared_pattern ); } return rest_ensure_response( $response ); } /** * Migrates old core pattern categories to the new categories. * * Core pattern categories are revamped. Migration is needed to ensure * backwards compatibility. * * @since 6.2.0 * * @param array $pattern Raw pattern as registered, before applying any changes. * @return array Migrated pattern. */ protected function migrate_pattern_categories( $pattern ) { // No categories to migrate. if ( ! isset( $pattern['categories'] ) || ! is_array( $pattern['categories'] ) ) { return $pattern; } foreach ( $pattern['categories'] as $index => $category ) { // If the category exists as a key, then it needs migration. if ( isset( static::$categories_migration[ $category ] ) ) { $pattern['categories'][ $index ] = static::$categories_migration[ $category ]; } } return $pattern; } /** * Prepare a raw block pattern before it gets output in a REST API response. * * @since 6.0.0 * @since 6.3.0 Added `source` property. * * @param array $item Raw pattern as registered, before any changes. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { // Resolve pattern blocks so they don't need to be resolved client-side // in the editor, improving performance. $blocks = parse_blocks( $item['content'] ); $blocks = resolve_pattern_blocks( $blocks ); $item['content'] = serialize_blocks( $blocks ); $fields = $this->get_fields_for_response( $request ); $keys = array( 'name' => 'name', 'title' => 'title', 'content' => 'content', 'description' => 'description', 'viewportWidth' => 'viewport_width', 'inserter' => 'inserter', 'categories' => 'categories', 'keywords' => 'keywords', 'blockTypes' => 'block_types', 'postTypes' => 'post_types', 'templateTypes' => 'template_types', 'source' => 'source', ); $data = array(); foreach ( $keys as $item_key => $rest_key ) { if ( isset( $item[ $item_key ] ) && rest_is_field_included( $rest_key, $fields ) ) { $data[ $rest_key ] = $item[ $item_key ]; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); return rest_ensure_response( $data ); } /** * Retrieves the block pattern schema, conforming to JSON Schema. * * @since 6.0.0 * @since 6.3.0 Added `source` property. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-pattern', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The pattern name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'title' => array( 'description' => __( 'The pattern title, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'content' => array( 'description' => __( 'The pattern content.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The pattern detailed description.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'viewport_width' => array( 'description' => __( 'The pattern viewport width for inserter preview.' ), 'type' => 'number', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'inserter' => array( 'description' => __( 'Determines whether the pattern is visible in inserter.' ), 'type' => 'boolean', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( 'The pattern category slugs.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'keywords' => array( 'description' => __( 'The pattern keywords.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'block_types' => array( 'description' => __( 'Block types that the pattern is intended to be used with.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'post_types' => array( 'description' => __( 'An array of post types that the pattern is restricted to be used with.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'template_types' => array( 'description' => __( 'An array of template types where the pattern fits.' ), 'type' => 'array', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'source' => array( 'description' => __( 'Where the pattern comes from e.g. core' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( 'core', 'plugin', 'theme', 'pattern-directory/core', 'pattern-directory/theme', 'pattern-directory/featured', ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Menu_Locations_Controller class * * @package WordPress * @subpackage REST_API * @since 5.9.0 */ /** * Core class used to access menu locations via the REST API. * * @since 5.9.0 * * @see WP_REST_Controller */ class WP_REST_Menu_Locations_Controller extends WP_REST_Controller { /** * Menu Locations Constructor. * * @since 5.9.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'menu-locations'; } /** * Registers the routes for the objects of the controller. * * @since 5.9.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<location>[\w-]+)', array( 'args' => array( 'location' => array( 'description' => __( 'An alphanumeric identifier for the menu location.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read menu locations. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { return $this->check_has_read_only_access( $request ); } /** * Retrieves all menu locations, depending on user context. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $data = array(); foreach ( get_registered_nav_menus() as $name => $description ) { $location = new stdClass(); $location->name = $name; $location->description = $description; $location = $this->prepare_item_for_response( $location, $request ); $data[ $name ] = $this->prepare_response_for_collection( $location ); } return rest_ensure_response( $data ); } /** * Checks if a given request has access to read a menu location. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { return $this->check_has_read_only_access( $request ); } /** * Retrieves a specific menu location. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $registered_menus = get_registered_nav_menus(); if ( ! array_key_exists( $request['location'], $registered_menus ) ) { return new WP_Error( 'rest_menu_location_invalid', __( 'Invalid menu location.' ), array( 'status' => 404 ) ); } $location = new stdClass(); $location->name = $request['location']; $location->description = $registered_menus[ $location->name ]; $data = $this->prepare_item_for_response( $location, $request ); return rest_ensure_response( $data ); } /** * Checks whether the current user has read permission for the endpoint. * * @since 6.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the current user has permission, WP_Error object otherwise. */ protected function check_has_read_only_access( $request ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php */ $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu locations.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Prepares a menu location object for serialization. * * @since 5.9.0 * * @param stdClass $item Post status data. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Menu location data. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $location = $item; $locations = get_nav_menu_locations(); $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'name', $fields ) ) { $data['name'] = $location->name; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $location->description; } if ( rest_is_field_included( 'menu', $fields ) ) { $data['menu'] = (int) $menu; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $location ) ); } /** * Filters menu location data returned from the REST API. * * @since 5.9.0 * * @param WP_REST_Response $response The response object. * @param object $location The original location object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_menu_location', $response, $location, $request ); } /** * Prepares links for the request. * * @since 5.9.0 * * @param stdClass $location Menu location. * @return array Links for the given menu location. */ protected function prepare_links( $location ) { $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); // Entity meta. $links = array( 'self' => array( 'href' => rest_url( trailingslashit( $base ) . $location->name ), ), 'collection' => array( 'href' => rest_url( $base ), ), ); $locations = get_nav_menu_locations(); $menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0; if ( $menu ) { $path = rest_get_route_for_term( $menu ); if ( $path ) { $url = rest_url( $path ); $links['https://api.w.org/menu'][] = array( 'href' => $url, 'embeddable' => true, ); } } return $links; } /** * Retrieves the menu location's schema, conforming to JSON Schema. * * @since 5.9.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'menu-location', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The name of the menu location.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'The description of the menu location.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'menu' => array( 'description' => __( 'The ID of the assigned menu.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 5.9.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } } <?php /** * REST API: WP_REST_Comments_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core controller used to access comments via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Comments_Controller extends WP_REST_Controller { /** * Instance of a comment meta fields object. * * @since 4.7.0 * @var WP_REST_Comment_Meta_Fields */ protected $meta; /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'comments'; $this->meta = new WP_REST_Comment_Meta_Fields(); } /** * Registers the routes for comments. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the comment.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'password' => array( 'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ), 'type' => 'string', ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), 'password' => array( 'description' => __( 'The password for the parent post of the comment (if the post is password protected).' ), 'type' => 'string', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to read comments. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, error object otherwise. */ public function get_items_permissions_check( $request ) { if ( ! empty( $request['post'] ) ) { foreach ( (array) $request['post'] as $post_id ) { $post = get_post( $post_id ); if ( ! empty( $post_id ) && $post && ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } elseif ( 0 === $post_id && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to read comments without a post.' ), array( 'status' => rest_authorization_required_code() ) ); } } } if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit comments.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'edit_posts' ) ) { $protected_params = array( 'author', 'author_exclude', 'author_email', 'type', 'status' ); $forbidden_params = array(); foreach ( $protected_params as $param ) { if ( 'status' === $param ) { if ( 'approve' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( 'type' === $param ) { if ( 'comment' !== $request[ $param ] ) { $forbidden_params[] = $param; } } elseif ( ! empty( $request[ $param ] ) ) { $forbidden_params[] = $param; } } if ( ! empty( $forbidden_params ) ) { return new WP_Error( 'rest_forbidden_param', /* translators: %s: List of forbidden parameters. */ sprintf( __( 'Query parameter not permitted: %s' ), implode( ', ', $forbidden_params ) ), array( 'status' => rest_authorization_required_code() ) ); } } return true; } /** * Retrieves a list of comment items. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function get_items( $request ) { // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); /* * This array defines mappings between public API query parameters whose * values are accepted as-passed, and their internal WP_Query parameter * name equivalents (some are the same). Only values which are also * present in $registered will be set. */ $parameter_mappings = array( 'author' => 'author__in', 'author_email' => 'author_email', 'author_exclude' => 'author__not_in', 'exclude' => 'comment__not_in', 'include' => 'comment__in', 'offset' => 'offset', 'order' => 'order', 'parent' => 'parent__in', 'parent_exclude' => 'parent__not_in', 'per_page' => 'number', 'post' => 'post__in', 'search' => 'search', 'status' => 'status', 'type' => 'type', ); $prepared_args = array(); /* * For each known parameter which is both registered and present in the request, * set the parameter's value on the query $prepared_args. */ foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } // Ensure certain parameter values default to empty strings. foreach ( array( 'author_email', 'search' ) as $param ) { if ( ! isset( $prepared_args[ $param ] ) ) { $prepared_args[ $param ] = ''; } } if ( isset( $registered['orderby'] ) ) { $prepared_args['orderby'] = $this->normalize_query_param( $request['orderby'] ); } $prepared_args['no_found_rows'] = false; $prepared_args['update_comment_post_cache'] = true; $prepared_args['date_query'] = array(); // Set before into date query. Date query must be specified as an array of an array. if ( isset( $registered['before'], $request['before'] ) ) { $prepared_args['date_query'][0]['before'] = $request['before']; } // Set after into date query. Date query must be specified as an array of an array. if ( isset( $registered['after'], $request['after'] ) ) { $prepared_args['date_query'][0]['after'] = $request['after']; } if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. $prepared_args['fields'] = 'ids'; // Disable priming comment meta for HEAD requests to improve performance. $prepared_args['update_comment_meta_cache'] = false; } /** * Filters WP_Comment_Query arguments when querying comments via the REST API. * * @since 4.7.0 * * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ * * @param array $prepared_args Array of arguments for WP_Comment_Query. * @param WP_REST_Request $request The REST API request. */ $prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request ); $query = new WP_Comment_Query(); $query_result = $query->query( $prepared_args ); if ( ! $is_head_request ) { $comments = array(); foreach ( $query_result as $comment ) { if ( ! $this->check_read_permission( $comment, $request ) ) { continue; } $data = $this->prepare_item_for_response( $comment, $request ); $comments[] = $this->prepare_response_for_collection( $data ); } } $total_comments = (int) $query->found_comments; $max_pages = (int) $query->max_num_pages; if ( $total_comments < 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $prepared_args['number'], $prepared_args['offset'] ); $query = new WP_Comment_Query(); $prepared_args['count'] = true; $prepared_args['orderby'] = 'none'; $total_comments = $query->query( $prepared_args ); $max_pages = (int) ceil( $total_comments / $request['per_page'] ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $comments ); $response->header( 'X-WP-Total', $total_comments ); $response->header( 'X-WP-TotalPages', $max_pages ); $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $request['page'] > 1 ) { $prev_page = $request['page'] - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $request['page'] ) { $next_page = $request['page'] + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Get the comment, if the ID is valid. * * @since 4.7.2 * * @param int $id Supplied ID. * @return WP_Comment|WP_Error Comment object if ID is valid, WP_Error otherwise. */ protected function get_comment( $id ) { $error = new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $id = (int) $id; $comment = get_comment( $id ); if ( empty( $comment ) ) { return $error; } if ( ! empty( $comment->comment_post_ID ) ) { $post = get_post( (int) $comment->comment_post_ID ); if ( empty( $post ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) ); } } return $comment; } /** * Checks if a given request has access to read the comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, error object otherwise. */ public function get_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } if ( ! empty( $request['context'] ) && 'edit' === $request['context'] && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit comments.' ), array( 'status' => rest_authorization_required_code() ) ); } $post = get_post( $comment->comment_post_ID ); if ( ! $this->check_read_permission( $comment, $request ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to read this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( $post && ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function get_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $data = $this->prepare_item_for_response( $comment, $request ); $response = rest_ensure_response( $data ); return $response; } /** * Checks if a given request has access to create a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, error object otherwise. */ public function create_item_permissions_check( $request ) { if ( ! is_user_logged_in() ) { if ( get_option( 'comment_registration' ) ) { return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) ); } /** * Filters whether comments can be created via the REST API without authentication. * * Enables creating comments for anonymous users. * * @since 4.7.0 * * @param bool $allow_anonymous Whether to allow anonymous comments to * be created. Default `false`. * @param WP_REST_Request $request Request used to generate the * response. */ $allow_anonymous = apply_filters( 'rest_allow_anonymous_comments', false, $request ); if ( ! $allow_anonymous ) { return new WP_Error( 'rest_comment_login_required', __( 'Sorry, you must be logged in to comment.' ), array( 'status' => 401 ) ); } } // Limit who can set comment `author`, `author_ip` or `status` to anything other than the default. if ( isset( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_comment_invalid_author', /* translators: %s: Request parameter. */ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author' ), array( 'status' => rest_authorization_required_code() ) ); } if ( isset( $request['author_ip'] ) && ! current_user_can( 'moderate_comments' ) ) { if ( empty( $_SERVER['REMOTE_ADDR'] ) || $request['author_ip'] !== $_SERVER['REMOTE_ADDR'] ) { return new WP_Error( 'rest_comment_invalid_author_ip', /* translators: %s: Request parameter. */ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'author_ip' ), array( 'status' => rest_authorization_required_code() ) ); } } if ( isset( $request['status'] ) && ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_comment_invalid_status', /* translators: %s: Request parameter. */ sprintf( __( "Sorry, you are not allowed to edit '%s' for comments." ), 'status' ), array( 'status' => rest_authorization_required_code() ) ); } if ( empty( $request['post'] ) ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Sorry, you are not allowed to create this comment without a post.' ), array( 'status' => 403 ) ); } $post = get_post( (int) $request['post'] ); if ( ! $post ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Sorry, you are not allowed to create this comment without a post.' ), array( 'status' => 403 ) ); } if ( 'draft' === $post->post_status ) { return new WP_Error( 'rest_comment_draft_post', __( 'Sorry, you are not allowed to create a comment on this post.' ), array( 'status' => 403 ) ); } if ( 'trash' === $post->post_status ) { return new WP_Error( 'rest_comment_trash_post', __( 'Sorry, you are not allowed to create a comment on this post.' ), array( 'status' => 403 ) ); } if ( ! $this->check_read_post_permission( $post, $request ) ) { return new WP_Error( 'rest_cannot_read_post', __( 'Sorry, you are not allowed to read the post for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! comments_open( $post->ID ) ) { return new WP_Error( 'rest_comment_closed', __( 'Sorry, comments are closed for this item.' ), array( 'status' => 403 ) ); } return true; } /** * Creates a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_comment_exists', __( 'Cannot create existing comment.' ), array( 'status' => 400 ) ); } // Do not allow comments to be created with a non-default type. if ( ! empty( $request['type'] ) && 'comment' !== $request['type'] ) { return new WP_Error( 'rest_invalid_comment_type', __( 'Cannot create a comment with that type.' ), array( 'status' => 400 ) ); } $prepared_comment = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_comment ) ) { return $prepared_comment; } $prepared_comment['comment_type'] = 'comment'; if ( ! isset( $prepared_comment['comment_content'] ) ) { $prepared_comment['comment_content'] = ''; } if ( ! $this->check_is_comment_content_allowed( $prepared_comment ) ) { return new WP_Error( 'rest_comment_content_invalid', __( 'Invalid comment content.' ), array( 'status' => 400 ) ); } // Setting remaining values before wp_insert_comment so we can use wp_allow_comment(). if ( ! isset( $prepared_comment['comment_date_gmt'] ) ) { $prepared_comment['comment_date_gmt'] = current_time( 'mysql', true ); } // Set author data if the user's logged in. $missing_author = empty( $prepared_comment['user_id'] ) && empty( $prepared_comment['comment_author'] ) && empty( $prepared_comment['comment_author_email'] ) && empty( $prepared_comment['comment_author_url'] ); if ( is_user_logged_in() && $missing_author ) { $user = wp_get_current_user(); $prepared_comment['user_id'] = $user->ID; $prepared_comment['comment_author'] = $user->display_name; $prepared_comment['comment_author_email'] = $user->user_email; $prepared_comment['comment_author_url'] = $user->user_url; } // Honor the discussion setting that requires a name and email address of the comment author. if ( get_option( 'require_name_email' ) ) { if ( empty( $prepared_comment['comment_author'] ) || empty( $prepared_comment['comment_author_email'] ) ) { return new WP_Error( 'rest_comment_author_data_required', __( 'Creating a comment requires valid author name and email values.' ), array( 'status' => 400 ) ); } } if ( ! isset( $prepared_comment['comment_author_email'] ) ) { $prepared_comment['comment_author_email'] = ''; } if ( ! isset( $prepared_comment['comment_author_url'] ) ) { $prepared_comment['comment_author_url'] = ''; } if ( ! isset( $prepared_comment['comment_agent'] ) ) { $prepared_comment['comment_agent'] = ''; } $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_comment ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = $check_comment_lengths->get_error_code(); return new WP_Error( $error_code, __( 'Comment field exceeds maximum length allowed.' ), array( 'status' => 400 ) ); } $prepared_comment['comment_approved'] = wp_allow_comment( $prepared_comment, true ); if ( is_wp_error( $prepared_comment['comment_approved'] ) ) { $error_code = $prepared_comment['comment_approved']->get_error_code(); $error_message = $prepared_comment['comment_approved']->get_error_message(); if ( 'comment_duplicate' === $error_code ) { return new WP_Error( $error_code, $error_message, array( 'status' => 409 ) ); } if ( 'comment_flood' === $error_code ) { return new WP_Error( $error_code, $error_message, array( 'status' => 400 ) ); } return $prepared_comment['comment_approved']; } /** * Filters a comment before it is inserted via the REST API. * * Allows modification of the comment right before it is inserted via wp_insert_comment(). * Returning a WP_Error value from the filter will short-circuit insertion and allow * skipping further processing. * * @since 4.7.0 * @since 4.8.0 `$prepared_comment` can now be a WP_Error to short-circuit insertion. * * @param array|WP_Error $prepared_comment The prepared comment data for wp_insert_comment(). * @param WP_REST_Request $request Request used to insert the comment. */ $prepared_comment = apply_filters( 'rest_pre_insert_comment', $prepared_comment, $request ); if ( is_wp_error( $prepared_comment ) ) { return $prepared_comment; } $comment_id = wp_insert_comment( wp_filter_comment( wp_slash( (array) $prepared_comment ) ) ); if ( ! $comment_id ) { return new WP_Error( 'rest_comment_failed_create', __( 'Creating comment failed.' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { $this->handle_status_param( $request['status'], $comment_id ); } $comment = get_comment( $comment_id ); /** * Fires after a comment is created or updated via the REST API. * * @since 4.7.0 * * @param WP_Comment $comment Inserted or updated comment object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a comment, false * when updating. */ do_action( 'rest_insert_comment', $comment, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $comment_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $comment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $context = current_user_can( 'moderate_comments' ) ? 'edit' : 'view'; $request->set_param( 'context', $context ); /** * Fires completely after a comment is created or updated via the REST API. * * @since 5.0.0 * * @param WP_Comment $comment Inserted or updated comment object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a comment, false * when updating. */ do_action( 'rest_after_insert_comment', $comment, $request, true ); $response = $this->prepare_item_for_response( $comment, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment_id ) ) ); return $response; } /** * Checks if a given REST request has access to update a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, error object otherwise. */ public function update_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } if ( ! $this->check_edit_permission( $comment ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function update_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $id = $comment->comment_ID; if ( isset( $request['type'] ) && get_comment_type( $id ) !== $request['type'] ) { return new WP_Error( 'rest_comment_invalid_type', __( 'Sorry, you are not allowed to change the comment type.' ), array( 'status' => 404 ) ); } $prepared_args = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_args ) ) { return $prepared_args; } if ( ! empty( $prepared_args['comment_post_ID'] ) ) { $post = get_post( $prepared_args['comment_post_ID'] ); if ( empty( $post ) ) { return new WP_Error( 'rest_comment_invalid_post_id', __( 'Invalid post ID.' ), array( 'status' => 403 ) ); } } if ( empty( $prepared_args ) && isset( $request['status'] ) ) { // Only the comment status is being changed. $change = $this->handle_status_param( $request['status'], $id ); if ( ! $change ) { return new WP_Error( 'rest_comment_failed_edit', __( 'Updating comment status failed.' ), array( 'status' => 500 ) ); } } elseif ( ! empty( $prepared_args ) ) { if ( is_wp_error( $prepared_args ) ) { return $prepared_args; } if ( isset( $prepared_args['comment_content'] ) && empty( $prepared_args['comment_content'] ) ) { return new WP_Error( 'rest_comment_content_invalid', __( 'Invalid comment content.' ), array( 'status' => 400 ) ); } $prepared_args['comment_ID'] = $id; $check_comment_lengths = wp_check_comment_data_max_lengths( $prepared_args ); if ( is_wp_error( $check_comment_lengths ) ) { $error_code = $check_comment_lengths->get_error_code(); return new WP_Error( $error_code, __( 'Comment field exceeds maximum length allowed.' ), array( 'status' => 400 ) ); } $updated = wp_update_comment( wp_slash( (array) $prepared_args ), true ); if ( is_wp_error( $updated ) ) { return new WP_Error( 'rest_comment_failed_edit', __( 'Updating comment failed.' ), array( 'status' => 500 ) ); } if ( isset( $request['status'] ) ) { $this->handle_status_param( $request['status'], $id ); } } $comment = get_comment( $id ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */ do_action( 'rest_insert_comment', $comment, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $fields_update = $this->update_additional_fields_for_object( $comment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */ do_action( 'rest_after_insert_comment', $comment, $request, false ); $response = $this->prepare_item_for_response( $comment, $request ); return rest_ensure_response( $response ); } /** * Checks if a given request has access to delete a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, error object otherwise. */ public function delete_item_permissions_check( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } if ( ! $this->check_edit_permission( $comment ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes a comment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or error object on failure. */ public function delete_item( $request ) { $comment = $this->get_comment( $request['id'] ); if ( is_wp_error( $comment ) ) { return $comment; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; /** * Filters whether a comment can be trashed via the REST API. * * Return false to disable trash support for the comment. * * @since 4.7.0 * * @param bool $supports_trash Whether the comment supports trashing. * @param WP_Comment $comment The comment object being considered for trashing support. */ $supports_trash = apply_filters( 'rest_comment_trashable', ( EMPTY_TRASH_DAYS > 0 ), $comment ); $request->set_param( 'context', 'edit' ); if ( $force ) { $previous = $this->prepare_item_for_response( $comment, $request ); $result = wp_delete_comment( $comment->comment_ID, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { // If this type doesn't support trashing, error out. if ( ! $supports_trash ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( "The comment does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } if ( 'trash' === $comment->comment_approved ) { return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) ); } $result = wp_trash_comment( $comment->comment_ID ); $comment = get_comment( $comment->comment_ID ); $response = $this->prepare_item_for_response( $comment, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The comment cannot be deleted.' ), array( 'status' => 500 ) ); } /** * Fires after a comment is deleted via the REST API. * * @since 4.7.0 * * @param WP_Comment $comment The deleted comment data. * @param WP_REST_Response $response The response returned from the API. * @param WP_REST_Request $request The request sent to the API. */ do_action( 'rest_delete_comment', $comment, $response, $request ); return $response; } /** * Prepares a single comment output for response. * * @since 4.7.0 * @since 5.9.0 Renamed `$comment` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_Comment $item Comment object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $comment = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */ return apply_filters( 'rest_prepare_comment', new WP_REST_Response( array() ), $comment, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = (int) $comment->comment_ID; } if ( in_array( 'post', $fields, true ) ) { $data['post'] = (int) $comment->comment_post_ID; } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $comment->comment_parent; } if ( in_array( 'author', $fields, true ) ) { $data['author'] = (int) $comment->user_id; } if ( in_array( 'author_name', $fields, true ) ) { $data['author_name'] = $comment->comment_author; } if ( in_array( 'author_email', $fields, true ) ) { $data['author_email'] = $comment->comment_author_email; } if ( in_array( 'author_url', $fields, true ) ) { $data['author_url'] = $comment->comment_author_url; } if ( in_array( 'author_ip', $fields, true ) ) { $data['author_ip'] = $comment->comment_author_IP; } if ( in_array( 'author_user_agent', $fields, true ) ) { $data['author_user_agent'] = $comment->comment_agent; } if ( in_array( 'date', $fields, true ) ) { $data['date'] = mysql_to_rfc3339( $comment->comment_date ); } if ( in_array( 'date_gmt', $fields, true ) ) { $data['date_gmt'] = mysql_to_rfc3339( $comment->comment_date_gmt ); } if ( in_array( 'content', $fields, true ) ) { $data['content'] = array( /** This filter is documented in wp-includes/comment-template.php */ 'rendered' => apply_filters( 'comment_text', $comment->comment_content, $comment, array() ), 'raw' => $comment->comment_content, ); } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_comment_link( $comment ); } if ( in_array( 'status', $fields, true ) ) { $data['status'] = $this->prepare_status_response( $comment->comment_approved ); } if ( in_array( 'type', $fields, true ) ) { $data['type'] = get_comment_type( $comment->comment_ID ); } if ( in_array( 'author_avatar_urls', $fields, true ) ) { $data['author_avatar_urls'] = rest_get_avatar_urls( $comment ); } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $comment->comment_ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $comment ) ); } /** * Filters a comment returned from the REST API. * * Allows modification of the comment right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Comment $comment The original comment object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_comment', $response, $comment, $request ); } /** * Prepares links for the request. * * @since 4.7.0 * * @param WP_Comment $comment Comment object. * @return array Links for the given comment. */ protected function prepare_links( $comment ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); if ( 0 !== (int) $comment->user_id ) { $links['author'] = array( 'href' => rest_url( 'wp/v2/users/' . $comment->user_id ), 'embeddable' => true, ); } if ( 0 !== (int) $comment->comment_post_ID ) { $post = get_post( $comment->comment_post_ID ); $post_route = rest_get_route_for_post( $post ); if ( ! empty( $post->ID ) && $post_route ) { $links['up'] = array( 'href' => rest_url( $post_route ), 'embeddable' => true, 'post_type' => $post->post_type, ); } } if ( 0 !== (int) $comment->comment_parent ) { $links['in-reply-to'] = array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $comment->comment_parent ) ), 'embeddable' => true, ); } // Only grab one comment to verify the comment has children. $comment_children = $comment->get_children( array( 'count' => true, 'orderby' => 'none', ) ); if ( ! empty( $comment_children ) ) { $args = array( 'parent' => $comment->comment_ID, ); $rest_url = add_query_arg( $args, rest_url( $this->namespace . '/' . $this->rest_base ) ); $links['children'] = array( 'href' => $rest_url, 'embeddable' => true, ); } return $links; } /** * Prepends internal property prefix to query parameters to match our response fields. * * @since 4.7.0 * * @param string $query_param Query parameter. * @return string The normalized query parameter. */ protected function normalize_query_param( $query_param ) { $prefix = 'comment_'; switch ( $query_param ) { case 'id': $normalized = $prefix . 'ID'; break; case 'post': $normalized = $prefix . 'post_ID'; break; case 'parent': $normalized = $prefix . 'parent'; break; case 'include': $normalized = 'comment__in'; break; default: $normalized = $prefix . $query_param; break; } return $normalized; } /** * Checks comment_approved to set comment status for single comment output. * * @since 4.7.0 * * @param string $comment_approved Comment status. * @return string Comment status. */ protected function prepare_status_response( $comment_approved ) { switch ( $comment_approved ) { case 'hold': case '0': $status = 'hold'; break; case 'approve': case '1': $status = 'approved'; break; case 'spam': case 'trash': default: $status = $comment_approved; break; } return $status; } /** * Prepares a single comment to be inserted into the database. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return array|WP_Error Prepared comment, otherwise WP_Error object. */ protected function prepare_item_for_database( $request ) { $prepared_comment = array(); /* * Allow the comment_content to be set via the 'content' or * the 'content.raw' properties of the Request object. */ if ( isset( $request['content'] ) && is_string( $request['content'] ) ) { $prepared_comment['comment_content'] = trim( $request['content'] ); } elseif ( isset( $request['content']['raw'] ) && is_string( $request['content']['raw'] ) ) { $prepared_comment['comment_content'] = trim( $request['content']['raw'] ); } if ( isset( $request['post'] ) ) { $prepared_comment['comment_post_ID'] = (int) $request['post']; } if ( isset( $request['parent'] ) ) { $prepared_comment['comment_parent'] = $request['parent']; } if ( isset( $request['author'] ) ) { $user = new WP_User( $request['author'] ); if ( $user->exists() ) { $prepared_comment['user_id'] = $user->ID; $prepared_comment['comment_author'] = $user->display_name; $prepared_comment['comment_author_email'] = $user->user_email; $prepared_comment['comment_author_url'] = $user->user_url; } else { return new WP_Error( 'rest_comment_author_invalid', __( 'Invalid comment author ID.' ), array( 'status' => 400 ) ); } } if ( isset( $request['author_name'] ) ) { $prepared_comment['comment_author'] = $request['author_name']; } if ( isset( $request['author_email'] ) ) { $prepared_comment['comment_author_email'] = $request['author_email']; } if ( isset( $request['author_url'] ) ) { $prepared_comment['comment_author_url'] = $request['author_url']; } if ( isset( $request['author_ip'] ) && current_user_can( 'moderate_comments' ) ) { $prepared_comment['comment_author_IP'] = $request['author_ip']; } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) && rest_is_ip_address( $_SERVER['REMOTE_ADDR'] ) ) { $prepared_comment['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; } else { $prepared_comment['comment_author_IP'] = '127.0.0.1'; } if ( ! empty( $request['author_user_agent'] ) ) { $prepared_comment['comment_agent'] = $request['author_user_agent']; } elseif ( $request->get_header( 'user_agent' ) ) { $prepared_comment['comment_agent'] = $request->get_header( 'user_agent' ); } if ( ! empty( $request['date'] ) ) { $date_data = rest_get_date_with_gmt( $request['date'] ); if ( ! empty( $date_data ) ) { list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; } } elseif ( ! empty( $request['date_gmt'] ) ) { $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) ) { list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; } } /** * Filters a comment added via the REST API after it is prepared for insertion into the database. * * Allows modification of the comment right after it is prepared for the database. * * @since 4.7.0 * * @param array $prepared_comment The prepared comment data for `wp_insert_comment`. * @param WP_REST_Request $request The current request. */ return apply_filters( 'rest_preprocess_comment', $prepared_comment, $request ); } /** * Retrieves the comment's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'comment', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the comment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'author' => array( 'description' => __( 'The ID of the user object, if author was a user.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'author_email' => array( 'description' => __( 'Email address for the comment author.' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_comment_author_email' ), 'validate_callback' => null, // Skip built-in validation of 'email'. ), ), 'author_ip' => array( 'description' => __( 'IP address for the comment author.' ), 'type' => 'string', 'format' => 'ip', 'context' => array( 'edit' ), ), 'author_name' => array( 'description' => __( 'Display name for the comment author.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'author_url' => array( 'description' => __( 'URL for the comment author.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), ), 'author_user_agent' => array( 'description' => __( 'User agent for the comment author.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'content' => array( 'description' => __( 'The content for the comment.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the comment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML content for the comment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), 'date' => array( 'description' => __( "The date the comment was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the comment was published, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'link' => array( 'description' => __( 'URL to the comment.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'parent' => array( 'description' => __( 'The ID for the parent of the comment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'default' => 0, ), 'post' => array( 'description' => __( 'The ID of the associated post object.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), 'default' => 0, ), 'status' => array( 'description' => __( 'State of the comment.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_key', ), ), 'type' => array( 'description' => __( 'Type of the comment.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); if ( get_option( 'show_avatars' ) ) { $avatar_properties = array(); $avatar_sizes = rest_get_avatar_sizes(); foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( /* translators: %d: Avatar image size in pixels. */ 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['author_avatar_urls'] = array( 'description' => __( 'Avatar URLs for the comment author.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, 'properties' => $avatar_properties, ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Comments collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['after'] = array( 'description' => __( 'Limit response to comments published after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['author'] = array( 'description' => __( 'Limit result set to comments assigned to specific user IDs. Requires authorization.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['author_exclude'] = array( 'description' => __( 'Ensure result set excludes comments assigned to specific user IDs. Requires authorization.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['author_email'] = array( 'default' => null, 'description' => __( 'Limit result set to that from a specific author email. Requires authorization.' ), 'format' => 'email', 'type' => 'string', ); $query_params['before'] = array( 'description' => __( 'Limit response to comments published before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc', ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by comment attribute.' ), 'type' => 'string', 'default' => 'date_gmt', 'enum' => array( 'date', 'date_gmt', 'id', 'include', 'post', 'parent', 'type', ), ); $query_params['parent'] = array( 'default' => array(), 'description' => __( 'Limit result set to comments of specific parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['parent_exclude'] = array( 'default' => array(), 'description' => __( 'Ensure result set excludes specific parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['post'] = array( 'default' => array(), 'description' => __( 'Limit result set to comments assigned to specific post IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ); $query_params['status'] = array( 'default' => 'approve', 'description' => __( 'Limit result set to comments assigned a specific status. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $query_params['type'] = array( 'default' => 'comment', 'description' => __( 'Limit result set to comments assigned a specific type. Requires authorization.' ), 'sanitize_callback' => 'sanitize_key', 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', ); $query_params['password'] = array( 'description' => __( 'The password for the post if it is password protected.' ), 'type' => 'string', ); /** * Filters REST API collection parameters for the comments controller. * * This filter registers the collection parameter, but does not map the * collection parameter to an internal WP_Comment_Query parameter. Use the * `rest_comment_query` filter to set WP_Comment_Query parameters. * * @since 4.7.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_comment_collection_params', $query_params ); } /** * Sets the comment_status of a given comment object when creating or updating a comment. * * @since 4.7.0 * * @param string|int $new_status New comment status. * @param int $comment_id Comment ID. * @return bool Whether the status was changed. */ protected function handle_status_param( $new_status, $comment_id ) { $old_status = wp_get_comment_status( $comment_id ); if ( $new_status === $old_status ) { return false; } switch ( $new_status ) { case 'approved': case 'approve': case '1': $changed = wp_set_comment_status( $comment_id, 'approve' ); break; case 'hold': case '0': $changed = wp_set_comment_status( $comment_id, 'hold' ); break; case 'spam': $changed = wp_spam_comment( $comment_id ); break; case 'unspam': $changed = wp_unspam_comment( $comment_id ); break; case 'trash': $changed = wp_trash_comment( $comment_id ); break; case 'untrash': $changed = wp_untrash_comment( $comment_id ); break; default: $changed = false; break; } return $changed; } /** * Checks if the post can be read. * * Correctly handles posts with the inherit status. * * @since 4.7.0 * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request data to check. * @return bool Whether post can be read. */ protected function check_read_post_permission( $post, $request ) { $post_type = get_post_type_object( $post->post_type ); // Return false if custom post type doesn't exist if ( ! $post_type ) { return false; } $posts_controller = $post_type->get_rest_controller(); /* * Ensure the posts controller is specifically a WP_REST_Posts_Controller instance * before using methods specific to that controller. */ if ( ! $posts_controller instanceof WP_REST_Posts_Controller ) { $posts_controller = new WP_REST_Posts_Controller( $post->post_type ); } $has_password_filter = false; // Only check password if a specific post was queried for or a single comment $requested_post = ! empty( $request['post'] ) && ( ! is_array( $request['post'] ) || 1 === count( $request['post'] ) ); $requested_comment = ! empty( $request['id'] ); if ( ( $requested_post || $requested_comment ) && $posts_controller->can_access_password_content( $post, $request ) ) { add_filter( 'post_password_required', '__return_false' ); $has_password_filter = true; } if ( post_password_required( $post ) ) { $result = current_user_can( 'edit_post', $post->ID ); } else { $result = $posts_controller->check_read_permission( $post ); } if ( $has_password_filter ) { remove_filter( 'post_password_required', '__return_false' ); } return $result; } /** * Checks if the comment can be read. * * @since 4.7.0 * * @param WP_Comment $comment Comment object. * @param WP_REST_Request $request Request data to check. * @return bool Whether the comment can be read. */ protected function check_read_permission( $comment, $request ) { if ( ! empty( $comment->comment_post_ID ) ) { $post = get_post( $comment->comment_post_ID ); if ( $post ) { if ( $this->check_read_post_permission( $post, $request ) && 1 === (int) $comment->comment_approved ) { return true; } } } if ( 0 === get_current_user_id() ) { return false; } if ( empty( $comment->comment_post_ID ) && ! current_user_can( 'moderate_comments' ) ) { return false; } if ( ! empty( $comment->user_id ) && get_current_user_id() === (int) $comment->user_id ) { return true; } return current_user_can( 'edit_comment', $comment->comment_ID ); } /** * Checks if a comment can be edited or deleted. * * @since 4.7.0 * * @param WP_Comment $comment Comment object. * @return bool Whether the comment can be edited or deleted. */ protected function check_edit_permission( $comment ) { if ( 0 === (int) get_current_user_id() ) { return false; } if ( current_user_can( 'moderate_comments' ) ) { return true; } return current_user_can( 'edit_comment', $comment->comment_ID ); } /** * Checks a comment author email for validity. * * Accepts either a valid email address or empty string as a valid comment * author email address. Setting the comment author email to an empty * string is allowed when a comment is being updated. * * @since 4.7.0 * * @param string $value Author email value submitted. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter name. * @return string|WP_Error The sanitized email address, if valid, * otherwise an error. */ public function check_comment_author_email( $value, $request, $param ) { $email = (string) $value; if ( empty( $email ) ) { return $email; } $check_email = rest_validate_request_arg( $email, $request, $param ); if ( is_wp_error( $check_email ) ) { return $check_email; } return $email; } /** * If empty comments are not allowed, checks if the provided comment content is not empty. * * @since 5.6.0 * * @param array $prepared_comment The prepared comment data. * @return bool True if the content is allowed, false otherwise. */ protected function check_is_comment_content_allowed( $prepared_comment ) { $check = wp_parse_args( $prepared_comment, array( 'comment_post_ID' => 0, 'comment_author' => null, 'comment_author_email' => null, 'comment_author_url' => null, 'comment_parent' => 0, 'user_id' => 0, ) ); /** This filter is documented in wp-includes/comment.php */ $allow_empty = apply_filters( 'allow_empty_comment', false, $check ); if ( $allow_empty ) { return true; } /* * Do not allow a comment to be created with missing or empty * comment_content. See wp_handle_comment_submission(). */ return '' !== $check['comment_content']; } } <?php /** * REST API: WP_REST_Autosaves_Controller class. * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core class used to access autosaves via the REST API. * * @since 5.0.0 * * @see WP_REST_Revisions_Controller * @see WP_REST_Controller */ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { /** * Parent post type. * * @since 5.0.0 * @var string */ private $parent_post_type; /** * Parent post controller. * * @since 5.0.0 * @var WP_REST_Controller */ private $parent_controller; /** * Revision controller. * * @since 5.0.0 * @var WP_REST_Revisions_Controller */ private $revisions_controller; /** * The base of the parent controller's route. * * @since 5.0.0 * @var string */ private $parent_base; /** * Constructor. * * @since 5.0.0 * * @param string $parent_post_type Post type of the parent. */ public function __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(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Posts_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $revisions_controller = $post_type_object->get_revisions_rest_controller(); if ( ! $revisions_controller ) { $revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type ); } $this->revisions_controller = $revisions_controller; $this->rest_base = 'autosaves'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** * Registers the routes for autosaves. * * @since 5.0.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<id>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the autosave.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'The ID for the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get the parent post. * * @since 5.0.0 * * @param int $parent_id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_parent( $parent_id ) { return $this->revisions_controller->get_parent( $parent_id ); } /** * Checks if a given request has access to get autosaves. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $parent = $this->get_parent( $request['id'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'edit_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view autosaves of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Checks if a given request has access to create an autosave revision. * * Autosave revisions inherit permissions from the parent post, * check if the current user has permission to edit the post. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create the item, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { $id = $request->get_param( 'id' ); if ( empty( $id ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid item ID.' ), array( 'status' => 404 ) ); } return $this->parent_controller->update_item_permissions_check( $request ); } /** * Creates, updates or deletes an autosave revision. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( ! defined( 'WP_RUN_CORE_TESTS' ) && ! defined( 'DOING_AUTOSAVE' ) ) { define( 'DOING_AUTOSAVE', true ); } $post = $this->get_parent( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $prepared_post = $this->parent_controller->prepare_item_for_database( $request ); $prepared_post->ID = $post->ID; $user_id = get_current_user_id(); // We need to check post lock to ensure the original author didn't leave their browser tab open. if ( ! function_exists( 'wp_check_post_lock' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; } $post_lock = wp_check_post_lock( $post->ID ); $is_draft = 'draft' === $post->post_status || 'auto-draft' === $post->post_status; if ( $is_draft && (int) $post->post_author === $user_id && ! $post_lock ) { /* * Draft posts for the same author: autosaving updates the post and does not create a revision. * Convert the post object to an array and add slashes, wp_update_post() expects escaped array. */ $autosave_id = wp_update_post( wp_slash( (array) $prepared_post ), true ); } else { // Non-draft posts: create or update the post autosave. Pass the meta data. $autosave_id = $this->create_post_autosave( (array) $prepared_post, (array) $request->get_param( 'meta' ) ); } if ( is_wp_error( $autosave_id ) ) { return $autosave_id; } $autosave = get_post( $autosave_id ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $autosave, $request ); $response = rest_ensure_response( $response ); return $response; } /** * Get the autosave, if the ID is valid. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. */ public function get_item( $request ) { $parent_id = (int) $request->get_param( 'parent' ); if ( $parent_id <= 0 ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) ); } $autosave = wp_get_post_autosave( $parent_id ); if ( ! $autosave ) { return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this post.' ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $autosave, $request ); return $response; } /** * Gets a collection of autosaves using wp_get_post_autosave. * * Contains the user's autosave, for empty if it doesn't exist. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $parent = $this->get_parent( $request['id'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $response = array(); $parent_id = $parent->ID; $revisions = wp_get_post_revisions( $parent_id, array( 'check_enabled' => false ) ); foreach ( $revisions as $revision ) { if ( str_contains( $revision->post_name, "{$parent_id}-autosave" ) ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } } return rest_ensure_response( $response ); } /** * Retrieves the autosave's schema, conforming to JSON Schema. * * @since 5.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = $this->revisions_controller->get_item_schema(); $schema['properties']['preview_link'] = array( 'description' => __( 'Preview link for the post.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'edit' ), 'readonly' => true, ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Creates autosave for the specified post. * * From wp-admin/post.php. * * @since 5.0.0 * @since 6.4.0 The `$meta` parameter was added. * * @param array $post_data Associative array containing the post data. * @param array $meta Associative array containing the post meta data. * @return mixed The autosave revision ID or WP_Error. */ public function create_post_autosave( $post_data, array $meta = array() ) { $post_id = (int) $post_data['ID']; $post = get_post( $post_id ); if ( is_wp_error( $post ) ) { return $post; } // Only create an autosave when it is different from the saved post. $autosave_is_different = false; $new_autosave = _wp_post_revision_data( $post_data, true ); foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { if ( normalize_whitespace( $new_autosave[ $field ] ) !== normalize_whitespace( $post->$field ) ) { $autosave_is_different = true; break; } } // Check if meta values have changed. if ( ! empty( $meta ) ) { $revisioned_meta_keys = wp_post_revision_meta_keys( $post->post_type ); foreach ( $revisioned_meta_keys as $meta_key ) { // get_metadata_raw is used to avoid retrieving the default value. $old_meta = get_metadata_raw( 'post', $post_id, $meta_key, true ); $new_meta = isset( $meta[ $meta_key ] ) ? $meta[ $meta_key ] : ''; if ( $new_meta !== $old_meta ) { $autosave_is_different = true; break; } } } $user_id = get_current_user_id(); // Store one autosave per author. If there is already an autosave, overwrite it. $old_autosave = wp_get_post_autosave( $post_id, $user_id ); if ( ! $autosave_is_different && $old_autosave ) { // Nothing to save, return the existing autosave. return $old_autosave->ID; } if ( $old_autosave ) { $new_autosave['ID'] = $old_autosave->ID; $new_autosave['post_author'] = $user_id; /** This filter is documented in wp-admin/post.php */ do_action( 'wp_creating_autosave', $new_autosave ); // wp_update_post() expects escaped array. $revision_id = wp_update_post( wp_slash( $new_autosave ) ); } else { // Create the new autosave as a special post revision. $revision_id = _wp_put_post_revision( $post_data, true ); } if ( is_wp_error( $revision_id ) || 0 === $revision_id ) { return $revision_id; } // Attached any passed meta values that have revisions enabled. if ( ! empty( $meta ) ) { foreach ( $revisioned_meta_keys as $meta_key ) { if ( isset( $meta[ $meta_key ] ) ) { update_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta[ $meta_key ] ) ); } } } return $revision_id; } /** * Prepares the revision for the REST response. * * @since 5.0.0 * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_Post $item Post revision object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $post = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php */ return apply_filters( 'rest_prepare_autosave', new WP_REST_Response( array() ), $post, $request ); } $response = $this->revisions_controller->prepare_item_for_response( $post, $request ); $fields = $this->get_fields_for_response( $request ); if ( in_array( 'preview_link', $fields, true ) ) { $parent_id = wp_is_post_autosave( $post ); $preview_post_id = false === $parent_id ? $post->ID : $parent_id; $preview_query_args = array(); if ( false !== $parent_id ) { $preview_query_args['preview_id'] = $parent_id; $preview_query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $parent_id ); } $response->data['preview_link'] = get_preview_post_link( $preview_post_id, $preview_query_args ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $response->data = $this->add_additional_fields_to_object( $response->data, $request ); $response->data = $this->filter_response_by_context( $response->data, $context ); /** * Filters a revision returned from the REST API. * * Allows modification of the revision right before it is returned. * * @since 5.0.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post The original revision object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_autosave', $response, $post, $request ); } /** * Retrieves the query params for the autosaves collection. * * @since 5.0.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } } <?php /** * REST API: WP_REST_Block_Pattern_Categories_Controller class * * @package WordPress * @subpackage REST_API * @since 6.0.0 */ /** * Core class used to access block pattern categories via the REST API. * * @since 6.0.0 * * @see WP_REST_Controller */ class WP_REST_Block_Pattern_Categories_Controller extends WP_REST_Controller { /** * Constructs the controller. * * @since 6.0.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-patterns/categories'; } /** * Registers the routes for the objects of the controller. * * @since 6.0.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read block patterns. * * @since 6.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view the registered block pattern categories.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Retrieves all block pattern categories. * * @since 6.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $response = array(); $categories = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); foreach ( $categories as $category ) { $prepared_category = $this->prepare_item_for_response( $category, $request ); $response[] = $this->prepare_response_for_collection( $prepared_category ); } return rest_ensure_response( $response ); } /** * Prepare a raw block pattern category before it gets output in a REST API response. * * @since 6.0.0 * * @param array $item Raw category as registered, before any changes. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $keys = array( 'name', 'label', 'description' ); $data = array(); foreach ( $keys as $key ) { if ( isset( $item[ $key ] ) && rest_is_field_included( $key, $fields ) ) { $data[ $key ] = $item[ $key ]; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); return rest_ensure_response( $data ); } /** * Retrieves the block pattern category schema, conforming to JSON Schema. * * @since 6.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'block-pattern-category', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The category name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'label' => array( 'description' => __( 'The category label, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The category description, in human readable format.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Templates_Controller class * * @package WordPress * @subpackage REST_API * @since 5.8.0 */ /** * Base Templates REST API Controller. * * @since 5.8.0 * * @see WP_REST_Controller */ class WP_REST_Templates_Controller extends WP_REST_Controller { /** * Post type. * * @since 5.8.0 * @var string */ protected $post_type; /** * Constructor. * * @since 5.8.0 * * @param string $post_type Post type. */ public function __construct( $post_type ) { $this->post_type = $post_type; $obj = get_post_type_object( $post_type ); $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; } /** * Registers the controllers routes. * * @since 5.8.0 * @since 6.1.0 Endpoint for fallback template content. */ public function register_routes() { // Lists all templates. register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); // Get fallback template content. register_rest_route( $this->namespace, '/' . $this->rest_base . '/lookup', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_template_fallback' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'slug' => array( 'description' => __( 'The slug of the template to get the fallback for' ), 'type' => 'string', 'required' => true, ), 'is_custom' => array( 'description' => __( 'Indicates if a template is custom or part of the template hierarchy' ), 'type' => 'boolean', ), 'template_prefix' => array( 'description' => __( 'The template prefix for the created template. This is used to extract the main template type, e.g. in `taxonomy-books` extracts the `taxonomy`' ), 'type' => 'string', ), ), ), ) ); // Lists/updates a single template based on the given id. register_rest_route( $this->namespace, // The route. sprintf( '/%s/(?P<id>%s%s)', $this->rest_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', // Matches the template name. '[\/\w%-]+' ), array( 'args' => array( 'id' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Returns the fallback template for the given slug. * * @since 6.1.0 * @since 6.3.0 Ignore empty templates. * * @param WP_REST_Request $request The request instance. * @return WP_REST_Response|WP_Error */ public function get_template_fallback( $request ) { $hierarchy = get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); do { $fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' ); array_shift( $hierarchy ); } while ( ! empty( $hierarchy ) && empty( $fallback_template->content ) ); // To maintain original behavior, return an empty object rather than a 404 error when no template is found. $response = $fallback_template ? $this->prepare_item_for_response( $fallback_template, $request ) : new stdClass(); return rest_ensure_response( $response ); } /** * Checks if the user has permissions to make the request. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ protected function permissions_check( $request ) { /* * Verify if the current user has edit_theme_options capability. * This capability is required to edit/view/delete templates. */ if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } /** * Requesting this endpoint for a template like 'twentytwentytwo//home' * requires using a path like /wp/v2/templates/twentytwentytwo//home. There * are special cases when WordPress routing corrects the name to contain * only a single slash like 'twentytwentytwo/home'. * * This method doubles the last slash if it's not already doubled. It relies * on the template ID format {theme_name}//{template_slug} and the fact that * slugs cannot contain slashes. * * @since 5.9.0 * @see https://core.trac.wordpress.org/ticket/54507 * * @param string $id Template ID. * @return string Sanitized template ID. */ public function _sanitize_template_id( $id ) { $id = urldecode( $id ); $last_slash_pos = strrpos( $id, '/' ); if ( false === $last_slash_pos ) { return $id; } $is_double_slashed = substr( $id, $last_slash_pos - 1, 1 ) === '/'; if ( $is_double_slashed ) { return $id; } return ( substr( $id, 0, $last_slash_pos ) . '/' . substr( $id, $last_slash_pos ) ); } /** * Checks if a given request has access to read templates. * * @since 5.8.0 * @since 6.6.0 Allow users with edit_posts capability to read templates. * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } /** * Returns a list of templates. * * @since 5.8.0 * * @param WP_REST_Request $request The request instance. * @return WP_REST_Response */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $query = array(); if ( isset( $request['wp_id'] ) ) { $query['wp_id'] = $request['wp_id']; } if ( isset( $request['area'] ) ) { $query['area'] = $request['area']; } if ( isset( $request['post_type'] ) ) { $query['post_type'] = $request['post_type']; } $templates = array(); foreach ( get_block_templates( $query, $this->post_type ) as $template ) { $data = $this->prepare_item_for_response( $template, $request ); $templates[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $templates ); } /** * Checks if a given request has access to read a single template. * * @since 5.8.0 * @since 6.6.0 Allow users with edit_posts capability to read individual templates. * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_manage_templates', __( 'Sorry, you are not allowed to access the templates on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } /** * Returns the given template * * @since 5.8.0 * * @param WP_REST_Request $request The request instance. * @return WP_REST_Response|WP_Error */ public function get_item( $request ) { if ( isset( $request['source'] ) && ( 'theme' === $request['source'] || 'plugin' === $request['source'] ) ) { $template = get_block_file_template( $request['id'], $this->post_type ); } else { $template = get_block_template( $request['id'], $this->post_type ); } if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $template, $request ); } /** * Checks if a given request has access to write a single template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has write access for the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Updates a single template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $template = get_block_template( $request['id'], $this->post_type ); if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } $post_before = get_post( $template->wp_id ); if ( isset( $request['source'] ) && 'theme' === $request['source'] ) { wp_delete_post( $template->wp_id, true ); $request->set_param( 'context', 'edit' ); $template = get_block_template( $request['id'], $this->post_type ); $response = $this->prepare_item_for_response( $template, $request ); return rest_ensure_response( $response ); } $changes = $this->prepare_item_for_database( $request ); if ( is_wp_error( $changes ) ) { return $changes; } if ( 'custom' === $template->source ) { $update = true; $result = wp_update_post( wp_slash( (array) $changes ), false ); } else { $update = false; $post_before = null; $result = wp_insert_post( wp_slash( (array) $changes ), false ); } if ( is_wp_error( $result ) ) { if ( 'db_update_error' === $result->get_error_code() ) { $result->add_data( array( 'status' => 500 ) ); } else { $result->add_data( array( 'status' => 400 ) ); } return $result; } $template = get_block_template( $request['id'], $this->post_type ); $fields_update = $this->update_additional_fields_for_object( $template, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); $post = get_post( $template->wp_id ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ do_action( "rest_after_insert_{$this->post_type}", $post, $request, false ); wp_after_insert_post( $post, $update, $post_before ); $response = $this->prepare_item_for_response( $template, $request ); return rest_ensure_response( $response ); } /** * Checks if a given request has access to create a template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Creates a single template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $prepared_post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_post ) ) { return $prepared_post; } $prepared_post->post_name = $request['slug']; $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true ); if ( is_wp_error( $post_id ) ) { if ( 'db_insert_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $posts = get_block_templates( array( 'wp_id' => $post_id ), $this->post_type ); if ( ! count( $posts ) ) { return new WP_Error( 'rest_template_insert_error', __( 'No templates exist with that id.' ), array( 'status' => 400 ) ); } $id = $posts[0]->id; $post = get_post( $post_id ); $template = get_block_template( $id, $this->post_type ); $fields_update = $this->update_additional_fields_for_object( $template, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ do_action( "rest_after_insert_{$this->post_type}", $post, $request, true ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $template, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $template->id ) ) ); return $response; } /** * Checks if a given request has access to delete a single template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has delete access for the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Deletes a single template. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $template = get_block_template( $request['id'], $this->post_type ); if ( ! $template ) { return new WP_Error( 'rest_template_not_found', __( 'No templates exist with that id.' ), array( 'status' => 404 ) ); } if ( 'custom' !== $template->source ) { return new WP_Error( 'rest_invalid_template', __( 'Templates based on theme files can\'t be removed.' ), array( 'status' => 400 ) ); } $id = $template->wp_id; $force = (bool) $request['force']; $request->set_param( 'context', 'edit' ); // If we're forcing, then delete permanently. if ( $force ) { $previous = $this->prepare_item_for_response( $template, $request ); $result = wp_delete_post( $id, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { // Otherwise, only trash if we haven't already. if ( 'trash' === $template->status ) { return new WP_Error( 'rest_template_already_trashed', __( 'The template has already been deleted.' ), array( 'status' => 410 ) ); } /* * (Note that internally this falls through to `wp_delete_post()` * if the Trash is disabled.) */ $result = wp_trash_post( $id ); $template->status = 'trash'; $response = $this->prepare_item_for_response( $template, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The template cannot be deleted.' ), array( 'status' => 500 ) ); } return $response; } /** * Prepares a single template for create or update. * * @since 5.8.0 * * @param WP_REST_Request $request Request object. * @return stdClass|WP_Error Changes to pass to wp_update_post. */ protected function prepare_item_for_database( $request ) { $template = $request['id'] ? get_block_template( $request['id'], $this->post_type ) : null; $changes = new stdClass(); if ( null === $template ) { $changes->post_type = $this->post_type; $changes->post_status = 'publish'; $changes->tax_input = array( 'wp_theme' => isset( $request['theme'] ) ? $request['theme'] : get_stylesheet(), ); } elseif ( 'custom' !== $template->source ) { $changes->post_name = $template->slug; $changes->post_type = $this->post_type; $changes->post_status = 'publish'; $changes->tax_input = array( 'wp_theme' => $template->theme, ); $changes->meta_input = array( 'origin' => $template->source, ); } else { $changes->post_name = $template->slug; $changes->ID = $template->wp_id; $changes->post_status = 'publish'; } if ( isset( $request['content'] ) ) { if ( is_string( $request['content'] ) ) { $changes->post_content = $request['content']; } elseif ( isset( $request['content']['raw'] ) ) { $changes->post_content = $request['content']['raw']; } } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_content = $template->content; } if ( isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $changes->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $changes->post_title = $request['title']['raw']; } } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_title = $template->title; } if ( isset( $request['description'] ) ) { $changes->post_excerpt = $request['description']; } elseif ( null !== $template && 'custom' !== $template->source ) { $changes->post_excerpt = $template->description; } if ( 'wp_template' === $this->post_type && isset( $request['is_wp_suggestion'] ) ) { $changes->meta_input = wp_parse_args( array( 'is_wp_suggestion' => $request['is_wp_suggestion'], ), $changes->meta_input = array() ); } if ( 'wp_template_part' === $this->post_type ) { if ( isset( $request['area'] ) ) { $changes->tax_input['wp_template_part_area'] = _filter_block_template_part_area( $request['area'] ); } elseif ( null !== $template && 'custom' !== $template->source && $template->area ) { $changes->tax_input['wp_template_part_area'] = _filter_block_template_part_area( $template->area ); } elseif ( empty( $template->area ) ) { $changes->tax_input['wp_template_part_area'] = WP_TEMPLATE_PART_AREA_UNCATEGORIZED; } } if ( ! empty( $request['author'] ) ) { $post_author = (int) $request['author']; if ( get_current_user_id() !== $post_author ) { $user_obj = get_userdata( $post_author ); if ( ! $user_obj ) { return new WP_Error( 'rest_invalid_author', __( 'Invalid author ID.' ), array( 'status' => 400 ) ); } } $changes->post_author = $post_author; } /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ return apply_filters( "rest_pre_insert_{$this->post_type}", $changes, $request ); } /** * Prepare a single template output for response * * @since 5.8.0 * @since 5.9.0 Renamed `$template` to `$item` to match parent class for PHP 8 named parameter support. * @since 6.3.0 Added `modified` property to the response. * * @param WP_Block_Template $item Template instance. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { return new WP_REST_Response( array() ); } /* * Resolve pattern blocks so they don't need to be resolved client-side * in the editor, improving performance. */ $blocks = parse_blocks( $item->content ); $blocks = resolve_pattern_blocks( $blocks ); $item->content = serialize_blocks( $blocks ); // Restores the more descriptive, specific name for use within this method. $template = $item; $fields = $this->get_fields_for_response( $request ); // Base fields for every template. $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $template->id; } if ( rest_is_field_included( 'theme', $fields ) ) { $data['theme'] = $template->theme; } if ( rest_is_field_included( 'content', $fields ) ) { $data['content'] = array(); } if ( rest_is_field_included( 'content.raw', $fields ) ) { $data['content']['raw'] = $template->content; } if ( rest_is_field_included( 'content.block_version', $fields ) ) { $data['content']['block_version'] = block_version( $template->content ); } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $template->slug; } if ( rest_is_field_included( 'source', $fields ) ) { $data['source'] = $template->source; } if ( rest_is_field_included( 'origin', $fields ) ) { $data['origin'] = $template->origin; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $template->type; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $template->description; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $template->title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { if ( $template->wp_id ) { /** This filter is documented in wp-includes/post-template.php */ $data['title']['rendered'] = apply_filters( 'the_title', $template->title, $template->wp_id ); } else { $data['title']['rendered'] = $template->title; } } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $template->status; } if ( rest_is_field_included( 'wp_id', $fields ) ) { $data['wp_id'] = (int) $template->wp_id; } if ( rest_is_field_included( 'has_theme_file', $fields ) ) { $data['has_theme_file'] = (bool) $template->has_theme_file; } if ( rest_is_field_included( 'is_custom', $fields ) && 'wp_template' === $template->type ) { $data['is_custom'] = $template->is_custom; } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $template->author; } if ( rest_is_field_included( 'area', $fields ) && 'wp_template_part' === $template->type ) { $data['area'] = $template->area; } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = mysql_to_rfc3339( $template->modified ); } if ( rest_is_field_included( 'author_text', $fields ) ) { $data['author_text'] = self::get_wp_templates_author_text_field( $template ); } if ( rest_is_field_included( 'original_source', $fields ) ) { $data['original_source'] = self::get_wp_templates_original_source_field( $template ); } if ( rest_is_field_included( 'plugin', $fields ) ) { $registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug ); if ( $registered_template ) { $data['plugin'] = $registered_template->plugin; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template->id ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions(); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return $response; } /** * Returns the source from where the template originally comes from. * * @since 6.5.0 * * @param WP_Block_Template $template_object Template instance. * @return string Original source of the template one of theme, plugin, site, or user. */ private static function get_wp_templates_original_source_field( $template_object ) { if ( 'wp_template' === $template_object->type || 'wp_template_part' === $template_object->type ) { /* * Added by theme. * Template originally provided by a theme, but customized by a user. * Templates originally didn't have the 'origin' field so identify * older customized templates by checking for no origin and a 'theme' * or 'custom' source. */ if ( $template_object->has_theme_file && ( 'theme' === $template_object->origin || ( empty( $template_object->origin ) && in_array( $template_object->source, array( 'theme', 'custom', ), true ) ) ) ) { return 'theme'; } // Added by plugin. if ( 'plugin' === $template_object->origin ) { return 'plugin'; } /* * Added by site. * Template was created from scratch, but has no author. Author support * was only added to templates in WordPress 5.9. Fallback to showing the * site logo and title. */ if ( empty( $template_object->has_theme_file ) && 'custom' === $template_object->source && empty( $template_object->author ) ) { return 'site'; } } // Added by user. return 'user'; } /** * Returns a human readable text for the author of the template. * * @since 6.5.0 * * @param WP_Block_Template $template_object Template instance. * @return string Human readable text for the author. */ private static function get_wp_templates_author_text_field( $template_object ) { $original_source = self::get_wp_templates_original_source_field( $template_object ); switch ( $original_source ) { case 'theme': $theme_name = wp_get_theme( $template_object->theme )->get( 'Name' ); return empty( $theme_name ) ? $template_object->theme : $theme_name; case 'plugin': if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( isset( $template_object->plugin ) ) { $plugins = wp_get_active_and_valid_plugins(); foreach ( $plugins as $plugin_file ) { $plugin_basename = plugin_basename( $plugin_file ); // Split basename by '/' to get the plugin slug. list( $plugin_slug, ) = explode( '/', $plugin_basename ); if ( $plugin_slug === $template_object->plugin ) { $plugin_data = get_plugin_data( $plugin_file ); if ( ! empty( $plugin_data['Name'] ) ) { return $plugin_data['Name']; } break; } } } /* * Fall back to the theme name if the plugin is not defined. That's needed to keep backwards * compatibility with templates that were registered before the plugin attribute was added. */ $plugins = get_plugins(); $plugin_basename = plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) ); if ( isset( $plugins[ $plugin_basename ] ) && isset( $plugins[ $plugin_basename ]['Name'] ) ) { return $plugins[ $plugin_basename ]['Name']; } return isset( $template_object->plugin ) ? $template_object->plugin : $template_object->theme; case 'site': return get_bloginfo( 'name' ); case 'user': $author = get_user_by( 'id', $template_object->author ); if ( ! $author ) { return __( 'Unknown author' ); } return $author->get( 'display_name' ); } // Fail-safe to return a string should the original source ever fall through. return ''; } /** * Prepares links for the request. * * @since 5.8.0 * * @param integer $id ID. * @return array Links for the given post. */ protected function prepare_links( $id ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $id ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $this->post_type ) ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( post_type_supports( $this->post_type, 'revisions' ) ) { $template = get_block_template( $id, $this->post_type ); if ( $template instanceof WP_Block_Template && ! empty( $template->wp_id ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $template->wp_id ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%s/%s/revisions', $this->namespace, $this->rest_base, $id ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); if ( $revisions_count > 0 ) { $links['predecessor-version'] = array( 'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ), 'id' => $revisions['latest_id'], ); } } } return $links; } /** * Get the link relations available for the post and current user. * * @since 5.8.0 * * @return string[] List of link relations. */ protected function get_available_actions() { $rels = array(); $post_type = get_post_type_object( $this->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'unfiltered_html' ) ) { $rels[] = 'https://api.w.org/action-unfiltered-html'; } return $rels; } /** * Retrieves the query params for the posts collection. * * @since 5.8.0 * @since 5.9.0 Added `'area'` and `'post_type'`. * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'wp_id' => array( 'description' => __( 'Limit to the specified post id.' ), 'type' => 'integer', ), 'area' => array( 'description' => __( 'Limit to the specified template part area.' ), 'type' => 'string', ), 'post_type' => array( 'description' => __( 'Post type to get the templates for.' ), 'type' => 'string', ), ); } /** * Retrieves the block type' schema, conforming to JSON Schema. * * @since 5.8.0 * @since 5.9.0 Added `'area'`. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'Unique slug identifying the template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'required' => true, 'minLength' => 1, 'pattern' => '[a-zA-Z0-9_\%-]+', ), 'theme' => array( 'description' => __( 'Theme identifier for the template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'type' => array( 'description' => __( 'Type of template.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'source' => array( 'description' => __( 'Source of template' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'origin' => array( 'description' => __( 'Source of a customized template' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'content' => array( 'description' => __( 'Content of template.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the template, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'block_version' => array( 'description' => __( 'Version of the content block format used by the template.' ), 'type' => 'integer', 'context' => array( 'edit' ), 'readonly' => true, ), ), ), 'title' => array( 'description' => __( 'Title of template.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the template, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML title for the template, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), 'description' => array( 'description' => __( 'Description of template.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), ), 'status' => array( 'description' => __( 'Status of template.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'default' => 'publish', 'context' => array( 'embed', 'view', 'edit' ), ), 'wp_id' => array( 'description' => __( 'Post ID.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'has_theme_file' => array( 'description' => __( 'Theme file exists.' ), 'type' => 'bool', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'author' => array( 'description' => __( 'The ID for the author of the template.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'modified' => array( 'description' => __( "The date the template was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'author_text' => array( 'type' => 'string', 'description' => __( 'Human readable text for the author.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'original_source' => array( 'description' => __( 'Where the template originally comes from e.g. \'theme\'' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( 'theme', 'plugin', 'site', 'user', ), ), ), ); if ( 'wp_template' === $this->post_type ) { $schema['properties']['is_custom'] = array( 'description' => __( 'Whether a template is a custom template.' ), 'type' => 'bool', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ); $schema['properties']['plugin'] = array( 'type' => 'string', 'description' => __( 'Plugin that registered the template.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ); } if ( 'wp_template_part' === $this->post_type ) { $schema['properties']['area'] = array( 'description' => __( 'Where the template part is intended for use (header, footer, etc.)' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Application_Passwords_Controller class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class to access a user's application passwords via the REST API. * * @since 5.6.0 * * @see WP_REST_Controller */ class WP_REST_Application_Passwords_Controller extends WP_REST_Controller { /** * Application Passwords controller constructor. * * @since 5.6.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'users/(?P<user_id>(?:[\d]+|me))/application-passwords'; } /** * Registers the REST API routes for the application passwords controller. * * @since 5.6.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema(), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_items' ), 'permission_callback' => array( $this, 'delete_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/introspect', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_current_item' ), 'permission_callback' => array( $this, 'get_current_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<uuid>[\w\-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to get application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'list_app_passwords', $user->ID ) ) { return new WP_Error( 'rest_cannot_list_application_passwords', __( 'Sorry, you are not allowed to list application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves a collection of application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID ); $response = array(); foreach ( $passwords as $password ) { $response[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $password, $request ) ); } return new WP_REST_Response( $response ); } /** * Checks if a given request has access to get a specific application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'read_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_read_application_password', __( 'Sorry, you are not allowed to read this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves one application password from the collection. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } return $this->prepare_item_for_response( $password, $request ); } /** * Checks if a given request has access to create application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'create_app_password', $user->ID ) ) { return new WP_Error( 'rest_cannot_create_application_passwords', __( 'Sorry, you are not allowed to create application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Creates an application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) ); if ( is_wp_error( $created ) ) { return $created; } $password = $created[0]; $item = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] ); $item['new_password'] = WP_Application_Passwords::chunk_password( $password ); $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } /** * Fires after a single application password is completely created or updated via the REST API. * * @since 5.6.0 * * @param array $item Inserted or updated password item. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating an application password, false when updating. */ do_action( 'rest_after_insert_application_password', $item, $request, true ); $request->set_param( 'context', 'edit' ); $response = $this->prepare_item_for_response( $item, $request ); $response->set_status( 201 ); $response->header( 'Location', $response->get_links()['self'][0]['href'] ); return $response; } /** * Checks if a given request has access to update application passwords. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_edit_application_password', __( 'Sorry, you are not allowed to edit this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates an application password. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $item = $this->get_application_password( $request ); if ( is_wp_error( $item ) ) { return $item; } $prepared = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared ) ) { return $prepared; } $saved = WP_Application_Passwords::update_application_password( $user->ID, $item['uuid'], wp_slash( (array) $prepared ) ); if ( is_wp_error( $saved ) ) { return $saved; } $fields_update = $this->update_additional_fields_for_object( $item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $item = WP_Application_Passwords::get_user_application_password( $user->ID, $item['uuid'] ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php */ do_action( 'rest_after_insert_application_password', $item, $request, false ); $request->set_param( 'context', 'edit' ); return $this->prepare_item_for_response( $item, $request ); } /** * Checks if a given request has access to delete all application passwords for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_items_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_passwords', $user->ID ) ) { return new WP_Error( 'rest_cannot_delete_application_passwords', __( 'Sorry, you are not allowed to delete application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes all application passwords for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_items( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $deleted = WP_Application_Passwords::delete_all_application_passwords( $user->ID ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'count' => $deleted, ) ); } /** * Checks if a given request has access to delete a specific application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_app_password', $user->ID, $request['uuid'] ) ) { return new WP_Error( 'rest_cannot_delete_application_password', __( 'Sorry, you are not allowed to delete this application password.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes an application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = $this->get_application_password( $request ); if ( is_wp_error( $password ) ) { return $password; } $request->set_param( 'context', 'edit' ); $previous = $this->prepare_item_for_response( $password, $request ); $deleted = WP_Application_Passwords::delete_application_password( $user->ID, $password['uuid'] ); if ( is_wp_error( $deleted ) ) { return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } /** * Checks if a given request has access to get the currently used application password for a user. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_current_item_permissions_check( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( get_current_user_id() !== $user->ID ) { return new WP_Error( 'rest_cannot_introspect_app_password_for_non_authenticated_user', __( 'The authenticated application password can only be introspected for the current user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves the application password being currently used for authentication of a user. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_current_item( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $uuid = rest_get_authenticated_app_password(); if ( ! $uuid ) { return new WP_Error( 'rest_no_authenticated_app_password', __( 'Cannot introspect application password.' ), array( 'status' => 404 ) ); } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $uuid ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 500 ) ); } return $this->prepare_item_for_response( $password, $request ); } /** * Performs a permissions check for the request. * * @since 5.6.0 * @deprecated 5.7.0 Use `edit_user` directly or one of the specific meta capabilities introduced in 5.7.0. * * @param WP_REST_Request $request * @return true|WP_Error */ protected function do_permissions_check( $request ) { _deprecated_function( __METHOD__, '5.7.0' ); $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_manage_application_passwords', __( 'Sorry, you are not allowed to manage application passwords for this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Prepares an application password for a create or update operation. * * @since 5.6.0 * * @param WP_REST_Request $request Request object. * @return object|WP_Error The prepared item, or WP_Error object on failure. */ protected function prepare_item_for_database( $request ) { $prepared = (object) array( 'name' => $request['name'], ); if ( $request['app_id'] && ! $request['uuid'] ) { $prepared->app_id = $request['app_id']; } /** * Filters an application password before it is inserted via the REST API. * * @since 5.6.0 * * @param stdClass $prepared An object representing a single application password prepared for inserting or updating the database. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_pre_insert_application_password', $prepared, $request ); } /** * Prepares the application password for the REST response. * * @since 5.6.0 * * @param array $item WordPress representation of the item. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $fields = $this->get_fields_for_response( $request ); $prepared = array( 'uuid' => $item['uuid'], 'app_id' => empty( $item['app_id'] ) ? '' : $item['app_id'], 'name' => $item['name'], 'created' => gmdate( 'Y-m-d\TH:i:s', $item['created'] ), 'last_used' => $item['last_used'] ? gmdate( 'Y-m-d\TH:i:s', $item['last_used'] ) : null, 'last_ip' => $item['last_ip'] ? $item['last_ip'] : null, ); if ( isset( $item['new_password'] ) ) { $prepared['password'] = $item['new_password']; } $prepared = $this->add_additional_fields_to_object( $prepared, $request ); $prepared = $this->filter_response_by_context( $prepared, $request['context'] ); $response = new WP_REST_Response( $prepared ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $user, $item ) ); } /** * Filters the REST API response for an application password. * * @since 5.6.0 * * @param WP_REST_Response $response The response object. * @param array $item The application password array. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_application_password', $response, $item, $request ); } /** * Prepares links for the request. * * @since 5.6.0 * * @param WP_User $user The requested user. * @param array $item The application password. * @return array The list of links. */ protected function prepare_links( WP_User $user, $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/users/%d/application-passwords/%s', $this->namespace, $user->ID, $item['uuid'] ) ), ), ); } /** * Gets the requested user. * * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @return WP_User|WP_Error The WordPress user associated with the request, or a WP_Error if none found. */ protected function get_user( $request ) { if ( ! wp_is_application_passwords_available() ) { return new WP_Error( 'application_passwords_disabled', __( 'Application passwords are not available.' ), array( 'status' => 501 ) ); } $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); $id = $request['user_id']; if ( 'me' === $id ) { if ( ! is_user_logged_in() ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } $user = wp_get_current_user(); } else { $id = (int) $id; if ( $id <= 0 ) { return $error; } $user = get_userdata( $id ); } if ( empty( $user ) || ! $user->exists() ) { return $error; } if ( is_multisite() && ! user_can( $user->ID, 'manage_sites' ) && ! is_user_member_of_blog( $user->ID ) ) { return $error; } if ( ! wp_is_application_passwords_available_for_user( $user ) ) { return new WP_Error( 'application_passwords_disabled_for_user', __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' ), array( 'status' => 501 ) ); } return $user; } /** * Gets the requested application password for a user. * * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @return array|WP_Error The application password details if found, a WP_Error otherwise. */ protected function get_application_password( $request ) { $user = $this->get_user( $request ); if ( is_wp_error( $user ) ) { return $user; } $password = WP_Application_Passwords::get_user_application_password( $user->ID, $request['uuid'] ); if ( ! $password ) { return new WP_Error( 'rest_application_password_not_found', __( 'Application password not found.' ), array( 'status' => 404 ) ); } return $password; } /** * Retrieves the query params for the collections. * * @since 5.6.0 * * @return array Query parameters for the collection. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } /** * Retrieves the application password's schema, conforming to JSON Schema. * * @since 5.6.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'application-password', 'type' => 'object', 'properties' => array( 'uuid' => array( 'description' => __( 'The unique identifier for the application password.' ), 'type' => 'string', 'format' => 'uuid', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'app_id' => array( 'description' => __( 'A UUID provided by the application to uniquely identify it. It is recommended to use an UUID v5 with the URL or DNS namespace.' ), 'type' => 'string', 'format' => 'uuid', 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The name of the application password.' ), 'type' => 'string', 'required' => true, 'context' => array( 'view', 'edit', 'embed' ), 'minLength' => 1, 'pattern' => '.*\S.*', ), 'password' => array( 'description' => __( 'The generated password. Only available after adding an application.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'created' => array( 'description' => __( 'The GMT date the application password was created.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_used' => array( 'description' => __( 'The GMT date the application password was last used.' ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'last_ip' => array( 'description' => __( 'The IP address the application password was last used by.' ), 'type' => array( 'string', 'null' ), 'format' => 'ip', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Attachments_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core controller used to access attachments via the REST API. * * @since 4.7.0 * * @see WP_REST_Posts_Controller */ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { /** * Whether the controller supports batching. * * @since 5.9.0 * @var false */ protected $allow_batch = false; /** * Registers the routes for attachments. * * @since 5.3.0 * * @see register_rest_route() */ public function register_routes() { parent::register_routes(); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/post-process', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'post_process_item' ), 'permission_callback' => array( $this, 'post_process_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the attachment.' ), 'type' => 'integer', ), 'action' => array( 'type' => 'string', 'enum' => array( 'create-image-subsizes' ), 'required' => true, ), ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/edit', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'edit_media_item' ), 'permission_callback' => array( $this, 'edit_media_item_permissions_check' ), 'args' => $this->get_edit_media_item_args(), ) ); } /** * Determines the allowed query_vars for a get_items() response and * prepares for WP_Query. * * @since 4.7.0 * * @param array $prepared_args Optional. Array of prepared arguments. Default empty array. * @param WP_REST_Request $request Optional. Request to prepare items for. * @return array Array of query arguments. */ protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = parent::prepare_items_query( $prepared_args, $request ); if ( empty( $query_args['post_status'] ) ) { $query_args['post_status'] = 'inherit'; } $media_types = $this->get_media_types(); if ( ! empty( $request['media_type'] ) && isset( $media_types[ $request['media_type'] ] ) ) { $query_args['post_mime_type'] = $media_types[ $request['media_type'] ]; } if ( ! empty( $request['mime_type'] ) ) { $parts = explode( '/', $request['mime_type'] ); if ( isset( $media_types[ $parts[0] ] ) && in_array( $request['mime_type'], $media_types[ $parts[0] ], true ) ) { $query_args['post_mime_type'] = $request['mime_type']; } } // Filter query clauses to include filenames. if ( isset( $query_args['s'] ) ) { add_filter( 'wp_allow_query_attachment_by_filename', '__return_true' ); } return $query_args; } /** * Checks if a given request has access to create an attachment. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error Boolean true if the attachment may be created, or a WP_Error if not. */ public function create_item_permissions_check( $request ) { $ret = parent::create_item_permissions_check( $request ); if ( ! $ret || is_wp_error( $ret ) ) { return $ret; } if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => 400 ) ); } // Attaching media to a post requires ability to edit said post. if ( ! empty( $request['post'] ) && ! current_user_can( 'edit_post', (int) $request['post'] ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $files = $request->get_file_params(); /** * Filter whether the server should prevent uploads for image types it doesn't support. Default true. * * Developers can use this filter to enable uploads of certain image types. By default image types that are not * supported by the server are prevented from being uploaded. * * @since 6.8.0 * * @param bool $check_mime Whether to prevent uploads of unsupported image types. * @param string|null $mime_type The mime type of the file being uploaded (if available). */ $prevent_unsupported_uploads = apply_filters( 'wp_prevent_unsupported_mime_type_uploads', true, isset( $files['file']['type'] ) ? $files['file']['type'] : null ); // If the upload is an image, check if the server can handle the mime type. if ( $prevent_unsupported_uploads && isset( $files['file']['type'] ) && str_starts_with( $files['file']['type'], 'image/' ) ) { // List of non-resizable image formats. $editor_non_resizable_formats = array( 'image/svg+xml', ); // Check if the image editor supports the type or ignore if it isn't a format resizable by an editor. if ( ! in_array( $files['file']['type'], $editor_non_resizable_formats, true ) && ! wp_image_editor_supports( array( 'mime_type' => $files['file']['type'] ) ) ) { return new WP_Error( 'rest_upload_image_type_not_supported', __( 'The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.' ), array( 'status' => 400 ) ); } } return true; } /** * Creates a single attachment. * * @since 4.7.0 * * @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. */ public function create_item( $request ) { if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) { return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) ); } $insert = $this->insert_attachment( $request ); if ( is_wp_error( $insert ) ) { return $insert; } $schema = $this->get_item_schema(); // Extract by name. $attachment_id = $insert['attachment_id']; $file = $insert['file']; if ( isset( $request['alt_text'] ) ) { update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) ); } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $thumbnail_update = $this->handle_featured_media( $request['featured_media'], $attachment_id ); if ( is_wp_error( $thumbnail_update ) ) { return $thumbnail_update; } } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $attachment_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $attachment = get_post( $attachment_id ); $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $terms_update = $this->handle_terms( $attachment_id, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } $request->set_param( 'context', 'edit' ); /** * Fires after a single attachment is completely created or updated via the REST API. * * @since 5.0.0 * * @param WP_Post $attachment Inserted or updated attachment object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating an attachment, false when updating. */ do_action( 'rest_after_insert_attachment', $attachment, $request, true ); wp_after_insert_post( $attachment, false, null ); if ( wp_is_serving_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. */ header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id ); } // Include media and image functions to get access to wp_generate_attachment_metadata(). require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; /* * Post-process the upload (create image sub-sizes, make PDF thumbnails, etc.) and insert attachment meta. * At this point the server may run out of resources and post-processing of uploaded images may fail. */ wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); $response = $this->prepare_item_for_response( $attachment, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $attachment_id ) ) ); return $response; } /** * Inserts the attachment post in the database. Does not update the attachment meta. * * @since 5.3.0 * * @param WP_REST_Request $request * @return array|WP_Error */ protected function insert_attachment( $request ) { // Get the file via $_FILES or raw data. $files = $request->get_file_params(); $headers = $request->get_headers(); $time = null; // Matches logic in media_handle_upload(). if ( ! empty( $request['post'] ) ) { $post = get_post( $request['post'] ); // The post date doesn't usually matter for pages, so don't backdate this upload. if ( $post && 'page' !== $post->post_type && substr( $post->post_date, 0, 4 ) > 0 ) { $time = $post->post_date; } } if ( ! empty( $files ) ) { $file = $this->upload_from_file( $files, $headers, $time ); } else { $file = $this->upload_from_data( $request->get_body(), $headers, $time ); } if ( is_wp_error( $file ) ) { return $file; } $name = wp_basename( $file['file'] ); $name_parts = pathinfo( $name ); $name = trim( substr( $name, 0, -( 1 + strlen( $name_parts['extension'] ) ) ) ); $url = $file['url']; $type = $file['type']; $file = $file['file']; // Include image functions to get access to wp_read_image_metadata(). require_once ABSPATH . 'wp-admin/includes/image.php'; // Use image exif/iptc data for title and caption defaults if possible. $image_meta = wp_read_image_metadata( $file ); if ( ! empty( $image_meta ) ) { if ( empty( $request['title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { $request['title'] = $image_meta['title']; } if ( empty( $request['caption'] ) && trim( $image_meta['caption'] ) ) { $request['caption'] = $image_meta['caption']; } } $attachment = $this->prepare_item_for_database( $request ); $attachment->post_mime_type = $type; $attachment->guid = $url; // If the title was not set, use the original filename. if ( empty( $attachment->post_title ) && ! empty( $files['file']['name'] ) ) { // Remove the file extension (after the last `.`) $tmp_title = substr( $files['file']['name'], 0, strrpos( $files['file']['name'], '.' ) ); if ( ! empty( $tmp_title ) ) { $attachment->post_title = $tmp_title; } } // Fall back to the original approach. if ( empty( $attachment->post_title ) ) { $attachment->post_title = preg_replace( '/\.[^.]+$/', '', wp_basename( $file ) ); } // $post_parent is inherited from $attachment['post_parent']. $id = wp_insert_attachment( wp_slash( (array) $attachment ), $file, 0, true, false ); if ( is_wp_error( $id ) ) { if ( 'db_update_error' === $id->get_error_code() ) { $id->add_data( array( 'status' => 500 ) ); } else { $id->add_data( array( 'status' => 400 ) ); } return $id; } $attachment = get_post( $id ); /** * Fires after a single attachment is created or updated via the REST API. * * @since 4.7.0 * * @param WP_Post $attachment Inserted or updated attachment object. * @param WP_REST_Request $request The request sent to the API. * @param bool $creating True when creating an attachment, false when updating. */ do_action( 'rest_insert_attachment', $attachment, $request, true ); return array( 'attachment_id' => $id, 'file' => $file, ); } /** * Determines the featured media based on a request param. * * @since 6.5.0 * * @param int $featured_media Featured Media ID. * @param int $post_id Post ID. * @return bool|WP_Error Whether the post thumbnail was successfully deleted, otherwise WP_Error. */ protected function handle_featured_media( $featured_media, $post_id ) { $post_type = get_post_type( $post_id ); $thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ); // Similar check as in wp_insert_post(). if ( ! $thumbnail_support && get_post_mime_type( $post_id ) ) { if ( wp_attachment_is( 'audio', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' ); } elseif ( wp_attachment_is( 'video', $post_id ) ) { $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' ); } } if ( $thumbnail_support ) { return parent::handle_featured_media( $featured_media, $post_id ); } return new WP_Error( 'rest_no_featured_media', sprintf( /* translators: %s: attachment mime type */ __( 'This site does not support post thumbnails on attachments with MIME type %s.' ), get_post_mime_type( $post_id ) ), array( 'status' => 400 ) ); } /** * Updates a single attachment. * * @since 4.7.0 * * @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. */ public function update_item( $request ) { if ( ! empty( $request['post'] ) && in_array( get_post_type( $request['post'] ), array( 'revision', 'attachment' ), true ) ) { return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) ); } $attachment_before = get_post( $request['id'] ); $response = parent::update_item( $request ); if ( is_wp_error( $response ) ) { return $response; } $response = rest_ensure_response( $response ); $data = $response->get_data(); if ( isset( $request['alt_text'] ) ) { update_post_meta( $data['id'], '_wp_attachment_image_alt', $request['alt_text'] ); } $attachment = get_post( $request['id'] ); if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $thumbnail_update = $this->handle_featured_media( $request['featured_media'], $attachment->ID ); if ( is_wp_error( $thumbnail_update ) ) { return $thumbnail_update; } } $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php */ do_action( 'rest_after_insert_attachment', $attachment, $request, false ); wp_after_insert_post( $attachment, true, $attachment_before ); $response = $this->prepare_item_for_response( $attachment, $request ); $response = rest_ensure_response( $response ); return $response; } /** * Performs post-processing on an attachment. * * @since 5.3.0 * * @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. */ public function post_process_item( $request ) { switch ( $request['action'] ) { case 'create-image-subsizes': require_once ABSPATH . 'wp-admin/includes/image.php'; wp_update_image_subsizes( $request['id'] ); break; } $request['context'] = 'edit'; return $this->prepare_item_for_response( get_post( $request['id'] ), $request ); } /** * Checks if a given request can perform post-processing on an attachment. * * @since 5.3.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function post_process_item_permissions_check( $request ) { return $this->update_item_permissions_check( $request ); } /** * Checks if a given request has access to editing media. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function edit_media_item_permissions_check( $request ) { if ( ! current_user_can( 'upload_files' ) ) { return new WP_Error( 'rest_cannot_edit_image', __( 'Sorry, you are not allowed to upload media on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return $this->update_item_permissions_check( $request ); } /** * Applies edits to a media item and creates a new attachment record. * * @since 5.5.0 * * @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. */ public function edit_media_item( $request ) { require_once ABSPATH . 'wp-admin/includes/image.php'; $attachment_id = $request['id']; // This also confirms the attachment is an image. $image_file = wp_get_original_image_path( $attachment_id ); $image_meta = wp_get_attachment_metadata( $attachment_id ); if ( ! $image_meta || ! $image_file || ! wp_image_file_matches_image_meta( $request['src'], $image_meta, $attachment_id ) ) { return new WP_Error( 'rest_unknown_attachment', __( 'Unable to get meta information for file.' ), array( 'status' => 404 ) ); } $supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/heic' ); $mime_type = get_post_mime_type( $attachment_id ); if ( ! in_array( $mime_type, $supported_types, true ) ) { return new WP_Error( 'rest_cannot_edit_file_type', __( 'This type of file cannot be edited.' ), array( 'status' => 400 ) ); } // The `modifiers` param takes precedence over the older format. if ( isset( $request['modifiers'] ) ) { $modifiers = $request['modifiers']; } else { $modifiers = array(); if ( ! empty( $request['rotation'] ) ) { $modifiers[] = array( 'type' => 'rotate', 'args' => array( 'angle' => $request['rotation'], ), ); } if ( isset( $request['x'], $request['y'], $request['width'], $request['height'] ) ) { $modifiers[] = array( 'type' => 'crop', 'args' => array( 'left' => $request['x'], 'top' => $request['y'], 'width' => $request['width'], 'height' => $request['height'], ), ); } if ( 0 === count( $modifiers ) ) { return new WP_Error( 'rest_image_not_edited', __( 'The image was not edited. Edit the image before applying the changes.' ), array( 'status' => 400 ) ); } } /* * If the file doesn't exist, attempt a URL fopen on the src link. * This can occur with certain file replication plugins. * Keep the original file path to get a modified name later. */ $image_file_to_edit = $image_file; if ( ! file_exists( $image_file_to_edit ) ) { $image_file_to_edit = _load_image_to_edit_path( $attachment_id ); } $image_editor = wp_get_image_editor( $image_file_to_edit ); if ( is_wp_error( $image_editor ) ) { return new WP_Error( 'rest_unknown_image_file_type', __( 'Unable to edit this image.' ), array( 'status' => 500 ) ); } foreach ( $modifiers as $modifier ) { $args = $modifier['args']; switch ( $modifier['type'] ) { case 'rotate': // Rotation direction: clockwise vs. counterclockwise. $rotate = 0 - $args['angle']; if ( 0 !== $rotate ) { $result = $image_editor->rotate( $rotate ); if ( is_wp_error( $result ) ) { return new WP_Error( 'rest_image_rotation_failed', __( 'Unable to rotate this image.' ), array( 'status' => 500 ) ); } } break; case 'crop': $size = $image_editor->get_size(); $crop_x = (int) round( ( $size['width'] * $args['left'] ) / 100.0 ); $crop_y = (int) round( ( $size['height'] * $args['top'] ) / 100.0 ); $width = (int) round( ( $size['width'] * $args['width'] ) / 100.0 ); $height = (int) round( ( $size['height'] * $args['height'] ) / 100.0 ); if ( $size['width'] !== $width || $size['height'] !== $height ) { $result = $image_editor->crop( $crop_x, $crop_y, $width, $height ); if ( is_wp_error( $result ) ) { return new WP_Error( 'rest_image_crop_failed', __( 'Unable to crop this image.' ), array( 'status' => 500 ) ); } } break; } } // Calculate the file name. $image_ext = pathinfo( $image_file, PATHINFO_EXTENSION ); $image_name = wp_basename( $image_file, ".{$image_ext}" ); /* * Do not append multiple `-edited` to the file name. * The user may be editing a previously edited image. */ if ( preg_match( '/-edited(-\d+)?$/', $image_name ) ) { // Remove any `-1`, `-2`, etc. `wp_unique_filename()` will add the proper number. $image_name = preg_replace( '/-edited(-\d+)?$/', '-edited', $image_name ); } else { // Append `-edited` before the extension. $image_name .= '-edited'; } $filename = "{$image_name}.{$image_ext}"; // Create the uploads subdirectory if needed. $uploads = wp_upload_dir(); // Make the file name unique in the (new) upload directory. $filename = wp_unique_filename( $uploads['path'], $filename ); // Save to disk. $saved = $image_editor->save( $uploads['path'] . "/$filename" ); if ( is_wp_error( $saved ) ) { return $saved; } // Create new attachment post. $new_attachment_post = array( 'post_mime_type' => $saved['mime-type'], 'guid' => $uploads['url'] . "/$filename", 'post_title' => $image_name, 'post_content' => '', ); // Copy post_content, post_excerpt, and post_title from the edited image's attachment post. $attachment_post = get_post( $attachment_id ); if ( $attachment_post ) { $new_attachment_post['post_content'] = $attachment_post->post_content; $new_attachment_post['post_excerpt'] = $attachment_post->post_excerpt; $new_attachment_post['post_title'] = $attachment_post->post_title; } $new_attachment_id = wp_insert_attachment( wp_slash( $new_attachment_post ), $saved['path'], 0, true ); if ( is_wp_error( $new_attachment_id ) ) { if ( 'db_update_error' === $new_attachment_id->get_error_code() ) { $new_attachment_id->add_data( array( 'status' => 500 ) ); } else { $new_attachment_id->add_data( array( 'status' => 400 ) ); } return $new_attachment_id; } // Copy the image alt text from the edited image. $image_alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $image_alt ) ) { // update_post_meta() expects slashed. update_post_meta( $new_attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) ); } if ( wp_is_serving_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. */ header( 'X-WP-Upload-Attachment-ID: ' . $new_attachment_id ); } // Generate image sub-sizes and meta. $new_image_meta = wp_generate_attachment_metadata( $new_attachment_id, $saved['path'] ); // Copy the EXIF metadata from the original attachment if not generated for the edited image. if ( isset( $image_meta['image_meta'] ) && isset( $new_image_meta['image_meta'] ) && is_array( $new_image_meta['image_meta'] ) ) { // Merge but skip empty values. foreach ( (array) $image_meta['image_meta'] as $key => $value ) { if ( empty( $new_image_meta['image_meta'][ $key ] ) && ! empty( $value ) ) { $new_image_meta['image_meta'][ $key ] = $value; } } } // Reset orientation. At this point the image is edited and orientation is correct. if ( ! empty( $new_image_meta['image_meta']['orientation'] ) ) { $new_image_meta['image_meta']['orientation'] = 1; } // The attachment_id may change if the site is exported and imported. $new_image_meta['parent_image'] = array( 'attachment_id' => $attachment_id, // Path to the originally uploaded image file relative to the uploads directory. 'file' => _wp_relative_upload_path( $image_file ), ); /** * Filters the meta data for the new image created by editing an existing image. * * @since 5.5.0 * * @param array $new_image_meta Meta data for the new image. * @param int $new_attachment_id Attachment post ID for the new image. * @param int $attachment_id Attachment post ID for the edited (parent) image. */ $new_image_meta = apply_filters( 'wp_edited_image_metadata', $new_image_meta, $new_attachment_id, $attachment_id ); wp_update_attachment_metadata( $new_attachment_id, $new_image_meta ); $response = $this->prepare_item_for_response( get_post( $new_attachment_id ), $request ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $new_attachment_id ) ) ); return $response; } /** * Prepares a single attachment for create or update. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return stdClass|WP_Error Post object. */ protected function prepare_item_for_database( $request ) { $prepared_attachment = parent::prepare_item_for_database( $request ); // Attachment caption (post_excerpt internally). if ( isset( $request['caption'] ) ) { if ( is_string( $request['caption'] ) ) { $prepared_attachment->post_excerpt = $request['caption']; } elseif ( isset( $request['caption']['raw'] ) ) { $prepared_attachment->post_excerpt = $request['caption']['raw']; } } // Attachment description (post_content internally). if ( isset( $request['description'] ) ) { if ( is_string( $request['description'] ) ) { $prepared_attachment->post_content = $request['description']; } elseif ( isset( $request['description']['raw'] ) ) { $prepared_attachment->post_content = $request['description']['raw']; } } if ( isset( $request['post'] ) ) { $prepared_attachment->post_parent = (int) $request['post']; } return $prepared_attachment; } /** * Prepares a single attachment output for response. * * @since 4.7.0 * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_Post $item Attachment object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $post = $item; $response = parent::prepare_item_for_response( $post, $request ); $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'description', $fields, true ) ) { $data['description'] = array( 'raw' => $post->post_content, /** This filter is documented in wp-includes/post-template.php */ 'rendered' => apply_filters( 'the_content', $post->post_content ), ); } if ( in_array( 'caption', $fields, true ) ) { /** This filter is documented in wp-includes/post-template.php */ $caption = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); /** This filter is documented in wp-includes/post-template.php */ $caption = apply_filters( 'the_excerpt', $caption ); $data['caption'] = array( 'raw' => $post->post_excerpt, 'rendered' => $caption, ); } if ( in_array( 'alt_text', $fields, true ) ) { $data['alt_text'] = get_post_meta( $post->ID, '_wp_attachment_image_alt', true ); } if ( in_array( 'media_type', $fields, true ) ) { $data['media_type'] = wp_attachment_is_image( $post->ID ) ? 'image' : 'file'; } if ( in_array( 'mime_type', $fields, true ) ) { $data['mime_type'] = $post->post_mime_type; } if ( in_array( 'media_details', $fields, true ) ) { $data['media_details'] = wp_get_attachment_metadata( $post->ID ); // Ensure empty details is an empty object. if ( empty( $data['media_details'] ) ) { $data['media_details'] = new stdClass(); } elseif ( ! empty( $data['media_details']['sizes'] ) ) { foreach ( $data['media_details']['sizes'] as $size => &$size_data ) { if ( isset( $size_data['mime-type'] ) ) { $size_data['mime_type'] = $size_data['mime-type']; unset( $size_data['mime-type'] ); } // Use the same method image_downsize() does. $image_src = wp_get_attachment_image_src( $post->ID, $size ); if ( ! $image_src ) { continue; } $size_data['source_url'] = $image_src[0]; } $full_src = wp_get_attachment_image_src( $post->ID, 'full' ); if ( ! empty( $full_src ) ) { $data['media_details']['sizes']['full'] = array( 'file' => wp_basename( $full_src[0] ), 'width' => $full_src[1], 'height' => $full_src[2], 'mime_type' => $post->post_mime_type, 'source_url' => $full_src[0], ); } } else { $data['media_details']['sizes'] = new stdClass(); } } if ( in_array( 'post', $fields, true ) ) { $data['post'] = ! empty( $post->post_parent ) ? (int) $post->post_parent : null; } if ( in_array( 'source_url', $fields, true ) ) { $data['source_url'] = wp_get_attachment_url( $post->ID ); } if ( in_array( 'missing_image_sizes', $fields, true ) ) { require_once ABSPATH . 'wp-admin/includes/image.php'; $data['missing_image_sizes'] = array_keys( wp_get_missing_image_subsizes( $post->ID ) ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); $links = $response->get_links(); // Wrap the data in a response object. $response = rest_ensure_response( $data ); foreach ( $links as $rel => $rel_links ) { foreach ( $rel_links as $link ) { $response->add_link( $rel, $link['href'], $link['attributes'] ); } } /** * Filters an attachment returned from the REST API. * * Allows modification of the attachment right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post The original attachment post. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_attachment', $response, $post, $request ); } /** * Retrieves the attachment's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema as an array. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); $schema['properties']['alt_text'] = array( 'description' => __( 'Alternative text to display when attachment is not displayed.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['caption'] = array( 'description' => __( 'The attachment caption.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Caption for the attachment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML caption for the attachment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); $schema['properties']['description'] = array( 'description' => __( 'The attachment description.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Description for the attachment, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML description for the attachment, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); $schema['properties']['media_type'] = array( 'description' => __( 'Attachment type.' ), 'type' => 'string', 'enum' => array( 'image', 'file' ), 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['mime_type'] = array( 'description' => __( 'The attachment MIME type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['media_details'] = array( 'description' => __( 'Details about the media file, specific to its type.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['post'] = array( 'description' => __( 'The ID for the associated post of the attachment.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); $schema['properties']['source_url'] = array( 'description' => __( 'URL to the original attachment file.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['missing_image_sizes'] = array( 'description' => __( 'List of the missing image sizes of the attachment.' ), 'type' => 'array', 'items' => array( 'type' => 'string' ), 'context' => array( 'edit' ), 'readonly' => true, ); unset( $schema['properties']['password'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Handles an upload via raw POST data. * * @since 4.7.0 * @since 6.6.0 Added the `$time` parameter. * * @param string $data Supplied file data. * @param array $headers HTTP headers from the request. * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. * @return array|WP_Error Data from wp_handle_sideload(). */ protected function upload_from_data( $data, $headers, $time = null ) { if ( empty( $data ) ) { return new WP_Error( 'rest_upload_no_data', __( 'No data supplied.' ), array( 'status' => 400 ) ); } if ( empty( $headers['content_type'] ) ) { return new WP_Error( 'rest_upload_no_content_type', __( 'No Content-Type supplied.' ), array( 'status' => 400 ) ); } if ( empty( $headers['content_disposition'] ) ) { return new WP_Error( 'rest_upload_no_content_disposition', __( 'No Content-Disposition supplied.' ), array( 'status' => 400 ) ); } $filename = self::get_filename_from_disposition( $headers['content_disposition'] ); if ( empty( $filename ) ) { return new WP_Error( 'rest_upload_invalid_disposition', __( 'Invalid Content-Disposition supplied. Content-Disposition needs to be formatted as `attachment; filename="image.png"` or similar.' ), array( 'status' => 400 ) ); } if ( ! empty( $headers['content_md5'] ) ) { $content_md5 = array_shift( $headers['content_md5'] ); $expected = trim( $content_md5 ); $actual = md5( $data ); if ( $expected !== $actual ) { return new WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) ); } } // Get the content-type. $type = array_shift( $headers['content_type'] ); // Include filesystem functions to get access to wp_tempnam() and wp_handle_sideload(). require_once ABSPATH . 'wp-admin/includes/file.php'; // Save the file. $tmpfname = wp_tempnam( $filename ); $fp = fopen( $tmpfname, 'w+' ); if ( ! $fp ) { return new WP_Error( 'rest_upload_file_error', __( 'Could not open file handle.' ), array( 'status' => 500 ) ); } fwrite( $fp, $data ); fclose( $fp ); // Now, sideload it in. $file_data = array( 'error' => null, 'tmp_name' => $tmpfname, 'name' => $filename, 'type' => $type, ); $size_check = self::check_upload_size( $file_data ); if ( is_wp_error( $size_check ) ) { return $size_check; } $overrides = array( 'test_form' => false, ); $sideloaded = wp_handle_sideload( $file_data, $overrides, $time ); if ( isset( $sideloaded['error'] ) ) { @unlink( $tmpfname ); return new WP_Error( 'rest_upload_sideload_error', $sideloaded['error'], array( 'status' => 500 ) ); } return $sideloaded; } /** * Parses filename from a Content-Disposition header value. * * As per RFC6266: * * content-disposition = "Content-Disposition" ":" * disposition-type *( ";" disposition-parm ) * * disposition-type = "inline" | "attachment" | disp-ext-type * ; case-insensitive * disp-ext-type = token * * disposition-parm = filename-parm | disp-ext-parm * * filename-parm = "filename" "=" value * | "filename*" "=" ext-value * * disp-ext-parm = token "=" value * | ext-token "=" ext-value * ext-token = <the characters in token, followed by "*"> * * @since 4.7.0 * * @link https://tools.ietf.org/html/rfc2388 * @link https://tools.ietf.org/html/rfc6266 * * @param string[] $disposition_header List of Content-Disposition header values. * @return string|null Filename if available, or null if not found. */ public static function get_filename_from_disposition( $disposition_header ) { // Get the filename. $filename = null; foreach ( $disposition_header as $value ) { $value = trim( $value ); if ( ! str_contains( $value, ';' ) ) { continue; } list( , $attr_parts ) = explode( ';', $value, 2 ); $attr_parts = explode( ';', $attr_parts ); $attributes = array(); foreach ( $attr_parts as $part ) { if ( ! str_contains( $part, '=' ) ) { continue; } list( $key, $value ) = explode( '=', $part, 2 ); $attributes[ trim( $key ) ] = trim( $value ); } if ( empty( $attributes['filename'] ) ) { continue; } $filename = trim( $attributes['filename'] ); // Unquote quoted filename, but after trimming. if ( str_starts_with( $filename, '"' ) && str_ends_with( $filename, '"' ) ) { $filename = substr( $filename, 1, -1 ); } } return $filename; } /** * Retrieves the query params for collections of attachments. * * @since 4.7.0 * * @return array Query parameters for the attachment collection as an array. */ public function get_collection_params() { $params = parent::get_collection_params(); $params['status']['default'] = 'inherit'; $params['status']['items']['enum'] = array( 'inherit', 'private', 'trash' ); $media_types = $this->get_media_types(); $params['media_type'] = array( 'default' => null, 'description' => __( 'Limit result set to attachments of a particular media type.' ), 'type' => 'string', 'enum' => array_keys( $media_types ), ); $params['mime_type'] = array( 'default' => null, 'description' => __( 'Limit result set to attachments of a particular MIME type.' ), 'type' => 'string', ); return $params; } /** * Handles an upload via multipart/form-data ($_FILES). * * @since 4.7.0 * @since 6.6.0 Added the `$time` parameter. * * @param array $files Data from the `$_FILES` superglobal. * @param array $headers HTTP headers from the request. * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. * @return array|WP_Error Data from wp_handle_upload(). */ protected function upload_from_file( $files, $headers, $time = null ) { if ( empty( $files ) ) { return new WP_Error( 'rest_upload_no_data', __( 'No data supplied.' ), array( 'status' => 400 ) ); } // Verify hash, if given. if ( ! empty( $headers['content_md5'] ) ) { $content_md5 = array_shift( $headers['content_md5'] ); $expected = trim( $content_md5 ); $actual = md5_file( $files['file']['tmp_name'] ); if ( $expected !== $actual ) { return new WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) ); } } // Pass off to WP to handle the actual upload. $overrides = array( 'test_form' => false, ); // Bypasses is_uploaded_file() when running unit tests. if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) { $overrides['action'] = 'wp_handle_mock_upload'; } $size_check = self::check_upload_size( $files['file'] ); if ( is_wp_error( $size_check ) ) { return $size_check; } // Include filesystem functions to get access to wp_handle_upload(). require_once ABSPATH . 'wp-admin/includes/file.php'; $file = wp_handle_upload( $files['file'], $overrides, $time ); if ( isset( $file['error'] ) ) { return new WP_Error( 'rest_upload_unknown_error', $file['error'], array( 'status' => 500 ) ); } return $file; } /** * Retrieves the supported media types. * * Media types are considered the MIME type category. * * @since 4.7.0 * * @return array Array of supported media types. */ protected function get_media_types() { $media_types = array(); foreach ( get_allowed_mime_types() as $mime_type ) { $parts = explode( '/', $mime_type ); if ( ! isset( $media_types[ $parts[0] ] ) ) { $media_types[ $parts[0] ] = array(); } $media_types[ $parts[0] ][] = $mime_type; } return $media_types; } /** * Determine if uploaded file exceeds space quota on multisite. * * Replicates check_upload_size(). * * @since 4.9.8 * * @param array $file $_FILES array for a given file. * @return true|WP_Error True if can upload, error for errors. */ protected function check_upload_size( $file ) { if ( ! is_multisite() ) { return true; } if ( get_site_option( 'upload_space_check_disabled' ) ) { return true; } $space_left = get_upload_space_available(); $file_size = filesize( $file['tmp_name'] ); if ( $space_left < $file_size ) { return new WP_Error( 'rest_upload_limited_space', /* translators: %s: Required disk space in kilobytes. */ sprintf( __( 'Not enough space to upload. %s KB needed.' ), number_format( ( $file_size - $space_left ) / KB_IN_BYTES ) ), array( 'status' => 400 ) ); } if ( $file_size > ( KB_IN_BYTES * get_site_option( 'fileupload_maxk', 1500 ) ) ) { return new WP_Error( 'rest_upload_file_too_big', /* translators: %s: Maximum allowed file size in kilobytes. */ sprintf( __( 'This file is too big. Files must be less than %s KB in size.' ), get_site_option( 'fileupload_maxk', 1500 ) ), array( 'status' => 400 ) ); } // Include multisite admin functions to get access to upload_is_user_over_quota(). require_once ABSPATH . 'wp-admin/includes/ms.php'; if ( upload_is_user_over_quota( false ) ) { return new WP_Error( 'rest_upload_user_quota_exceeded', __( 'You have used your space quota. Please delete files before uploading.' ), array( 'status' => 400 ) ); } return true; } /** * Gets the request args for the edit item route. * * @since 5.5.0 * * @return array */ protected function get_edit_media_item_args() { return array( 'src' => array( 'description' => __( 'URL to the edited image file.' ), 'type' => 'string', 'format' => 'uri', 'required' => true, ), 'modifiers' => array( 'description' => __( 'Array of image edits.' ), 'type' => 'array', 'minItems' => 1, 'items' => array( 'description' => __( 'Image edit.' ), 'type' => 'object', 'required' => array( 'type', 'args', ), 'oneOf' => array( array( 'title' => __( 'Rotation' ), 'properties' => array( 'type' => array( 'description' => __( 'Rotation type.' ), 'type' => 'string', 'enum' => array( 'rotate' ), ), 'args' => array( 'description' => __( 'Rotation arguments.' ), 'type' => 'object', 'required' => array( 'angle', ), 'properties' => array( 'angle' => array( 'description' => __( 'Angle to rotate clockwise in degrees.' ), 'type' => 'number', ), ), ), ), ), array( 'title' => __( 'Crop' ), 'properties' => array( 'type' => array( 'description' => __( 'Crop type.' ), 'type' => 'string', 'enum' => array( 'crop' ), ), 'args' => array( 'description' => __( 'Crop arguments.' ), 'type' => 'object', 'required' => array( 'left', 'top', 'width', 'height', ), 'properties' => array( 'left' => array( 'description' => __( 'Horizontal position from the left to begin the crop as a percentage of the image width.' ), 'type' => 'number', ), 'top' => array( 'description' => __( 'Vertical position from the top to begin the crop as a percentage of the image height.' ), 'type' => 'number', ), 'width' => array( 'description' => __( 'Width of the crop as a percentage of the image width.' ), 'type' => 'number', ), 'height' => array( 'description' => __( 'Height of the crop as a percentage of the image height.' ), 'type' => 'number', ), ), ), ), ), ), ), ), 'rotation' => array( 'description' => __( 'The amount to rotate the image clockwise in degrees. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'integer', 'minimum' => 0, 'exclusiveMinimum' => true, 'maximum' => 360, 'exclusiveMaximum' => true, ), 'x' => array( 'description' => __( 'As a percentage of the image, the x position to start the crop from. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'y' => array( 'description' => __( 'As a percentage of the image, the y position to start the crop from. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'width' => array( 'description' => __( 'As a percentage of the image, the width to crop the image to. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), 'height' => array( 'description' => __( 'As a percentage of the image, the height to crop the image to. DEPRECATED: Use `modifiers` instead.' ), 'type' => 'number', 'minimum' => 0, 'maximum' => 100, ), ); } } <?php /** * REST API: WP_REST_Font_Families_Controller class * * @package WordPress * @subpackage REST_API * @since 6.5.0 */ /** * Font Families Controller class. * * @since 6.5.0 */ class WP_REST_Font_Families_Controller extends WP_REST_Posts_Controller { /** * The latest version of theme.json schema supported by the controller. * * @since 6.5.0 * @var int */ const LATEST_THEME_JSON_VERSION_SUPPORTED = 3; /** * Whether the controller supports batching. * * @since 6.5.0 * @var false */ protected $allow_batch = false; /** * Checks if a given request has access to font families. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( ! current_user_can( $post_type->cap->read ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font families.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Checks if a given request has access to a font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( ! current_user_can( 'read_post', $post->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access this font family.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Validates settings when creating or updating a font family. * * @since 6.5.0 * * @param string $value Encoded JSON string of font family settings. * @param WP_REST_Request $request Request object. * @return true|WP_Error True if the settings are valid, otherwise a WP_Error object. */ public function validate_font_family_settings( $value, $request ) { $settings = json_decode( $value, true ); // Check settings string is valid JSON. if ( null === $settings ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: Parameter name: "font_family_settings". */ sprintf( __( '%s parameter must be a valid JSON string.' ), 'font_family_settings' ), array( 'status' => 400 ) ); } $schema = $this->get_item_schema()['properties']['font_family_settings']; $required = $schema['required']; if ( isset( $request['id'] ) ) { // Allow sending individual properties if we are updating an existing font family. unset( $schema['required'] ); // But don't allow updating the slug, since it is used as a unique identifier. if ( isset( $settings['slug'] ) ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: Name of parameter being updated: font_family_settings[slug]". */ sprintf( __( '%s cannot be updated.' ), 'font_family_settings[slug]' ), array( 'status' => 400 ) ); } } // Check that the font face settings match the theme.json schema. $has_valid_settings = rest_validate_value_from_schema( $settings, $schema, 'font_family_settings' ); if ( is_wp_error( $has_valid_settings ) ) { $has_valid_settings->add_data( array( 'status' => 400 ) ); return $has_valid_settings; } // Check that none of the required settings are empty values. foreach ( $required as $key ) { if ( isset( $settings[ $key ] ) && ! $settings[ $key ] ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: Name of the empty font family setting parameter, e.g. "font_family_settings[slug]". */ sprintf( __( '%s cannot be empty.' ), "font_family_settings[ $key ]" ), array( 'status' => 400 ) ); } } return true; } /** * Sanitizes the font family settings when creating or updating a font family. * * @since 6.5.0 * * @param string $value Encoded JSON string of font family settings. * @return array Decoded array of font family settings. */ public function sanitize_font_family_settings( $value ) { // Settings arrive as stringified JSON, since this is a multipart/form-data request. $settings = json_decode( $value, true ); $schema = $this->get_item_schema()['properties']['font_family_settings']['properties']; // Sanitize settings based on callbacks in the schema. foreach ( $settings as $key => $value ) { $sanitize_callback = $schema[ $key ]['arg_options']['sanitize_callback']; $settings[ $key ] = call_user_func( $sanitize_callback, $value ); } return $settings; } /** * Creates a single font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $settings = $request->get_param( 'font_family_settings' ); // Check that the font family slug is unique. $query = new WP_Query( array( 'post_type' => $this->post_type, 'posts_per_page' => 1, 'name' => $settings['slug'], 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); if ( ! empty( $query->posts ) ) { return new WP_Error( 'rest_duplicate_font_family', /* translators: %s: Font family slug. */ sprintf( __( 'A font family with slug "%s" already exists.' ), $settings['slug'] ), array( 'status' => 400 ) ); } return parent::create_item( $request ); } /** * Deletes a single font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for font families. if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.' ), 'force=true' ), array( 'status' => 501 ) ); } return parent::delete_item( $request ); } /** * Prepares a single font family output for response. * * @since 6.5.0 * * @param WP_Post $item Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $item->ID; } if ( rest_is_field_included( 'theme_json_version', $fields ) ) { $data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED; } if ( rest_is_field_included( 'font_faces', $fields ) ) { $data['font_faces'] = $this->get_font_face_ids( $item->ID ); } if ( rest_is_field_included( 'font_family_settings', $fields ) ) { $data['font_family_settings'] = $this->get_settings_from_post( $item ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } /** * Filters the font family data for a REST API response. * * @since 6.5.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post Font family post object. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_prepare_wp_font_family', $response, $item, $request ); } /** * Retrieves the post's schema, conforming to JSON Schema. * * @since 6.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', // Base properties for every Post. 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.', 'default' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'theme_json_version' => array( 'description' => __( 'Version of the theme.json schema used for the typography settings.' ), 'type' => 'integer', 'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'minimum' => 2, 'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'context' => array( 'view', 'edit', 'embed' ), ), 'font_faces' => array( 'description' => __( 'The IDs of the child font faces in the font family.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), 'items' => array( 'type' => 'integer', ), ), // Font family settings come directly from theme.json schema // See https://schemas.wp.org/trunk/theme.json 'font_family_settings' => array( 'description' => __( 'font-face definition in theme.json format.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'name' => array( 'description' => __( 'Name of the font family preset, translatable.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'slug' => array( 'description' => __( 'Kebab-case unique identifier for the font family preset.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', ), ), 'fontFamily' => array( 'description' => __( 'CSS font-family value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => array( 'WP_Font_Utils', 'sanitize_font_family' ), ), ), 'preview' => array( 'description' => __( 'URL to a preview image of the font family.' ), 'type' => 'string', 'format' => 'uri', 'default' => '', 'arg_options' => array( 'sanitize_callback' => 'sanitize_url', ), ), ), 'required' => array( 'name', 'slug', 'fontFamily' ), 'additionalProperties' => false, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the item's schema for display / public consumption purposes. * * @since 6.5.0 * * @return array Public item schema data. */ public function get_public_item_schema() { $schema = parent::get_public_item_schema(); // Also remove `arg_options' from child font_family_settings properties, since the parent // controller only handles the top level properties. foreach ( $schema['properties']['font_family_settings']['properties'] as &$property ) { unset( $property['arg_options'] ); } return $schema; } /** * Retrieves the query params for the font family collection. * * @since 6.5.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); // Remove unneeded params. unset( $query_params['after'], $query_params['modified_after'], $query_params['before'], $query_params['modified_before'], $query_params['search'], $query_params['search_columns'], $query_params['status'] ); $query_params['orderby']['default'] = 'id'; $query_params['orderby']['enum'] = array( 'id', 'include' ); /** * Filters collection parameters for the font family controller. * * @since 6.5.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_wp_font_family_collection_params', $query_params ); } /** * Get the arguments used when creating or updating a font family. * * @since 6.5.0 * * @return array Font family create/edit arguments. */ public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { if ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) { $properties = $this->get_item_schema()['properties']; return array( 'theme_json_version' => $properties['theme_json_version'], // When creating or updating, font_family_settings is stringified JSON, to work with multipart/form-data. // Font families don't currently support file uploads, but may accept preview files in the future. 'font_family_settings' => array( 'description' => __( 'font-family declaration in theme.json format, encoded as a string.' ), 'type' => 'string', 'required' => true, 'validate_callback' => array( $this, 'validate_font_family_settings' ), 'sanitize_callback' => array( $this, 'sanitize_font_family_settings' ), ), ); } return parent::get_endpoint_args_for_item_schema( $method ); } /** * Get the child font face post IDs. * * @since 6.5.0 * * @param int $font_family_id Font family post ID. * @return int[] Array of child font face post IDs. */ protected function get_font_face_ids( $font_family_id ) { $query = new WP_Query( array( 'fields' => 'ids', 'post_parent' => $font_family_id, 'post_type' => 'wp_font_face', 'posts_per_page' => 99, 'order' => 'ASC', 'orderby' => 'id', 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); return $query->posts; } /** * Prepares font family links for the request. * * @since 6.5.0 * * @param WP_Post $post Post object. * @return array Links for the given post. */ protected function prepare_links( $post ) { // Entity meta. $links = parent::prepare_links( $post ); return array( 'self' => $links['self'], 'collection' => $links['collection'], 'font_faces' => $this->prepare_font_face_links( $post->ID ), ); } /** * Prepares child font face links for the request. * * @param int $font_family_id Font family post ID. * @return array Links for the child font face posts. */ protected function prepare_font_face_links( $font_family_id ) { $font_face_ids = $this->get_font_face_ids( $font_family_id ); $links = array(); foreach ( $font_face_ids as $font_face_id ) { $links[] = array( 'embeddable' => true, 'href' => rest_url( sprintf( '%s/%s/%s/font-faces/%s', $this->namespace, $this->rest_base, $font_family_id, $font_face_id ) ), ); } return $links; } /** * Prepares a single font family post for create or update. * * @since 6.5.0 * * @param WP_REST_Request $request Request object. * @return stdClass|WP_Error Post object or WP_Error. */ protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); // Settings have already been decoded by ::sanitize_font_family_settings(). $settings = $request->get_param( 'font_family_settings' ); // This is an update and we merge with the existing font family. if ( isset( $request['id'] ) ) { $existing_post = $this->get_post( $request['id'] ); if ( is_wp_error( $existing_post ) ) { return $existing_post; } $prepared_post->ID = $existing_post->ID; $existing_settings = $this->get_settings_from_post( $existing_post ); $settings = array_merge( $existing_settings, $settings ); } $prepared_post->post_type = $this->post_type; $prepared_post->post_status = 'publish'; $prepared_post->post_title = $settings['name']; $prepared_post->post_name = sanitize_title( $settings['slug'] ); // Remove duplicate information from settings. unset( $settings['name'] ); unset( $settings['slug'] ); $prepared_post->post_content = wp_json_encode( $settings ); return $prepared_post; } /** * Gets the font family's settings from the post. * * @since 6.5.0 * * @param WP_Post $post Font family post object. * @return array Font family settings array. */ protected function get_settings_from_post( $post ) { $settings_json = json_decode( $post->post_content, true ); // Default to empty strings if the settings are missing. return array( 'name' => isset( $post->post_title ) && $post->post_title ? $post->post_title : '', 'slug' => isset( $post->post_name ) && $post->post_name ? $post->post_name : '', 'fontFamily' => isset( $settings_json['fontFamily'] ) && $settings_json['fontFamily'] ? $settings_json['fontFamily'] : '', 'preview' => isset( $settings_json['preview'] ) && $settings_json['preview'] ? $settings_json['preview'] : '', ); } } <?php /** * REST API: WP_REST_Template_Autosaves_Controller class. * * @package WordPress * @subpackage REST_API * @since 6.4.0 */ /** * Core class used to access template autosaves via the REST API. * * @since 6.4.0 * * @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. * * @since 6.4.0 * @var WP_REST_Controller */ private $parent_controller; /** * Revision controller. * * @since 6.4.0 * @var WP_REST_Revisions_Controller */ private $revisions_controller; /** * The base of the parent controller's route. * * @since 6.4.0 * @var string */ private $parent_base; /** * Constructor. * * @since 6.4.0 * * @param string $parent_post_type Post type of the parent. */ 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(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Templates_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $revisions_controller = $post_type_object->get_revisions_rest_controller(); if ( ! $revisions_controller ) { $revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type ); } $this->revisions_controller = $revisions_controller; $this->rest_base = 'autosaves'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** * Registers the routes for autosaves. * * @since 6.4.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/(?P<id>%s%s)/%s', $this->parent_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', // Matches the template name. '[\/\w%-]+', $this->rest_base ), array( 'args' => array( 'id' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s/%s', $this->parent_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', // Matches the template name. '[\/\w%-]+', $this->rest_base, '(?P<id>[\d]+)' ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), 'id' => array( 'description' => __( 'The ID for the autosave.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Prepares the item for the REST response. * * @since 6.4.0 * * @param WP_Post $item Post revision object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { $template = _build_block_template_result_from_post( $item ); $response = $this->parent_controller->prepare_item_for_response( $template, $request ); // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { return $response; } $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->post_parent; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template ); $response->add_links( $links ); } return $response; } /** * Gets the autosave, if the ID is valid. * * @since 6.4.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_Post|WP_Error Autosave post object if ID is valid, WP_Error otherwise. */ public function get_item( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $autosave = wp_get_post_autosave( $parent->ID ); if ( ! $autosave ) { return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this template.' ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $autosave, $request ); return $response; } /** * Get the parent post. * * @since 6.4.0 * * @param int $parent_id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_parent( $parent_id ) { return $this->revisions_controller->get_parent( $parent_id ); } /** * Prepares links for the request. * * @since 6.4.0 * * @param WP_Block_Template $template Template. * @return array Links for the given post. */ protected function prepare_links( $template ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ), ), 'parent' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ), ), ); return $links; } /** * Retrieves the autosave's schema, conforming to JSON Schema. * * @since 6.4.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = $this->revisions_controller->get_item_schema(); return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Widgets_Controller class * * @package WordPress * @subpackage REST_API * @since 5.8.0 */ /** * Core class to access widgets via the REST API. * * @since 5.8.0 * * @see WP_REST_Controller */ class WP_REST_Widgets_Controller extends WP_REST_Controller { /** * Tracks whether {@see retrieve_widgets()} has been called in the current request. * * @since 5.9.0 * @var bool */ protected $widgets_retrieved = false; /** * Whether the controller supports batching. * * @since 5.9.0 * @var array */ protected $allow_batch = array( 'v1' => true ); /** * Widgets controller constructor. * * @since 5.8.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'widgets'; } /** * Registers the widget routes for the controller. * * @since 5.8.0 */ public function register_routes() { register_rest_route( $this->namespace, $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema(), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, $this->rest_base . '/(?P<id>[\w\-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'description' => __( 'Whether to force removal of the widget, or move it to the inactive sidebar.' ), 'type' => 'boolean', ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to get widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $this->retrieve_widgets(); if ( isset( $request['sidebar'] ) && $this->check_read_sidebar_permission( $request['sidebar'] ) ) { return true; } foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { if ( $this->check_read_sidebar_permission( $sidebar_id ) ) { return true; } } return $this->permissions_check( $request ); } /** * Retrieves a collection of widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $this->retrieve_widgets(); $prepared = array(); $permissions_check = $this->permissions_check( $request ); foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) { if ( isset( $request['sidebar'] ) && $sidebar_id !== $request['sidebar'] ) { continue; } if ( is_wp_error( $permissions_check ) && ! $this->check_read_sidebar_permission( $sidebar_id ) ) { continue; } foreach ( $widget_ids as $widget_id ) { $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); if ( ! is_wp_error( $response ) ) { $prepared[] = $this->prepare_response_for_collection( $response ); } } } return new WP_REST_Response( $prepared ); } /** * Checks if a given request has access to get a widget. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( $sidebar_id && $this->check_read_sidebar_permission( $sidebar_id ) ) { return true; } return $this->permissions_check( $request ); } /** * Checks if a sidebar can be read publicly. * * @since 5.9.0 * * @param string $sidebar_id The sidebar ID. * @return bool Whether the sidebar can be read. */ protected function check_read_sidebar_permission( $sidebar_id ) { $sidebar = wp_get_sidebar( $sidebar_id ); return ! empty( $sidebar['show_in_rest'] ); } /** * Gets an individual widget. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( is_null( $sidebar_id ) ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); } /** * Checks if a given request has access to create widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Creates a widget. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $sidebar_id = $request['sidebar']; $widget_id = $this->save_widget( $request, $sidebar_id ); if ( is_wp_error( $widget_id ) ) { return $widget_id; } wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); $request['context'] = 'edit'; $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request ); if ( is_wp_error( $response ) ) { return $response; } $response->set_status( 201 ); return $response; } /** * Checks if a given request has access to update widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Updates an existing widget. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { global $wp_widget_factory; /* * retrieve_widgets() contains logic to move "hidden" or "lost" widgets to the * wp_inactive_widgets sidebar based on the contents of the $sidebars_widgets global. * * When batch requests are processed, this global is not properly updated by previous * calls, resulting in widgets incorrectly being moved to the wp_inactive_widgets * sidebar. * * See https://core.trac.wordpress.org/ticket/53657. */ wp_get_sidebars_widgets(); $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); // Allow sidebar to be unset or missing when widget is not a WP_Widget. $parsed_id = wp_parse_widget_id( $widget_id ); $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); if ( is_null( $sidebar_id ) && $widget_object ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } if ( $request->has_param( 'instance' ) || $request->has_param( 'form_data' ) ) { $maybe_error = $this->save_widget( $request, $sidebar_id ); if ( is_wp_error( $maybe_error ) ) { return $maybe_error; } } if ( $request->has_param( 'sidebar' ) ) { if ( $sidebar_id !== $request['sidebar'] ) { $sidebar_id = $request['sidebar']; wp_assign_widget_to_sidebar( $widget_id, $sidebar_id ); } } $request['context'] = 'edit'; return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); } /** * Checks if a given request has access to delete widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { return $this->permissions_check( $request ); } /** * Deletes a widget. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * @global array $wp_registered_widget_updates The registered widget update functions. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { global $wp_widget_factory, $wp_registered_widget_updates; /* * retrieve_widgets() contains logic to move "hidden" or "lost" widgets to the * wp_inactive_widgets sidebar based on the contents of the $sidebars_widgets global. * * When batch requests are processed, this global is not properly updated by previous * calls, resulting in widgets incorrectly being moved to the wp_inactive_widgets * sidebar. * * See https://core.trac.wordpress.org/ticket/53657. */ wp_get_sidebars_widgets(); $this->retrieve_widgets(); $widget_id = $request['id']; $sidebar_id = wp_find_widgets_sidebar( $widget_id ); if ( is_null( $sidebar_id ) ) { return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.' ), array( 'status' => 404 ) ); } $request['context'] = 'edit'; if ( $request['force'] ) { $response = $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request ); $parsed_id = wp_parse_widget_id( $widget_id ); $id_base = $parsed_id['id_base']; $original_post = $_POST; $original_request = $_REQUEST; $_POST = array( 'sidebar' => $sidebar_id, "widget-$id_base" => array(), 'the-widget-id' => $widget_id, 'delete_widget' => '1', ); $_REQUEST = $_POST; /** This action is documented in wp-admin/widgets-form.php */ do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base ); $callback = $wp_registered_widget_updates[ $id_base ]['callback']; $params = $wp_registered_widget_updates[ $id_base ]['params']; if ( is_callable( $callback ) ) { ob_start(); call_user_func_array( $callback, $params ); ob_end_clean(); } $_POST = $original_post; $_REQUEST = $original_request; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); if ( $widget_object ) { /* * WP_Widget sets `updated = true` after an update to prevent more than one widget * from being saved per request. This isn't what we want in the REST API, though, * as we support batch requests. */ $widget_object->updated = false; } wp_assign_widget_to_sidebar( $widget_id, '' ); $response->set_data( array( 'deleted' => true, 'previous' => $response->get_data(), ) ); } else { wp_assign_widget_to_sidebar( $widget_id, 'wp_inactive_widgets' ); $response = $this->prepare_item_for_response( array( 'sidebar_id' => 'wp_inactive_widgets', 'widget_id' => $widget_id, ), $request ); } /** * Fires after a widget is deleted via the REST API. * * @since 5.8.0 * * @param string $widget_id ID of the widget marked for deletion. * @param string $sidebar_id ID of the sidebar the widget was deleted from. * @param WP_REST_Response|WP_Error $response The response data, or WP_Error object on failure. * @param WP_REST_Request $request The request sent to the API. */ do_action( 'rest_delete_widget', $widget_id, $sidebar_id, $response, $request ); return $response; } /** * Performs a permissions check for managing widgets. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error */ protected function permissions_check( $request ) { if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } /** * Looks for "lost" widgets once per request. * * @since 5.9.0 * * @see retrieve_widgets() */ protected function retrieve_widgets() { if ( ! $this->widgets_retrieved ) { retrieve_widgets(); $this->widgets_retrieved = true; } } /** * Saves the widget in the request object. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * @global array $wp_registered_widget_updates The registered widget update functions. * * @param WP_REST_Request $request Full details about the request. * @param string $sidebar_id ID of the sidebar the widget belongs to. * @return string|WP_Error The saved widget ID. */ protected function save_widget( $request, $sidebar_id ) { global $wp_widget_factory, $wp_registered_widget_updates; require_once ABSPATH . 'wp-admin/includes/widgets.php'; // For next_widget_id_number(). if ( isset( $request['id'] ) ) { // Saving an existing widget. $id = $request['id']; $parsed_id = wp_parse_widget_id( $id ); $id_base = $parsed_id['id_base']; $number = isset( $parsed_id['number'] ) ? $parsed_id['number'] : null; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); $creating = false; } elseif ( $request['id_base'] ) { // Saving a new widget. $id_base = $request['id_base']; $widget_object = $wp_widget_factory->get_widget_object( $id_base ); $number = $widget_object ? next_widget_id_number( $id_base ) : null; $id = $widget_object ? $id_base . '-' . $number : $id_base; $creating = true; } else { return new WP_Error( 'rest_invalid_widget', __( 'Widget type (id_base) is required.' ), array( 'status' => 400 ) ); } if ( ! isset( $wp_registered_widget_updates[ $id_base ] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided widget type (id_base) cannot be updated.' ), array( 'status' => 400 ) ); } if ( isset( $request['instance'] ) ) { if ( ! $widget_object ) { return new WP_Error( 'rest_invalid_widget', __( 'Cannot set instance on a widget that does not extend WP_Widget.' ), array( 'status' => 400 ) ); } if ( isset( $request['instance']['raw'] ) ) { if ( empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'Widget type does not support raw instances.' ), array( 'status' => 400 ) ); } $instance = $request['instance']['raw']; } elseif ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) { $serialized_instance = base64_decode( $request['instance']['encoded'] ); if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is malformed.' ), array( 'status' => 400 ) ); } $instance = unserialize( $serialized_instance ); } else { return new WP_Error( 'rest_invalid_widget', __( 'The provided instance is invalid. Must contain raw OR encoded and hash.' ), array( 'status' => 400 ) ); } $form_data = array( "widget-$id_base" => array( $number => $instance, ), 'sidebar' => $sidebar_id, ); } elseif ( isset( $request['form_data'] ) ) { $form_data = $request['form_data']; } else { $form_data = array(); } $original_post = $_POST; $original_request = $_REQUEST; foreach ( $form_data as $key => $value ) { $slashed_value = wp_slash( $value ); $_POST[ $key ] = $slashed_value; $_REQUEST[ $key ] = $slashed_value; } $callback = $wp_registered_widget_updates[ $id_base ]['callback']; $params = $wp_registered_widget_updates[ $id_base ]['params']; if ( is_callable( $callback ) ) { ob_start(); call_user_func_array( $callback, $params ); ob_end_clean(); } $_POST = $original_post; $_REQUEST = $original_request; if ( $widget_object ) { // Register any multi-widget that the update callback just created. $widget_object->_set( $number ); $widget_object->_register_one( $number ); /* * WP_Widget sets `updated = true` after an update to prevent more than one widget * from being saved per request. This isn't what we want in the REST API, though, * as we support batch requests. */ $widget_object->updated = false; } /** * Fires after a widget is created or updated via the REST API. * * @since 5.8.0 * * @param string $id ID of the widget being saved. * @param string $sidebar_id ID of the sidebar containing the widget being saved. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a widget, false when updating. */ do_action( 'rest_after_save_widget', $id, $sidebar_id, $request, $creating ); return $id; } /** * Prepares the widget for the REST response. * * @since 5.8.0 * * @global WP_Widget_Factory $wp_widget_factory * @global array $wp_registered_widgets The registered widgets. * * @param array $item An array containing a widget_id and sidebar_id. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { global $wp_widget_factory, $wp_registered_widgets; $widget_id = $item['widget_id']; $sidebar_id = $item['sidebar_id']; if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) { return new WP_Error( 'rest_invalid_widget', __( 'The requested widget is invalid.' ), array( 'status' => 500 ) ); } $widget = $wp_registered_widgets[ $widget_id ]; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php */ return apply_filters( 'rest_prepare_widget', new WP_REST_Response( array() ), $widget, $request ); } $parsed_id = wp_parse_widget_id( $widget_id ); $fields = $this->get_fields_for_response( $request ); $prepared = array( 'id' => $widget_id, 'id_base' => $parsed_id['id_base'], 'sidebar' => $sidebar_id, 'rendered' => '', 'rendered_form' => null, 'instance' => null, ); if ( rest_is_field_included( 'rendered', $fields ) && 'wp_inactive_widgets' !== $sidebar_id ) { $prepared['rendered'] = trim( wp_render_widget( $widget_id, $sidebar_id ) ); } if ( rest_is_field_included( 'rendered_form', $fields ) ) { $rendered_form = wp_render_widget_control( $widget_id ); if ( ! is_null( $rendered_form ) ) { $prepared['rendered_form'] = trim( $rendered_form ); } } if ( rest_is_field_included( 'instance', $fields ) ) { $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] ); if ( $widget_object && isset( $parsed_id['number'] ) ) { $all_instances = $widget_object->get_settings(); $instance = $all_instances[ $parsed_id['number'] ]; $serialized_instance = serialize( $instance ); $prepared['instance']['encoded'] = base64_encode( $serialized_instance ); $prepared['instance']['hash'] = wp_hash( $serialized_instance ); if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) { // Use new stdClass so that JSON result is {} and not []. $prepared['instance']['raw'] = empty( $instance ) ? new stdClass() : $instance; } } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $prepared = $this->add_additional_fields_to_object( $prepared, $request ); $prepared = $this->filter_response_by_context( $prepared, $context ); $response = rest_ensure_response( $prepared ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $prepared ) ); } /** * Filters the REST API response for a widget. * * @since 5.8.0 * * @param WP_REST_Response|WP_Error $response The response object, or WP_Error object on failure. * @param array $widget The registered widget data. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_widget', $response, $widget, $request ); } /** * Prepares links for the widget. * * @since 5.8.0 * * @param array $prepared Widget. * @return array Links for the given widget. */ protected function prepare_links( $prepared ) { $id_base = ! empty( $prepared['id_base'] ) ? $prepared['id_base'] : $prepared['id']; return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $prepared['id'] ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'about' => array( 'href' => rest_url( sprintf( 'wp/v2/widget-types/%s', $id_base ) ), 'embeddable' => true, ), 'https://api.w.org/sidebar' => array( 'href' => rest_url( sprintf( 'wp/v2/sidebars/%s/', $prepared['sidebar'] ) ), ), ); } /** * Gets the list of collection params. * * @since 5.8.0 * * @return array[] */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'sidebar' => array( 'description' => __( 'The sidebar to return widgets for.' ), 'type' => 'string', ), ); } /** * Retrieves the widget's schema, conforming to JSON Schema. * * @since 5.8.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'widget', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the widget.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'id_base' => array( 'description' => __( 'The type of the widget. Corresponds to ID in widget-types endpoint.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'sidebar' => array( 'description' => __( 'The sidebar the widget belongs to.' ), 'type' => 'string', 'default' => 'wp_inactive_widgets', 'required' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML representation of the widget.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rendered_form' => array( 'description' => __( 'HTML representation of the widget admin form.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'instance' => array( 'description' => __( 'Instance settings of the widget, if supported.' ), 'type' => 'object', 'context' => array( 'edit' ), 'default' => null, 'properties' => array( 'encoded' => array( 'description' => __( 'Base64 encoded representation of the instance settings.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'hash' => array( 'description' => __( 'Cryptographic hash of the instance settings.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'raw' => array( 'description' => __( 'Unencoded instance settings, if supported.' ), 'type' => 'object', 'context' => array( 'edit' ), ), ), ), 'form_data' => array( 'description' => __( 'URL-encoded form data from the widget admin form. Used to update a widget that does not support instance. Write only.' ), 'type' => 'string', 'context' => array(), 'arg_options' => array( 'sanitize_callback' => static function ( $form_data ) { $array = array(); wp_parse_str( $form_data, $array ); return $array; }, ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Font_Faces_Controller class * * @package WordPress * @subpackage REST_API * @since 6.5.0 */ /** * Class to access font faces through the REST API. */ class WP_REST_Font_Faces_Controller extends WP_REST_Posts_Controller { /** * The latest version of theme.json schema supported by the controller. * * @since 6.5.0 * @var int */ const LATEST_THEME_JSON_VERSION_SUPPORTED = 3; /** * Whether the controller supports batching. * * @since 6.5.0 * @var false */ protected $allow_batch = false; /** * Registers the routes for posts. * * @since 6.5.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( 'args' => array( 'font_family_id' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'required' => true, ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_create_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'font_family_id' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'required' => true, ), 'id' => array( 'description' => __( 'Unique identifier for the font face.' ), 'type' => 'integer', 'required' => true, ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.', 'default' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to font faces. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( ! current_user_can( $post_type->cap->read ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font faces.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Checks if a given request has access to a font face. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( ! current_user_can( 'read_post', $post->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access this font face.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Validates settings when creating a font face. * * @since 6.5.0 * * @param string $value Encoded JSON string of font face settings. * @param WP_REST_Request $request Request object. * @return true|WP_Error True if the settings are valid, otherwise a WP_Error object. */ public function validate_create_font_face_settings( $value, $request ) { $settings = json_decode( $value, true ); // Check settings string is valid JSON. if ( null === $settings ) { return new WP_Error( 'rest_invalid_param', __( 'font_face_settings parameter must be a valid JSON string.' ), array( 'status' => 400 ) ); } // Check that the font face settings match the theme.json schema. $schema = $this->get_item_schema()['properties']['font_face_settings']; $has_valid_settings = rest_validate_value_from_schema( $settings, $schema, 'font_face_settings' ); if ( is_wp_error( $has_valid_settings ) ) { $has_valid_settings->add_data( array( 'status' => 400 ) ); return $has_valid_settings; } // Check that none of the required settings are empty values. $required = $schema['required']; foreach ( $required as $key ) { if ( isset( $settings[ $key ] ) && ! $settings[ $key ] ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: Name of the missing font face settings parameter, e.g. "font_face_settings[src]". */ sprintf( __( '%s cannot be empty.' ), "font_face_setting[ $key ]" ), array( 'status' => 400 ) ); } } $srcs = is_array( $settings['src'] ) ? $settings['src'] : array( $settings['src'] ); $files = $request->get_file_params(); foreach ( $srcs as $src ) { // Check that each src is a non-empty string. $src = ltrim( $src ); if ( empty( $src ) ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: Font face source parameter name: "font_face_settings[src]". */ sprintf( __( '%s values must be non-empty strings.' ), 'font_face_settings[src]' ), array( 'status' => 400 ) ); } // Check that srcs are valid URLs or file references. if ( false === wp_http_validate_url( $src ) && ! isset( $files[ $src ] ) ) { return new WP_Error( 'rest_invalid_param', /* translators: 1: Font face source parameter name: "font_face_settings[src]", 2: The invalid src value. */ sprintf( __( '%1$s value "%2$s" must be a valid URL or file reference.' ), 'font_face_settings[src]', $src ), array( 'status' => 400 ) ); } } // Check that each file in the request references a src in the settings. foreach ( array_keys( $files ) as $file ) { if ( ! in_array( $file, $srcs, true ) ) { return new WP_Error( 'rest_invalid_param', /* translators: 1: File key (e.g. "file-0") in the request data, 2: Font face source parameter name: "font_face_settings[src]". */ sprintf( __( 'File %1$s must be used in %2$s.' ), $file, 'font_face_settings[src]' ), array( 'status' => 400 ) ); } } return true; } /** * Sanitizes the font face settings when creating a font face. * * @since 6.5.0 * * @param string $value Encoded JSON string of font face settings. * @return array Decoded and sanitized array of font face settings. */ public function sanitize_font_face_settings( $value ) { // Settings arrive as stringified JSON, since this is a multipart/form-data request. $settings = json_decode( $value, true ); $schema = $this->get_item_schema()['properties']['font_face_settings']['properties']; // Sanitize settings based on callbacks in the schema. foreach ( $settings as $key => $value ) { $sanitize_callback = $schema[ $key ]['arg_options']['sanitize_callback']; $settings[ $key ] = call_user_func( $sanitize_callback, $value ); } return $settings; } /** * Retrieves a collection of font faces within the parent font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } return parent::get_items( $request ); } /** * Retrieves a single font face within the parent font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } // Check that the font face has a valid parent font family. $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } if ( (int) $font_family->ID !== (int) $post->post_parent ) { return new WP_Error( 'rest_font_face_parent_id_mismatch', /* translators: %d: A post id. */ sprintf( __( 'The font face does not belong to the specified font family with id of "%d".' ), $font_family->ID ), array( 'status' => 404 ) ); } return parent::get_item( $request ); } /** * Creates a font face for the parent font family. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } // Settings have already been decoded by ::sanitize_font_face_settings(). $settings = $request->get_param( 'font_face_settings' ); $file_params = $request->get_file_params(); // Check that the necessary font face properties are unique. $query = new WP_Query( array( 'post_type' => $this->post_type, 'posts_per_page' => 1, 'title' => WP_Font_Utils::get_font_face_slug( $settings ), 'update_post_meta_cache' => false, 'update_post_term_cache' => false, ) ); if ( ! empty( $query->posts ) ) { return new WP_Error( 'rest_duplicate_font_face', __( 'A font face matching those settings already exists.' ), array( 'status' => 400 ) ); } // Move the uploaded font asset from the temp folder to the fonts directory. if ( ! function_exists( 'wp_handle_upload' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } $srcs = is_string( $settings['src'] ) ? array( $settings['src'] ) : $settings['src']; $processed_srcs = array(); $font_file_meta = array(); foreach ( $srcs as $src ) { // If src not a file reference, use it as is. if ( ! isset( $file_params[ $src ] ) ) { $processed_srcs[] = $src; continue; } $file = $file_params[ $src ]; $font_file = $this->handle_font_file_upload( $file ); if ( is_wp_error( $font_file ) ) { return $font_file; } $processed_srcs[] = $font_file['url']; $font_file_meta[] = $this->relative_fonts_path( $font_file['file'] ); } // Store the updated settings for prepare_item_for_database to use. $settings['src'] = count( $processed_srcs ) === 1 ? $processed_srcs[0] : $processed_srcs; $request->set_param( 'font_face_settings', $settings ); // Ensure that $settings data is slashed, so values with quotes are escaped. // WP_REST_Posts_Controller::create_item uses wp_slash() on the post_content. $font_face_post = parent::create_item( $request ); if ( is_wp_error( $font_face_post ) ) { return $font_face_post; } $font_face_id = $font_face_post->data['id']; foreach ( $font_file_meta as $font_file_path ) { add_post_meta( $font_face_id, '_wp_font_face_file', $font_file_path ); } return $font_face_post; } /** * Deletes a single font face. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $font_family = $this->get_parent_font_family_post( $request['font_family_id'] ); if ( is_wp_error( $font_family ) ) { return $font_family; } if ( (int) $font_family->ID !== (int) $post->post_parent ) { return new WP_Error( 'rest_font_face_parent_id_mismatch', /* translators: %d: A post id. */ sprintf( __( 'The font face does not belong to the specified font family with id of "%d".' ), $font_family->ID ), array( 'status' => 404 ) ); } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for font faces. if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( 'Font faces do not support trashing. Set "%s" to delete.' ), 'force=true' ), array( 'status' => 501 ) ); } return parent::delete_item( $request ); } /** * Prepares a single font face output for response. * * @since 6.5.0 * * @param WP_Post $item Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $item->ID; } if ( rest_is_field_included( 'theme_json_version', $fields ) ) { $data['theme_json_version'] = static::LATEST_THEME_JSON_VERSION_SUPPORTED; } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = $item->post_parent; } if ( rest_is_field_included( 'font_face_settings', $fields ) ) { $data['font_face_settings'] = $this->get_settings_from_post( $item ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } /** * Filters the font face data for a REST API response. * * @since 6.5.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post Font face post object. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_prepare_wp_font_face', $response, $item, $request ); } /** * Retrieves the post's schema, conforming to JSON Schema. * * @since 6.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', // Base properties for every Post. 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.', 'default' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'theme_json_version' => array( 'description' => __( 'Version of the theme.json schema used for the typography settings.' ), 'type' => 'integer', 'default' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'minimum' => 2, 'maximum' => static::LATEST_THEME_JSON_VERSION_SUPPORTED, 'context' => array( 'view', 'edit', 'embed' ), ), 'parent' => array( 'description' => __( 'The ID for the parent font family of the font face.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), // Font face settings come directly from theme.json schema // See https://schemas.wp.org/trunk/theme.json 'font_face_settings' => array( 'description' => __( 'font-face declaration in theme.json format.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'fontFamily' => array( 'description' => __( 'CSS font-family value.' ), 'type' => 'string', 'default' => '', 'arg_options' => array( 'sanitize_callback' => array( 'WP_Font_Utils', 'sanitize_font_family' ), ), ), 'fontStyle' => array( 'description' => __( 'CSS font-style value.' ), 'type' => 'string', 'default' => 'normal', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontWeight' => array( 'description' => __( 'List of available font weights, separated by a space.' ), 'default' => '400', // Changed from `oneOf` to avoid errors from loose type checking. // e.g. a fontWeight of "400" validates as both a string and an integer due to is_numeric check. 'type' => array( 'string', 'integer' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontDisplay' => array( 'description' => __( 'CSS font-display value.' ), 'type' => 'string', 'default' => 'fallback', 'enum' => array( 'auto', 'block', 'fallback', 'swap', 'optional', ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'src' => array( 'description' => __( 'Paths or URLs to the font files.' ), // Changed from `oneOf` to `anyOf` due to rest_sanitize_array converting a string into an array, // and causing a "matches more than one of the expected formats" error. 'anyOf' => array( array( 'type' => 'string', ), array( 'type' => 'array', 'items' => array( 'type' => 'string', ), ), ), 'default' => array(), 'arg_options' => array( 'sanitize_callback' => function ( $value ) { return is_array( $value ) ? array_map( array( $this, 'sanitize_src' ), $value ) : $this->sanitize_src( $value ); }, ), ), 'fontStretch' => array( 'description' => __( 'CSS font-stretch value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'ascentOverride' => array( 'description' => __( 'CSS ascent-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'descentOverride' => array( 'description' => __( 'CSS descent-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontVariant' => array( 'description' => __( 'CSS font-variant value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontFeatureSettings' => array( 'description' => __( 'CSS font-feature-settings value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'fontVariationSettings' => array( 'description' => __( 'CSS font-variation-settings value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'lineGapOverride' => array( 'description' => __( 'CSS line-gap-override value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'sizeAdjust' => array( 'description' => __( 'CSS size-adjust value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'unicodeRange' => array( 'description' => __( 'CSS unicode-range value.' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'preview' => array( 'description' => __( 'URL to a preview image of the font face.' ), 'type' => 'string', 'format' => 'uri', 'default' => '', 'arg_options' => array( 'sanitize_callback' => 'sanitize_url', ), ), ), 'required' => array( 'fontFamily', 'src' ), 'additionalProperties' => false, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the item's schema for display / public consumption purposes. * * @since 6.5.0 * * @return array Public item schema data. */ public function get_public_item_schema() { $schema = parent::get_public_item_schema(); // Also remove `arg_options' from child font_family_settings properties, since the parent // controller only handles the top level properties. foreach ( $schema['properties']['font_face_settings']['properties'] as &$property ) { unset( $property['arg_options'] ); } return $schema; } /** * Retrieves the query params for the font face collection. * * @since 6.5.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); // Remove unneeded params. unset( $query_params['after'], $query_params['modified_after'], $query_params['before'], $query_params['modified_before'], $query_params['search'], $query_params['search_columns'], $query_params['slug'], $query_params['status'] ); $query_params['orderby']['default'] = 'id'; $query_params['orderby']['enum'] = array( 'id', 'include' ); /** * Filters collection parameters for the font face controller. * * @since 6.5.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_wp_font_face_collection_params', $query_params ); } /** * Get the params used when creating a new font face. * * @since 6.5.0 * * @return array Font face create arguments. */ public function get_create_params() { $properties = $this->get_item_schema()['properties']; return array( 'theme_json_version' => $properties['theme_json_version'], // When creating, font_face_settings is stringified JSON, to work with multipart/form-data used // when uploading font files. 'font_face_settings' => array( 'description' => __( 'font-face declaration in theme.json format, encoded as a string.' ), 'type' => 'string', 'required' => true, 'validate_callback' => array( $this, 'validate_create_font_face_settings' ), 'sanitize_callback' => array( $this, 'sanitize_font_face_settings' ), ), ); } /** * Get the parent font family, if the ID is valid. * * @since 6.5.0 * * @param int $font_family_id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_parent_font_family_post( $font_family_id ) { $error = new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.', 'default' ), array( 'status' => 404 ) ); if ( (int) $font_family_id <= 0 ) { return $error; } $font_family_post = get_post( (int) $font_family_id ); if ( empty( $font_family_post ) || empty( $font_family_post->ID ) || 'wp_font_family' !== $font_family_post->post_type ) { return $error; } return $font_family_post; } /** * Prepares links for the request. * * @since 6.5.0 * * @param WP_Post $post Post object. * @return array Links for the given post. */ protected function prepare_links( $post ) { // Entity meta. return array( 'self' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent . '/font-faces/' . $post->ID ), ), 'collection' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent . '/font-faces' ), ), 'parent' => array( 'href' => rest_url( $this->namespace . '/font-families/' . $post->post_parent ), ), ); } /** * Prepares a single font face post for creation. * * @since 6.5.0 * * @param WP_REST_Request $request Request object. * @return stdClass Post object. */ protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); // Settings have already been decoded by ::sanitize_font_face_settings(). $settings = $request->get_param( 'font_face_settings' ); // Store this "slug" as the post_title rather than post_name, since it uses the fontFamily setting, // which may contain multibyte characters. $title = WP_Font_Utils::get_font_face_slug( $settings ); $prepared_post->post_type = $this->post_type; $prepared_post->post_parent = $request['font_family_id']; $prepared_post->post_status = 'publish'; $prepared_post->post_title = $title; $prepared_post->post_name = sanitize_title( $title ); $prepared_post->post_content = wp_json_encode( $settings ); return $prepared_post; } /** * Sanitizes a single src value for a font face. * * @since 6.5.0 * * @param string $value Font face src that is a URL or the key for a $_FILES array item. * @return string Sanitized value. */ protected function sanitize_src( $value ) { $value = ltrim( $value ); return false === wp_http_validate_url( $value ) ? (string) $value : sanitize_url( $value ); } /** * Handles the upload of a font file using wp_handle_upload(). * * @since 6.5.0 * * @param array $file Single file item from $_FILES. * @return array|WP_Error Array containing uploaded file attributes on success, or WP_Error object on failure. */ protected function handle_font_file_upload( $file ) { add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); // Filter the upload directory to return the fonts directory. add_filter( 'upload_dir', '_wp_filter_font_directory' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), // Not testing a form submission. 'test_form' => false, // Only allow uploading font files for this request. 'mimes' => WP_Font_Utils::get_allowed_font_mime_types(), ); // Bypasses is_uploaded_file() when running unit tests. if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) { $overrides['action'] = 'wp_handle_mock_upload'; } $uploaded_file = wp_handle_upload( $file, $overrides ); remove_filter( 'upload_dir', '_wp_filter_font_directory' ); remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); return $uploaded_file; } /** * Handles file upload error. * * @since 6.5.0 * * @param array $file File upload data. * @param string $message Error message from wp_handle_upload(). * @return WP_Error WP_Error object. */ public function handle_font_file_upload_error( $file, $message ) { $status = 500; $code = 'rest_font_upload_unknown_error'; if ( __( 'Sorry, you are not allowed to upload this file type.' ) === $message ) { $status = 400; $code = 'rest_font_upload_invalid_file_type'; } return new WP_Error( $code, $message, array( 'status' => $status ) ); } /** * Returns relative path to an uploaded font file. * * The path is relative to the current fonts directory. * * @since 6.5.0 * @access private * * @param string $path Full path to the file. * @return string Relative path on success, unchanged path on failure. */ protected function relative_fonts_path( $path ) { $new_path = $path; $fonts_dir = wp_get_font_dir(); if ( str_starts_with( $new_path, $fonts_dir['basedir'] ) ) { $new_path = str_replace( $fonts_dir['basedir'], '', $new_path ); $new_path = ltrim( $new_path, '/' ); } return $new_path; } /** * Gets the font face's settings from the post. * * @since 6.5.0 * * @param WP_Post $post Font face post object. * @return array Font face settings array. */ protected function get_settings_from_post( $post ) { $settings = json_decode( $post->post_content, true ); $properties = $this->get_item_schema()['properties']['font_face_settings']['properties']; // Provide required, empty settings if needed. if ( null === $settings ) { $settings = array( 'fontFamily' => '', 'src' => array(), ); } // Only return the properties defined in the schema. return array_intersect_key( $settings, $properties ); } } <?php /** * REST API: WP_REST_Menu_Items_Controller class * * @package WordPress * @subpackage REST_API * @since 5.9.0 */ /** * Core class to access nav items via the REST API. * * @since 5.9.0 * * @see WP_REST_Posts_Controller */ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller { /** * Gets the nav menu item, if the ID is valid. * * @since 5.9.0 * * @param int $id Supplied ID. * @return object|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_nav_menu_item( $id ) { $post = $this->get_post( $id ); if ( is_wp_error( $post ) ) { return $post; } return wp_setup_nav_menu_item( $post ); } /** * Checks if a given request has access to read menu items. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $has_permission = parent::get_items_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } /** * Checks if a given request has access to read a menu item if they have access to edit them. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has read access for the item, WP_Error object or false otherwise. */ public function get_item_permissions_check( $request ) { $permission_check = parent::get_item_permissions_check( $request ); if ( true !== $permission_check ) { return $permission_check; } return $this->check_has_read_only_access( $request ); } /** * Checks whether the current user has read permission for the endpoint. * * This allows for any user that can `edit_theme_options` or edit any REST API available post type. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ protected function check_has_read_only_access( $request ) { /** * Filters whether the current user has read access to menu items via the REST API. * * @since 6.8.0 * * @param bool $read_only_access Whether the current user has read access to menu items * via the REST API. * @param WP_REST_Request $request Full details about the request. * @param WP_REST_Controller $this The current instance of the controller. */ $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( current_user_can( 'edit_theme_options' ) ) { return true; } if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menu items.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Creates a single nav menu item. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $prepared_nav_item = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_nav_item ) ) { return $prepared_nav_item; } $prepared_nav_item = (array) $prepared_nav_item; $nav_menu_item_id = wp_update_nav_menu_item( $prepared_nav_item['menu-id'], $prepared_nav_item['menu-item-db-id'], wp_slash( $prepared_nav_item ), false ); if ( is_wp_error( $nav_menu_item_id ) ) { if ( 'db_insert_error' === $nav_menu_item_id->get_error_code() ) { $nav_menu_item_id->add_data( array( 'status' => 500 ) ); } else { $nav_menu_item_id->add_data( array( 'status' => 400 ) ); } return $nav_menu_item_id; } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); if ( is_wp_error( $nav_menu_item ) ) { $nav_menu_item->add_data( array( 'status' => 404 ) ); return $nav_menu_item; } /** * Fires after a single menu item is created or updated via the REST API. * * @since 5.9.0 * * @param object $nav_menu_item Inserted or updated menu item object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a menu item, false when updating. */ do_action( 'rest_insert_nav_menu_item', $nav_menu_item, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $nav_menu_item_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); $fields_update = $this->update_additional_fields_for_object( $nav_menu_item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** * Fires after a single menu item is completely created or updated via the REST API. * * @since 5.9.0 * * @param object $nav_menu_item Inserted or updated menu item object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a menu item, false when updating. */ do_action( 'rest_after_insert_nav_menu_item', $nav_menu_item, $request, true ); $post = get_post( $nav_menu_item_id ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $nav_menu_item_id ) ) ); return $response; } /** * Updates a single nav menu item. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $valid_check = $this->get_nav_menu_item( $request['id'] ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } $post_before = get_post( $request['id'] ); $prepared_nav_item = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_nav_item ) ) { return $prepared_nav_item; } $prepared_nav_item = (array) $prepared_nav_item; $nav_menu_item_id = wp_update_nav_menu_item( $prepared_nav_item['menu-id'], $prepared_nav_item['menu-item-db-id'], wp_slash( $prepared_nav_item ), false ); if ( is_wp_error( $nav_menu_item_id ) ) { if ( 'db_update_error' === $nav_menu_item_id->get_error_code() ) { $nav_menu_item_id->add_data( array( 'status' => 500 ) ); } else { $nav_menu_item_id->add_data( array( 'status' => 400 ) ); } return $nav_menu_item_id; } $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); if ( is_wp_error( $nav_menu_item ) ) { $nav_menu_item->add_data( array( 'status' => 404 ) ); return $nav_menu_item; } /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php */ do_action( 'rest_insert_nav_menu_item', $nav_menu_item, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $nav_menu_item->ID ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $nav_menu_item_id ); $nav_menu_item = $this->get_nav_menu_item( $nav_menu_item_id ); $fields_update = $this->update_additional_fields_for_object( $nav_menu_item, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php */ do_action( 'rest_after_insert_nav_menu_item', $nav_menu_item, $request, false ); wp_after_insert_post( $post, true, $post_before ); $response = $this->prepare_item_for_response( get_post( $nav_menu_item_id ), $request ); return rest_ensure_response( $response ); } /** * Deletes a single nav menu item. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error True on success, or WP_Error object on failure. */ public function delete_item( $request ) { $menu_item = $this->get_nav_menu_item( $request['id'] ); if ( is_wp_error( $menu_item ) ) { return $menu_item; } // We don't support trashing for menu items. if ( ! $request['force'] ) { /* translators: %s: force=true */ return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Menu items do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $previous = $this->prepare_item_for_response( get_post( $request['id'] ), $request ); $result = wp_delete_post( $request['id'], true ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); /** * Fires immediately after a single menu item is deleted via the REST API. * * @since 5.9.0 * * @param object $nav_menu_item Inserted or updated menu item object. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request Request object. */ do_action( 'rest_delete_nav_menu_item', $menu_item, $response, $request ); return $response; } /** * Prepares a single nav menu item for create or update. * * @since 5.9.0 * * @param WP_REST_Request $request Request object. * * @return object|WP_Error */ protected function prepare_item_for_database( $request ) { $menu_item_db_id = $request['id']; $menu_item_obj = $this->get_nav_menu_item( $menu_item_db_id ); // Need to persist the menu item data. See https://core.trac.wordpress.org/ticket/28138 if ( ! is_wp_error( $menu_item_obj ) ) { // Correct the menu position if this was the first item. See https://core.trac.wordpress.org/ticket/28140 $position = ( 0 === $menu_item_obj->menu_order ) ? 1 : $menu_item_obj->menu_order; $prepared_nav_item = array( 'menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => $menu_item_obj->object_id, 'menu-item-object' => $menu_item_obj->object, 'menu-item-parent-id' => $menu_item_obj->menu_item_parent, 'menu-item-position' => $position, 'menu-item-type' => $menu_item_obj->type, 'menu-item-title' => $menu_item_obj->title, 'menu-item-url' => $menu_item_obj->url, 'menu-item-description' => $menu_item_obj->description, 'menu-item-attr-title' => $menu_item_obj->attr_title, 'menu-item-target' => $menu_item_obj->target, 'menu-item-classes' => $menu_item_obj->classes, // Stored in the database as a string. 'menu-item-xfn' => explode( ' ', $menu_item_obj->xfn ), 'menu-item-status' => $menu_item_obj->post_status, 'menu-id' => $this->get_menu_id( $menu_item_db_id ), ); } else { $prepared_nav_item = array( 'menu-id' => 0, 'menu-item-db-id' => 0, 'menu-item-object-id' => 0, 'menu-item-object' => '', 'menu-item-parent-id' => 0, 'menu-item-position' => 1, 'menu-item-type' => 'custom', 'menu-item-title' => '', 'menu-item-url' => '', 'menu-item-description' => '', 'menu-item-attr-title' => '', 'menu-item-target' => '', 'menu-item-classes' => array(), 'menu-item-xfn' => array(), 'menu-item-status' => 'publish', ); } $mapping = array( 'menu-item-db-id' => 'id', 'menu-item-object-id' => 'object_id', 'menu-item-object' => 'object', 'menu-item-parent-id' => 'parent', 'menu-item-position' => 'menu_order', 'menu-item-type' => 'type', 'menu-item-url' => 'url', 'menu-item-description' => 'description', 'menu-item-attr-title' => 'attr_title', 'menu-item-target' => 'target', 'menu-item-classes' => 'classes', 'menu-item-xfn' => 'xfn', 'menu-item-status' => 'status', ); $schema = $this->get_item_schema(); foreach ( $mapping as $original => $api_request ) { if ( isset( $request[ $api_request ] ) ) { $prepared_nav_item[ $original ] = $request[ $api_request ]; } } $taxonomy = get_taxonomy( 'nav_menu' ); $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; // If menus submitted, cast to int. if ( ! empty( $request[ $base ] ) ) { $prepared_nav_item['menu-id'] = absint( $request[ $base ] ); } // Nav menu title. if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $prepared_nav_item['menu-item-title'] = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $prepared_nav_item['menu-item-title'] = $request['title']['raw']; } } $error = new WP_Error(); // Check if object id exists before saving. if ( ! $prepared_nav_item['menu-item-object'] ) { // If taxonomy, check if term exists. if ( 'taxonomy' === $prepared_nav_item['menu-item-type'] ) { $original = get_term( absint( $prepared_nav_item['menu-item-object-id'] ) ); if ( empty( $original ) || is_wp_error( $original ) ) { $error->add( 'rest_term_invalid_id', __( 'Invalid term ID.' ), array( 'status' => 400 ) ); } else { $prepared_nav_item['menu-item-object'] = get_term_field( 'taxonomy', $original ); } // If post, check if post object exists. } elseif ( 'post_type' === $prepared_nav_item['menu-item-type'] ) { $original = get_post( absint( $prepared_nav_item['menu-item-object-id'] ) ); if ( empty( $original ) ) { $error->add( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 400 ) ); } else { $prepared_nav_item['menu-item-object'] = get_post_type( $original ); } } } // If post type archive, check if post type exists. if ( 'post_type_archive' === $prepared_nav_item['menu-item-type'] ) { $post_type = $prepared_nav_item['menu-item-object'] ? $prepared_nav_item['menu-item-object'] : false; $original = get_post_type_object( $post_type ); if ( ! $original ) { $error->add( 'rest_post_invalid_type', __( 'Invalid post type.' ), array( 'status' => 400 ) ); } } // Check if menu item is type custom, then title and url are required. if ( 'custom' === $prepared_nav_item['menu-item-type'] ) { if ( '' === $prepared_nav_item['menu-item-title'] ) { $error->add( 'rest_title_required', __( 'The title is required when using a custom menu item type.' ), array( 'status' => 400 ) ); } if ( empty( $prepared_nav_item['menu-item-url'] ) ) { $error->add( 'rest_url_required', __( 'The url is required when using a custom menu item type.' ), array( 'status' => 400 ) ); } } if ( $error->has_errors() ) { return $error; } // The xfn and classes properties are arrays, but passed to wp_update_nav_menu_item as a string. foreach ( array( 'menu-item-xfn', 'menu-item-classes' ) as $key ) { $prepared_nav_item[ $key ] = implode( ' ', $prepared_nav_item[ $key ] ); } // Only draft / publish are valid post status for menu items. if ( 'publish' !== $prepared_nav_item['menu-item-status'] ) { $prepared_nav_item['menu-item-status'] = 'draft'; } $prepared_nav_item = (object) $prepared_nav_item; /** * Filters a menu item before it is inserted via the REST API. * * @since 5.9.0 * * @param object $prepared_nav_item An object representing a single menu item prepared * for inserting or updating the database. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_pre_insert_nav_menu_item', $prepared_nav_item, $request ); } /** * Prepares a single nav menu item output for response. * * @since 5.9.0 * * @param WP_Post $item Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Base fields for every post. $fields = $this->get_fields_for_response( $request ); $menu_item = $this->get_nav_menu_item( $item->ID ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $menu_item->ID; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $menu_item->title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); /** This filter is documented in wp-includes/post-template.php */ $title = apply_filters( 'the_title', $menu_item->title, $menu_item->ID ); $data['title']['rendered'] = $title; remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $menu_item->post_status; } if ( rest_is_field_included( 'url', $fields ) ) { $data['url'] = $menu_item->url; } if ( rest_is_field_included( 'attr_title', $fields ) ) { // Same as post_excerpt. $data['attr_title'] = $menu_item->attr_title; } if ( rest_is_field_included( 'description', $fields ) ) { // Same as post_content. $data['description'] = $menu_item->description; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $menu_item->type; } if ( rest_is_field_included( 'type_label', $fields ) ) { $data['type_label'] = $menu_item->type_label; } if ( rest_is_field_included( 'object', $fields ) ) { $data['object'] = $menu_item->object; } if ( rest_is_field_included( 'object_id', $fields ) ) { // It is stored as a string, but should be exposed as an integer. $data['object_id'] = absint( $menu_item->object_id ); } if ( rest_is_field_included( 'parent', $fields ) ) { // Same as post_parent, exposed as an integer. $data['parent'] = (int) $menu_item->menu_item_parent; } if ( rest_is_field_included( 'menu_order', $fields ) ) { // Same as post_parent, exposed as an integer. $data['menu_order'] = (int) $menu_item->menu_order; } if ( rest_is_field_included( 'target', $fields ) ) { $data['target'] = $menu_item->target; } if ( rest_is_field_included( 'classes', $fields ) ) { $data['classes'] = (array) $menu_item->classes; } if ( rest_is_field_included( 'xfn', $fields ) ) { $data['xfn'] = array_map( 'sanitize_html_class', explode( ' ', $menu_item->xfn ) ); } if ( rest_is_field_included( 'invalid', $fields ) ) { $data['invalid'] = (bool) $menu_item->_invalid; } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $menu_item->ID, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( rest_is_field_included( $base, $fields ) ) { $terms = get_the_terms( $item, $taxonomy->name ); if ( ! is_array( $terms ) ) { continue; } $term_ids = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); if ( 'nav_menu' === $taxonomy->name ) { $data[ $base ] = $term_ids ? array_shift( $term_ids ) : 0; } else { $data[ $base ] = $term_ids; } } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $item, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } /** * Filters the menu item data for a REST API response. * * @since 5.9.0 * * @param WP_REST_Response $response The response object. * @param object $menu_item Menu item setup by {@see wp_setup_nav_menu_item()}. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_prepare_nav_menu_item', $response, $menu_item, $request ); } /** * Prepares links for the request. * * @since 5.9.0 * * @param WP_Post $post Post object. * @return array Links for the given post. */ protected function prepare_links( $post ) { $links = parent::prepare_links( $post ); $menu_item = $this->get_nav_menu_item( $post->ID ); if ( empty( $menu_item->object_id ) ) { return $links; } $path = ''; $type = ''; $key = $menu_item->type; if ( 'post_type' === $menu_item->type ) { $path = rest_get_route_for_post( $menu_item->object_id ); $type = get_post_type( $menu_item->object_id ); } elseif ( 'taxonomy' === $menu_item->type ) { $path = rest_get_route_for_term( $menu_item->object_id ); $type = get_term_field( 'taxonomy', $menu_item->object_id ); } if ( $path && $type ) { $links['https://api.w.org/menu-item-object'][] = array( 'href' => rest_url( $path ), $key => $type, 'embeddable' => true, ); } return $links; } /** * Retrieves Link Description Objects that should be added to the Schema for the nav menu items collection. * * @since 5.9.0 * * @return array */ protected function get_schema_links() { $links = parent::get_schema_links(); $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" ); $links[] = array( 'rel' => 'https://api.w.org/menu-item-object', 'title' => __( 'Get linked object.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'object' => array( 'type' => 'integer', ), ), ), ); return $links; } /** * Retrieves the nav menu item's schema, conforming to JSON Schema. * * @since 5.9.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', ); $schema['properties']['title'] = array( 'description' => __( 'The title for the object.' ), 'type' => array( 'string', 'object' ), 'context' => array( 'view', 'edit', 'embed' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the object, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML title for the object, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); $schema['properties']['id'] = array( 'description' => __( 'Unique identifier for the object.' ), 'type' => 'integer', 'default' => 0, 'minimum' => 0, 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['type_label'] = array( 'description' => __( 'The singular label used to describe this type of menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ); $schema['properties']['type'] = array( 'description' => __( 'The family of objects originally represented, such as "post_type" or "taxonomy".' ), 'type' => 'string', 'enum' => array( 'taxonomy', 'post_type', 'post_type_archive', 'custom' ), 'context' => array( 'view', 'edit', 'embed' ), 'default' => 'custom', ); $schema['properties']['status'] = array( 'description' => __( 'A named status for the object.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'default' => 'publish', 'context' => array( 'view', 'edit', 'embed' ), ); $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the object.' ), 'type' => 'integer', 'minimum' => 0, 'default' => 0, 'context' => array( 'view', 'edit', 'embed' ), ); $schema['properties']['attr_title'] = array( 'description' => __( 'Text for the title attribute of the link element for this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['classes'] = array( 'description' => __( 'Class names for the link element of this menu item.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => static function ( $value ) { return array_map( 'sanitize_html_class', wp_parse_list( $value ) ); }, ), ); $schema['properties']['description'] = array( 'description' => __( 'The description of this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); $schema['properties']['menu_order'] = array( 'description' => __( 'The DB ID of the nav_menu_item that is this item\'s menu parent, if any, otherwise 0.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'integer', 'minimum' => 1, 'default' => 1, ); $schema['properties']['object'] = array( 'description' => __( 'The type of object originally represented, such as "category", "post", or "attachment".' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_key', ), ); $schema['properties']['object_id'] = array( 'description' => __( 'The database ID of the original object this menu item represents, for example the ID for posts or the term_id for categories.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'integer', 'minimum' => 0, 'default' => 0, ); $schema['properties']['target'] = array( 'description' => __( 'The target attribute of the link element for this menu item.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'enum' => array( '_blank', '', ), ); $schema['properties']['url'] = array( 'description' => __( 'The URL to which this menu item points.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'validate_callback' => static function ( $url ) { if ( '' === $url ) { return true; } if ( sanitize_url( $url ) ) { return true; } return new WP_Error( 'rest_invalid_url', __( 'Invalid URL.' ) ); }, ), ); $schema['properties']['xfn'] = array( 'description' => __( 'The XFN relationship expressed in the link of this menu item.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => static function ( $value ) { return array_map( 'sanitize_html_class', wp_parse_list( $value ) ); }, ), ); $schema['properties']['invalid'] = array( 'description' => __( 'Whether the menu item represents an object that no longer exists.' ), 'context' => array( 'view', 'edit', 'embed' ), 'type' => 'boolean', 'readonly' => true, ); $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $schema['properties'][ $base ] = array( /* translators: %s: taxonomy name */ 'description' => sprintf( __( 'The terms assigned to the object in the %s taxonomy.' ), $taxonomy->name ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ); if ( 'nav_menu' === $taxonomy->name ) { $schema['properties'][ $base ]['type'] = 'integer'; unset( $schema['properties'][ $base ]['items'] ); } } $schema['properties']['meta'] = $this->meta->get_field_schema(); $schema_links = $this->get_schema_links(); if ( $schema_links ) { $schema['links'] = $schema_links; } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for the nav menu items collection. * * @since 5.9.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['menu_order'] = array( 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'asc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.' ), 'type' => 'string', 'default' => 'menu_order', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', 'menu_order', ), ); // Change default to 100 items. $query_params['per_page']['default'] = 100; return $query_params; } /** * Determines the allowed query_vars for a get_items() response and prepares * them for WP_Query. * * @since 5.9.0 * * @param array $prepared_args Optional. Prepared WP_Query arguments. Default empty array. * @param WP_REST_Request $request Optional. Full details about the request. * @return array Items query arguments. */ protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = parent::prepare_items_query( $prepared_args, $request ); // Map to proper WP_Query orderby param. if ( isset( $query_args['orderby'], $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', 'menu_order' => 'menu_order', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } $query_args['update_menu_item_cache'] = true; return $query_args; } /** * Gets the id of the menu that the given menu item belongs to. * * @since 5.9.0 * * @param int $menu_item_id Menu item id. * @return int */ protected function get_menu_id( $menu_item_id ) { $menu_ids = wp_get_post_terms( $menu_item_id, 'nav_menu', array( 'fields' => 'ids' ) ); $menu_id = 0; if ( $menu_ids && ! is_wp_error( $menu_ids ) ) { $menu_id = array_shift( $menu_ids ); } return $menu_id; } } <?php /** * REST API: WP_REST_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core base controller for managing and interacting with REST API items. * * @since 4.7.0 */ #[AllowDynamicProperties] abstract class WP_REST_Controller { /** * The namespace of this controller's route. * * @since 4.7.0 * @var string */ protected $namespace; /** * The base of this controller's route. * * @since 4.7.0 * @var string */ protected $rest_base; /** * Cached results of get_item_schema. * * @since 5.3.0 * @var array */ protected $schema; /** * Registers the routes for the objects of the controller. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { _doing_it_wrong( 'WP_REST_Controller::register_routes', /* translators: %s: register_routes() */ sprintf( __( "Method '%s' must be overridden." ), __METHOD__ ), '4.7.0' ); } /** * Checks if a given request has access to get items. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Retrieves a collection of items. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Checks if a given request has access to get a specific item. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Retrieves one item from the collection. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Checks if a given request has access to create items. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Creates one item from the collection. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Checks if a given request has access to update a specific item. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Updates one item from the collection. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Checks if a given request has access to delete a specific item. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Deletes one item from the collection. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Prepares one item for create or update operation. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return object|WP_Error The prepared item, or WP_Error object on failure. */ protected function prepare_item_for_database( $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Prepares the item for the REST response. * * @since 4.7.0 * * @param mixed $item WordPress representation of the item. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { return new WP_Error( 'invalid-method', /* translators: %s: Method name. */ sprintf( __( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( 'status' => 405 ) ); } /** * Prepares a response for insertion into a collection. * * @since 4.7.0 * * @param WP_REST_Response $response Response object. * @return array|mixed Response data, ready for insertion into collection data. */ public function prepare_response_for_collection( $response ) { if ( ! ( $response instanceof WP_REST_Response ) ) { return $response; } $data = (array) $response->get_data(); $server = rest_get_server(); $links = $server::get_compact_response_links( $response ); if ( ! empty( $links ) ) { $data['_links'] = $links; } return $data; } /** * Filters a response based on the context defined in the schema. * * @since 4.7.0 * * @param array $response_data Response data to filter. * @param string $context Context defined in the schema. * @return array Filtered response. */ public function filter_response_by_context( $response_data, $context ) { $schema = $this->get_item_schema(); return rest_filter_response_by_context( $response_data, $schema, $context ); } /** * Retrieves the item's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { return $this->add_additional_fields_schema( array() ); } /** * Retrieves the item's schema for display / public consumption purposes. * * @since 4.7.0 * * @return array Public item schema data. */ public function get_public_item_schema() { $schema = $this->get_item_schema(); if ( ! empty( $schema['properties'] ) ) { foreach ( $schema['properties'] as &$property ) { unset( $property['arg_options'] ); } } return $schema; } /** * Retrieves the query params for the collections. * * @since 4.7.0 * * @return array Query parameters for the collection. */ public function get_collection_params() { return array( 'context' => $this->get_context_param(), 'page' => array( 'description' => __( 'Current page of the collection.' ), 'type' => 'integer', 'default' => 1, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', 'minimum' => 1, ), 'per_page' => array( 'description' => __( 'Maximum number of items to be returned in result set.' ), 'type' => 'integer', 'default' => 10, 'minimum' => 1, 'maximum' => 100, 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ), 'search' => array( 'description' => __( 'Limit results to those matching a string.' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', ), ); } /** * Retrieves the magical context param. * * Ensures consistent descriptions between endpoints, and populates enum from schema. * * @since 4.7.0 * * @param array $args Optional. Additional arguments for context parameter. Default empty array. * @return array Context parameter details. */ public function get_context_param( $args = array() ) { $param_details = array( 'description' => __( 'Scope under which the request is made; determines fields present in response.' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'validate_callback' => 'rest_validate_request_arg', ); $schema = $this->get_item_schema(); if ( empty( $schema['properties'] ) ) { return array_merge( $param_details, $args ); } $contexts = array(); foreach ( $schema['properties'] as $attributes ) { if ( ! empty( $attributes['context'] ) ) { $contexts = array_merge( $contexts, $attributes['context'] ); } } if ( ! empty( $contexts ) ) { $param_details['enum'] = array_unique( $contexts ); rsort( $param_details['enum'] ); } return array_merge( $param_details, $args ); } /** * Adds the values from additional fields to a data object. * * @since 4.7.0 * * @param array $response_data Prepared response array. * @param WP_REST_Request $request Full details about the request. * @return array Modified data object with additional fields. */ protected function add_additional_fields_to_object( $response_data, $request ) { $additional_fields = $this->get_additional_fields(); $requested_fields = $this->get_fields_for_response( $request ); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['get_callback'] ) { continue; } if ( ! rest_is_field_included( $field_name, $requested_fields ) ) { continue; } $response_data[ $field_name ] = call_user_func( $field_options['get_callback'], $response_data, $field_name, $request, $this->get_object_type() ); } return $response_data; } /** * Updates the values of additional fields added to a data object. * * @since 4.7.0 * * @param object $data_object Data model like WP_Term or WP_Post. * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True on success, WP_Error object if a field cannot be updated. */ protected function update_additional_fields_for_object( $data_object, $request ) { $additional_fields = $this->get_additional_fields(); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['update_callback'] ) { continue; } // Don't run the update callbacks if the data wasn't passed in the request. if ( ! isset( $request[ $field_name ] ) ) { continue; } $result = call_user_func( $field_options['update_callback'], $request[ $field_name ], $data_object, $field_name, $request, $this->get_object_type() ); if ( is_wp_error( $result ) ) { return $result; } } return true; } /** * Adds the schema from additional fields to a schema array. * * The type of object is inferred from the passed schema. * * @since 4.7.0 * * @param array $schema Schema array. * @return array Modified Schema array. */ protected function add_additional_fields_schema( $schema ) { if ( empty( $schema['title'] ) ) { return $schema; } // Can't use $this->get_object_type otherwise we cause an inf loop. $object_type = $schema['title']; $additional_fields = $this->get_additional_fields( $object_type ); foreach ( $additional_fields as $field_name => $field_options ) { if ( ! $field_options['schema'] ) { continue; } $schema['properties'][ $field_name ] = $field_options['schema']; } return $schema; } /** * Retrieves all of the registered additional fields for a given object-type. * * @since 4.7.0 * * @global array $wp_rest_additional_fields Holds registered fields, organized by object type. * * @param string $object_type Optional. The object type. * @return array Registered additional fields (if any), empty array if none or if the object type * could not be inferred. */ protected function get_additional_fields( $object_type = null ) { global $wp_rest_additional_fields; if ( ! $object_type ) { $object_type = $this->get_object_type(); } if ( ! $object_type ) { return array(); } if ( ! $wp_rest_additional_fields || ! isset( $wp_rest_additional_fields[ $object_type ] ) ) { return array(); } return $wp_rest_additional_fields[ $object_type ]; } /** * Retrieves the object type this controller is responsible for managing. * * @since 4.7.0 * * @return string Object type for the controller. */ protected function get_object_type() { $schema = $this->get_item_schema(); if ( ! $schema || ! isset( $schema['title'] ) ) { return null; } return $schema['title']; } /** * Gets an array of fields to be included on the response. * * Included fields are based on item schema and `_fields=` request argument. * * @since 4.9.6 * * @param WP_REST_Request $request Full details about the request. * @return string[] Fields to be included in the response. */ public function get_fields_for_response( $request ) { $schema = $this->get_item_schema(); $properties = isset( $schema['properties'] ) ? $schema['properties'] : array(); $additional_fields = $this->get_additional_fields(); foreach ( $additional_fields as $field_name => $field_options ) { /* * For back-compat, include any field with an empty schema * because it won't be present in $this->get_item_schema(). */ if ( is_null( $field_options['schema'] ) ) { $properties[ $field_name ] = $field_options; } } // Exclude fields that specify a different context than the request context. $context = $request['context']; if ( $context ) { foreach ( $properties as $name => $options ) { if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) { unset( $properties[ $name ] ); } } } $fields = array_keys( $properties ); /* * '_links' and '_embedded' are not typically part of the item schema, * but they can be specified in '_fields', so they are added here as a * convenience for checking with rest_is_field_included(). */ $fields[] = '_links'; if ( $request->has_param( '_embed' ) ) { $fields[] = '_embedded'; } $fields = array_unique( $fields ); if ( ! isset( $request['_fields'] ) ) { return $fields; } $requested_fields = wp_parse_list( $request['_fields'] ); if ( 0 === count( $requested_fields ) ) { return $fields; } // Trim off outside whitespace from the comma delimited list. $requested_fields = array_map( 'trim', $requested_fields ); // Always persist 'id', because it can be needed for add_additional_fields_to_object(). if ( in_array( 'id', $fields, true ) ) { $requested_fields[] = 'id'; } // Return the list of all requested fields which appear in the schema. return array_reduce( $requested_fields, static function ( $response_fields, $field ) use ( $fields ) { if ( in_array( $field, $fields, true ) ) { $response_fields[] = $field; return $response_fields; } // Check for nested fields if $field is not a direct match. $nested_fields = explode( '.', $field ); /* * A nested field is included so long as its top-level property * is present in the schema. */ if ( in_array( $nested_fields[0], $fields, true ) ) { $response_fields[] = $field; } return $response_fields; }, array() ); } /** * Retrieves an array of endpoint arguments from the item schema for the controller. * * @since 4.7.0 * * @param string $method Optional. HTTP method of the request. The arguments for `CREATABLE` requests are * checked for required values and may fall-back to a given default, this is not done * on `EDITABLE` requests. Default WP_REST_Server::CREATABLE. * @return array Endpoint arguments. */ public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { return rest_get_endpoint_args_for_schema( $this->get_item_schema(), $method ); } /** * Sanitizes the slug value. * * @since 4.7.0 * * @internal We can't use sanitize_title() directly, as the second * parameter is the fallback title, which would end up being set to the * request object. * * @see https://github.com/WP-API/WP-API/issues/1585 * * @todo Remove this in favour of https://core.trac.wordpress.org/ticket/34659 * * @param string $slug Slug value passed in request. * @return string Sanitized value for the slug. */ public function sanitize_slug( $slug ) { return sanitize_title( $slug ); } } <?php /** * REST API: WP_REST_Posts_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to access posts via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Posts_Controller extends WP_REST_Controller { /** * Post type. * * @since 4.7.0 * @var string */ protected $post_type; /** * Instance of a post meta fields object. * * @since 4.7.0 * @var WP_REST_Post_Meta_Fields */ protected $meta; /** * Passwordless post access permitted. * * @since 5.7.1 * @var int[] */ protected $password_check_passed = array(); /** * Whether the controller supports batching. * * @since 5.9.0 * @var array */ protected $allow_batch = array( 'v1' => true ); /** * Constructor. * * @since 4.7.0 * * @param string $post_type Post type. */ public function __construct( $post_type ) { $this->post_type = $post_type; $obj = get_post_type_object( $post_type ); $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; $this->namespace = ! empty( $obj->rest_namespace ) ? $obj->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Post_Meta_Fields( $this->post_type ); } /** * Registers the routes for posts. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); $schema = $this->get_item_schema(); $get_item_args = array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); if ( isset( $schema['properties']['excerpt'] ) ) { $get_item_args['excerpt_length'] = array( 'description' => __( 'Override the default excerpt length.' ), 'type' => 'integer', ); } if ( isset( $schema['properties']['password'] ) ) { $get_item_args['password'] = array( 'description' => __( 'The password for the post if it is password protected.' ), 'type' => 'string', ); } register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the post.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $get_item_args, ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Whether to bypass Trash and force deletion.' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to read posts. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Overrides the result of the post password check for REST requested posts. * * Allow users to read the content of password protected posts if they have * previously passed a permission check or if they have the `edit_post` capability * for the post being checked. * * @since 5.7.1 * * @param bool $required Whether the post requires a password check. * @param WP_Post $post The post been password checked. * @return bool Result of password check taking into account REST API considerations. */ public function check_password_required( $required, $post ) { if ( ! $required ) { return $required; } $post = get_post( $post ); if ( ! $post ) { return $required; } if ( ! empty( $this->password_check_passed[ $post->ID ] ) ) { // Password previously checked and approved. return false; } return ! current_user_can( 'edit_post', $post->ID ); } /** * Retrieves a collection of posts. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // Ensure a search string is set in case the orderby is set to 'relevance'. if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) { return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) ); } // Ensure an include parameter is set in case the orderby is set to 'include'. if ( ! empty( $request['orderby'] ) && 'include' === $request['orderby'] && empty( $request['include'] ) ) { return new WP_Error( 'rest_orderby_include_missing_include', __( 'You need to define an include parameter to order by include.' ), array( 'status' => 400 ) ); } // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); $args = array(); /* * This array defines mappings between public API query parameters whose * values are accepted as-passed, and their internal WP_Query parameter * name equivalents (some are the same). Only values which are also * present in $registered will be set. */ $parameter_mappings = array( 'author' => 'author__in', 'author_exclude' => 'author__not_in', 'exclude' => 'post__not_in', 'include' => 'post__in', 'ignore_sticky' => 'ignore_sticky_posts', 'menu_order' => 'menu_order', 'offset' => 'offset', 'order' => 'order', 'orderby' => 'orderby', 'page' => 'paged', 'parent' => 'post_parent__in', 'parent_exclude' => 'post_parent__not_in', 'search' => 's', 'search_columns' => 'search_columns', 'slug' => 'post_name__in', 'status' => 'post_status', ); /* * For each known parameter which is both registered and present in the request, * set the parameter's value on the query $args. */ foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $args[ $wp_param ] = $request[ $api_param ]; } } // Check for & assign any parameters which require special handling or setting. $args['date_query'] = array(); if ( isset( $registered['before'], $request['before'] ) ) { $args['date_query'][] = array( 'before' => $request['before'], 'column' => 'post_date', ); } if ( isset( $registered['modified_before'], $request['modified_before'] ) ) { $args['date_query'][] = array( 'before' => $request['modified_before'], 'column' => 'post_modified', ); } if ( isset( $registered['after'], $request['after'] ) ) { $args['date_query'][] = array( 'after' => $request['after'], 'column' => 'post_date', ); } if ( isset( $registered['modified_after'], $request['modified_after'] ) ) { $args['date_query'][] = array( 'after' => $request['modified_after'], 'column' => 'post_modified', ); } // Ensure our per_page parameter overrides any provided posts_per_page filter. if ( isset( $registered['per_page'] ) ) { $args['posts_per_page'] = $request['per_page']; } if ( isset( $registered['sticky'], $request['sticky'] ) ) { $sticky_posts = get_option( 'sticky_posts', array() ); if ( ! is_array( $sticky_posts ) ) { $sticky_posts = array(); } if ( $request['sticky'] ) { /* * As post__in will be used to only get sticky posts, * we have to support the case where post__in was already * specified. */ $args['post__in'] = $args['post__in'] ? array_intersect( $sticky_posts, $args['post__in'] ) : $sticky_posts; /* * If we intersected, but there are no post IDs in common, * WP_Query won't return "no posts" for post__in = array() * so we have to fake it a bit. */ if ( ! $args['post__in'] ) { $args['post__in'] = array( 0 ); } } elseif ( $sticky_posts ) { /* * As post___not_in will be used to only get posts that * are not sticky, we have to support the case where post__not_in * was already specified. */ $args['post__not_in'] = array_merge( $args['post__not_in'], $sticky_posts ); } } /* * Honor the original REST API `post__in` behavior. Don't prepend sticky posts * when `post__in` has been specified. */ if ( ! empty( $args['post__in'] ) ) { unset( $args['ignore_sticky_posts'] ); } if ( isset( $registered['search_semantics'], $request['search_semantics'] ) && 'exact' === $request['search_semantics'] ) { $args['exact'] = true; } $args = $this->prepare_tax_query( $args, $request ); if ( isset( $registered['format'], $request['format'] ) ) { $formats = $request['format']; /* * The relation needs to be set to `OR` since the request can contain * two separate conditions. The user may be querying for items that have * either the `standard` format or a specific format. */ $formats_query = array( 'relation' => 'OR' ); /* * The default post format, `standard`, is not stored in the database. * If `standard` is part of the request, the query needs to exclude all post items that * have a format assigned. */ if ( in_array( 'standard', $formats, true ) ) { $formats_query[] = array( 'taxonomy' => 'post_format', 'field' => 'slug', 'operator' => 'NOT EXISTS', ); // Remove the `standard` format, since it cannot be queried. unset( $formats[ array_search( 'standard', $formats, true ) ] ); } // Add any remaining formats to the formats query. if ( ! empty( $formats ) ) { // Add the `post-format-` prefix. $terms = array_map( static function ( $format ) { return "post-format-$format"; }, $formats ); $formats_query[] = array( 'taxonomy' => 'post_format', 'field' => 'slug', 'terms' => $terms, 'operator' => 'IN', ); } // Enable filtering by both post formats and other taxonomies by combining them with `AND`. if ( isset( $args['tax_query'] ) ) { $args['tax_query'][] = array( 'relation' => 'AND', $formats_query, ); } else { $args['tax_query'] = $formats_query; } } // Force the post_type argument, since it's not a user input variable. $args['post_type'] = $this->post_type; $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. $args['fields'] = 'ids'; // Disable priming post meta for HEAD requests to improve performance. $args['update_post_term_cache'] = false; $args['update_post_meta_cache'] = false; } /** * Filters WP_Query arguments when querying posts via the REST API. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_post_query` * - `rest_page_query` * - `rest_attachment_query` * * Enables adding extra arguments or setting defaults for a post collection request. * * @since 4.7.0 * @since 5.7.0 Moved after the `tax_query` query arg is generated. * * @link https://developer.wordpress.org/reference/classes/wp_query/ * * @param array $args Array of arguments for WP_Query. * @param WP_REST_Request $request The REST API request. */ $args = apply_filters( "rest_{$this->post_type}_query", $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); $posts_query = new WP_Query(); $query_result = $posts_query->query( $query_args ); // Allow access to all password protected posts if the context is edit. if ( 'edit' === $request['context'] ) { add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } if ( ! $is_head_request ) { $posts = array(); update_post_author_caches( $query_result ); update_post_parent_caches( $query_result ); if ( post_type_supports( $this->post_type, 'thumbnail' ) ) { update_post_thumbnail_cache( $posts_query ); } foreach ( $query_result as $post ) { if ( 'edit' === $request['context'] ) { $permission = $this->check_update_permission( $post ); } else { $permission = $this->check_read_permission( $post ); } if ( ! $permission ) { continue; } $data = $this->prepare_item_for_response( $post, $request ); $posts[] = $this->prepare_response_for_collection( $data ); } } // Reset filter. if ( 'edit' === $request['context'] ) { remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_posts = $posts_query->found_posts; if ( $total_posts < 1 && $page > 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $query_args['paged'] ); $count_query = new WP_Query(); $count_query->query( $query_args ); $total_posts = $count_query->found_posts; } $max_pages = (int) ceil( $total_posts / (int) $posts_query->query_vars['posts_per_page'] ); if ( $page > $max_pages && $total_posts > 0 ) { return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $posts ); $response->header( 'X-WP-Total', (int) $total_posts ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( rest_get_route_for_post_type_items( $this->post_type ) ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Gets the post, if the ID is valid. * * @since 4.7.2 * * @param int $id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_post( $id ) { $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $post = get_post( (int) $id ); if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { return $error; } return $post; } /** * Checks if a given request has access to read a post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has read access for the item, WP_Error object or false otherwise. */ public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( $post && ! empty( $request->get_query_params()['password'] ) ) { // Check post password, and return error if invalid. if ( ! hash_equals( $post->post_password, $request->get_query_params()['password'] ) ) { return new WP_Error( 'rest_post_incorrect_password', __( 'Incorrect post password.' ), array( 'status' => 403 ) ); } } // Allow access to all password protected posts if the context is edit. if ( 'edit' === $request['context'] ) { add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); } if ( $post ) { return $this->check_read_permission( $post ); } return true; } /** * Checks if the user can access password-protected content. * * This method determines whether we need to override the regular password * check in core with a filter. * * @since 4.7.0 * * @param WP_Post $post Post to check against. * @param WP_REST_Request $request Request data to check. * @return bool True if the user can access password-protected content, otherwise false. */ public function can_access_password_content( $post, $request ) { if ( empty( $post->post_password ) ) { // No filter required. return false; } /* * Users always gets access to password protected content in the edit * context if they have the `edit_post` meta capability. */ if ( 'edit' === $request['context'] && current_user_can( 'edit_post', $post->ID ) ) { return true; } // No password, no auth. if ( empty( $request['password'] ) ) { return false; } // Double-check the request password. return hash_equals( $post->post_password, $request['password'] ); } /** * Retrieves a single post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $data = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $data ); if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) { $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) ); } return $response; } /** * Checks if a given request has access to create a post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $post_type = get_post_type_object( $this->post_type ); if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) { return new WP_Error( 'rest_cannot_edit_others', __( 'Sorry, you are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( $post_type->cap->create_posts ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_assign_terms_permission( $request ) ) { return new WP_Error( 'rest_cannot_assign_term', __( 'Sorry, you are not allowed to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Creates a single post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } $prepared_post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $prepared_post ) ) { return $prepared_post; } $prepared_post->post_type = $this->post_type; if ( ! empty( $prepared_post->post_name ) && ! empty( $prepared_post->post_status ) && in_array( $prepared_post->post_status, array( 'draft', 'pending' ), true ) ) { /* * `wp_unique_post_slug()` returns the same slug for 'draft' or 'pending' posts. * * To ensure that a unique slug is generated, pass the post data with the 'publish' status. */ $prepared_post->post_name = wp_unique_post_slug( $prepared_post->post_name, $prepared_post->id, 'publish', $prepared_post->post_type, $prepared_post->post_parent ); } $post_id = wp_insert_post( wp_slash( (array) $prepared_post ), true, false ); if ( is_wp_error( $post_id ) ) { if ( 'db_insert_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $post = get_post( $post_id ); /** * Fires after a single post is created or updated via the REST API. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_insert_post` * - `rest_insert_page` * - `rest_insert_attachment` * * @since 4.7.0 * * @param WP_Post $post Inserted or updated post object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a post, false when updating. */ do_action( "rest_insert_{$this->post_type}", $post, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['sticky'] ) ) { if ( ! empty( $request['sticky'] ) ) { stick_post( $post_id ); } else { unstick_post( $post_id ); } } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $this->handle_featured_media( $request['featured_media'], $post_id ); } if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) { set_post_format( $post, $request['format'] ); } if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) { $this->handle_template( $request['template'], $post_id, true ); } $terms_update = $this->handle_terms( $post_id, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $post_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** * Fires after a single post is completely created or updated via the REST API. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_after_insert_post` * - `rest_after_insert_page` * - `rest_after_insert_attachment` * * @since 5.0.0 * * @param WP_Post $post Inserted or updated post object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a post, false when updating. */ do_action( "rest_after_insert_{$this->post_type}", $post, $request, true ); wp_after_insert_post( $post, false, null ); $response = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( rest_get_route_for_post( $post ) ) ); return $response; } /** * Checks if a given request has access to update a post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $post_type = get_post_type_object( $this->post_type ); if ( $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) { return new WP_Error( 'rest_cannot_edit_others', __( 'Sorry, you are not allowed to update posts as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) && ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_assign_sticky', __( 'Sorry, you are not allowed to make posts sticky.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_assign_terms_permission( $request ) ) { return new WP_Error( 'rest_cannot_assign_term', __( 'Sorry, you are not allowed to assign the provided terms.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates a single post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $valid_check = $this->get_post( $request['id'] ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } $post_before = get_post( $request['id'] ); $post = $this->prepare_item_for_database( $request ); if ( is_wp_error( $post ) ) { return $post; } if ( ! empty( $post->post_status ) ) { $post_status = $post->post_status; } else { $post_status = $post_before->post_status; } /* * `wp_unique_post_slug()` returns the same slug for 'draft' or 'pending' posts. * * To ensure that a unique slug is generated, pass the post data with the 'publish' status. */ if ( ! empty( $post->post_name ) && in_array( $post_status, array( 'draft', 'pending' ), true ) ) { $post_parent = ! empty( $post->post_parent ) ? $post->post_parent : 0; $post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, 'publish', $post->post_type, $post_parent ); } // Convert the post object to an array, otherwise wp_update_post() will expect non-escaped input. $post_id = wp_update_post( wp_slash( (array) $post ), true, false ); if ( is_wp_error( $post_id ) ) { if ( 'db_update_error' === $post_id->get_error_code() ) { $post_id->add_data( array( 'status' => 500 ) ); } else { $post_id->add_data( array( 'status' => 400 ) ); } return $post_id; } $post = get_post( $post_id ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ do_action( "rest_insert_{$this->post_type}", $post, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['format'] ) && ! empty( $request['format'] ) ) { set_post_format( $post, $request['format'] ); } if ( ! empty( $schema['properties']['featured_media'] ) && isset( $request['featured_media'] ) ) { $this->handle_featured_media( $request['featured_media'], $post_id ); } if ( ! empty( $schema['properties']['sticky'] ) && isset( $request['sticky'] ) ) { if ( ! empty( $request['sticky'] ) ) { stick_post( $post_id ); } else { unstick_post( $post_id ); } } if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) { $this->handle_template( $request['template'], $post->ID ); } $terms_update = $this->handle_terms( $post->ID, $request ); if ( is_wp_error( $terms_update ) ) { return $terms_update; } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $post->ID ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); // Filter is fired in WP_REST_Attachments_Controller subclass. if ( 'attachment' === $this->post_type ) { $response = $this->prepare_item_for_response( $post, $request ); return rest_ensure_response( $response ); } /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ do_action( "rest_after_insert_{$this->post_type}", $post, $request, false ); wp_after_insert_post( $post, true, $post_before ); $response = $this->prepare_item_for_response( $post, $request ); return rest_ensure_response( $response ); } /** * Checks if a given request has access to delete a post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( $post && ! $this->check_delete_permission( $post ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes a single post. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } $id = $post->ID; $force = (bool) $request['force']; $supports_trash = ( EMPTY_TRASH_DAYS > 0 ); if ( 'attachment' === $post->post_type ) { $supports_trash = $supports_trash && MEDIA_TRASH; } /** * Filters whether a post is trashable. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_post_trashable` * - `rest_page_trashable` * - `rest_attachment_trashable` * * Pass false to disable Trash support for the post. * * @since 4.7.0 * * @param bool $supports_trash Whether the post type support trashing. * @param WP_Post $post The Post object being considered for trashing support. */ $supports_trash = apply_filters( "rest_{$this->post_type}_trashable", $supports_trash, $post ); if ( ! $this->check_delete_permission( $post ) ) { return new WP_Error( 'rest_user_cannot_delete_post', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $request->set_param( 'context', 'edit' ); // If we're forcing, then delete permanently. if ( $force ) { $previous = $this->prepare_item_for_response( $post, $request ); $result = wp_delete_post( $id, true ); $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( "The post does not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } // Otherwise, only trash if we haven't already. if ( 'trash' === $post->post_status ) { return new WP_Error( 'rest_already_trashed', __( 'The post has already been deleted.' ), array( 'status' => 410 ) ); } /* * (Note that internally this falls through to `wp_delete_post()` * if the Trash is disabled.) */ $result = wp_trash_post( $id ); $post = get_post( $id ); $response = $this->prepare_item_for_response( $post, $request ); } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } /** * Fires immediately after a single post is deleted or trashed via the REST API. * * They dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_delete_post` * - `rest_delete_page` * - `rest_delete_attachment` * * @since 4.7.0 * * @param WP_Post $post The deleted or trashed post. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action( "rest_delete_{$this->post_type}", $post, $response, $request ); return $response; } /** * Determines the allowed query_vars for a get_items() response and prepares * them for WP_Query. * * @since 4.7.0 * * @param array $prepared_args Optional. Prepared WP_Query arguments. Default empty array. * @param WP_REST_Request $request Optional. Full details about the request. * @return array Items query arguments. */ protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = array(); foreach ( $prepared_args as $key => $value ) { /** * Filters the query_vars used in get_items() for the constructed query. * * The dynamic portion of the hook name, `$key`, refers to the query_var key. * * @since 4.7.0 * * @param string $value The query_var value. */ $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } if ( 'post' !== $this->post_type || ! isset( $query_args['ignore_sticky_posts'] ) ) { $query_args['ignore_sticky_posts'] = true; } // Map to proper WP_Query orderby param. if ( isset( $query_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } return $query_args; } /** * Checks the post_date_gmt or modified_gmt and prepare any post or * modified date for single post output. * * @since 4.7.0 * * @param string $date_gmt GMT publication time. * @param string|null $date Optional. Local publication time. Default null. * @return string|null ISO8601/RFC3339 formatted datetime. */ protected function prepare_date_response( $date_gmt, $date = null ) { // Use the date if passed. if ( isset( $date ) ) { return mysql_to_rfc3339( $date ); } // Return null if $date_gmt is empty/zeros. if ( '0000-00-00 00:00:00' === $date_gmt ) { return null; } // Return the formatted datetime. return mysql_to_rfc3339( $date_gmt ); } /** * Prepares a single post for create or update. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return stdClass|WP_Error Post object or WP_Error. */ protected function prepare_item_for_database( $request ) { $prepared_post = new stdClass(); $current_status = ''; // Post ID. if ( isset( $request['id'] ) ) { $existing_post = $this->get_post( $request['id'] ); if ( is_wp_error( $existing_post ) ) { return $existing_post; } $prepared_post->ID = $existing_post->ID; $current_status = $existing_post->post_status; } $schema = $this->get_item_schema(); // Post title. if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $prepared_post->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $prepared_post->post_title = $request['title']['raw']; } } // Post content. if ( ! empty( $schema['properties']['content'] ) && isset( $request['content'] ) ) { if ( is_string( $request['content'] ) ) { $prepared_post->post_content = $request['content']; } elseif ( isset( $request['content']['raw'] ) ) { $prepared_post->post_content = $request['content']['raw']; } } // Post excerpt. if ( ! empty( $schema['properties']['excerpt'] ) && isset( $request['excerpt'] ) ) { if ( is_string( $request['excerpt'] ) ) { $prepared_post->post_excerpt = $request['excerpt']; } elseif ( isset( $request['excerpt']['raw'] ) ) { $prepared_post->post_excerpt = $request['excerpt']['raw']; } } // Post type. if ( empty( $request['id'] ) ) { // Creating new post, use default type for the controller. $prepared_post->post_type = $this->post_type; } else { // Updating a post, use previous type. $prepared_post->post_type = get_post_type( $request['id'] ); } $post_type = get_post_type_object( $prepared_post->post_type ); // Post status. if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) && ( ! $current_status || $current_status !== $request['status'] ) ) { $status = $this->handle_status_param( $request['status'], $post_type ); if ( is_wp_error( $status ) ) { return $status; } $prepared_post->post_status = $status; } // Post date. if ( ! empty( $schema['properties']['date'] ) && ! empty( $request['date'] ) ) { $current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date : false; $date_data = rest_get_date_with_gmt( $request['date'] ); if ( ! empty( $date_data ) && $current_date !== $date_data[0] ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; $prepared_post->edit_date = true; } } elseif ( ! empty( $schema['properties']['date_gmt'] ) && ! empty( $request['date_gmt'] ) ) { $current_date = isset( $prepared_post->ID ) ? get_post( $prepared_post->ID )->post_date_gmt : false; $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) && $current_date !== $date_data[1] ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; $prepared_post->edit_date = true; } } /* * Sending a null date or date_gmt value resets date and date_gmt to their * default values (`0000-00-00 00:00:00`). */ if ( ( ! empty( $schema['properties']['date_gmt'] ) && $request->has_param( 'date_gmt' ) && null === $request['date_gmt'] ) || ( ! empty( $schema['properties']['date'] ) && $request->has_param( 'date' ) && null === $request['date'] ) ) { $prepared_post->post_date_gmt = null; $prepared_post->post_date = null; } // Post slug. if ( ! empty( $schema['properties']['slug'] ) && isset( $request['slug'] ) ) { $prepared_post->post_name = $request['slug']; } // Author. if ( ! empty( $schema['properties']['author'] ) && ! empty( $request['author'] ) ) { $post_author = (int) $request['author']; if ( get_current_user_id() !== $post_author ) { $user_obj = get_userdata( $post_author ); if ( ! $user_obj ) { return new WP_Error( 'rest_invalid_author', __( 'Invalid author ID.' ), array( 'status' => 400 ) ); } } $prepared_post->post_author = $post_author; } // Post password. if ( ! empty( $schema['properties']['password'] ) && isset( $request['password'] ) ) { $prepared_post->post_password = $request['password']; if ( '' !== $request['password'] ) { if ( ! empty( $schema['properties']['sticky'] ) && ! empty( $request['sticky'] ) ) { return new WP_Error( 'rest_invalid_field', __( 'A post can not be sticky and have a password.' ), array( 'status' => 400 ) ); } if ( ! empty( $prepared_post->ID ) && is_sticky( $prepared_post->ID ) ) { return new WP_Error( 'rest_invalid_field', __( 'A sticky post can not be password protected.' ), array( 'status' => 400 ) ); } } } if ( ! empty( $schema['properties']['sticky'] ) && ! empty( $request['sticky'] ) ) { if ( ! empty( $prepared_post->ID ) && post_password_required( $prepared_post->ID ) ) { return new WP_Error( 'rest_invalid_field', __( 'A password protected post can not be set to sticky.' ), array( 'status' => 400 ) ); } } // Parent. if ( ! empty( $schema['properties']['parent'] ) && isset( $request['parent'] ) ) { if ( 0 === (int) $request['parent'] ) { $prepared_post->post_parent = 0; } else { $parent = get_post( (int) $request['parent'] ); if ( empty( $parent ) ) { return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post parent ID.' ), array( 'status' => 400 ) ); } $prepared_post->post_parent = (int) $parent->ID; } } // Menu order. if ( ! empty( $schema['properties']['menu_order'] ) && isset( $request['menu_order'] ) ) { $prepared_post->menu_order = (int) $request['menu_order']; } // Comment status. if ( ! empty( $schema['properties']['comment_status'] ) && ! empty( $request['comment_status'] ) ) { $prepared_post->comment_status = $request['comment_status']; } // Ping status. if ( ! empty( $schema['properties']['ping_status'] ) && ! empty( $request['ping_status'] ) ) { $prepared_post->ping_status = $request['ping_status']; } if ( ! empty( $schema['properties']['template'] ) ) { // Force template to null so that it can be handled exclusively by the REST controller. $prepared_post->page_template = null; } /** * Filters a post before it is inserted via the REST API. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_pre_insert_post` * - `rest_pre_insert_page` * - `rest_pre_insert_attachment` * * @since 4.7.0 * * @param stdClass $prepared_post An object representing a single post prepared * for inserting or updating the database. * @param WP_REST_Request $request Request object. */ return apply_filters( "rest_pre_insert_{$this->post_type}", $prepared_post, $request ); } /** * Checks whether the status is valid for the given post. * * Allows for sending an update request with the current status, even if that status would not be acceptable. * * @since 5.6.0 * * @param string $status The provided status. * @param WP_REST_Request $request The request object. * @param string $param The parameter name. * @return true|WP_Error True if the status is valid, or WP_Error if not. */ public function check_status( $status, $request, $param ) { if ( $request['id'] ) { $post = $this->get_post( $request['id'] ); if ( ! is_wp_error( $post ) && $post->post_status === $status ) { return true; } } $args = $request->get_attributes()['args'][ $param ]; return rest_validate_value_from_schema( $status, $args, $param ); } /** * Determines validity and normalizes the given status parameter. * * @since 4.7.0 * * @param string $post_status Post status. * @param WP_Post_Type $post_type Post type. * @return string|WP_Error Post status or WP_Error if lacking the proper permission. */ protected function handle_status_param( $post_status, $post_type ) { switch ( $post_status ) { case 'draft': case 'pending': break; case 'private': if ( ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to create private posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } break; case 'publish': case 'future': if ( ! current_user_can( $post_type->cap->publish_posts ) ) { return new WP_Error( 'rest_cannot_publish', __( 'Sorry, you are not allowed to publish posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } break; default: if ( ! get_post_status_object( $post_status ) ) { $post_status = 'draft'; } break; } return $post_status; } /** * Determines the featured media based on a request param. * * @since 4.7.0 * * @param int $featured_media Featured Media ID. * @param int $post_id Post ID. * @return bool|WP_Error Whether the post thumbnail was successfully deleted, otherwise WP_Error. */ protected function handle_featured_media( $featured_media, $post_id ) { $featured_media = (int) $featured_media; if ( $featured_media ) { $result = set_post_thumbnail( $post_id, $featured_media ); if ( $result ) { return true; } else { return new WP_Error( 'rest_invalid_featured_media', __( 'Invalid featured media ID.' ), array( 'status' => 400 ) ); } } else { return delete_post_thumbnail( $post_id ); } } /** * Checks whether the template is valid for the given post. * * @since 4.9.0 * * @param string $template Page template filename. * @param WP_REST_Request $request Request. * @return true|WP_Error True if template is still valid or if the same as existing value, or a WP_Error if template not supported. */ public function check_template( $template, $request ) { if ( ! $template ) { return true; } if ( $request['id'] ) { $post = get_post( $request['id'] ); $current_template = get_page_template_slug( $request['id'] ); } else { $post = null; $current_template = ''; } // Always allow for updating a post to the same template, even if that template is no longer supported. if ( $template === $current_template ) { return true; } // If this is a create request, get_post() will return null and wp theme will fallback to the passed post type. $allowed_templates = wp_get_theme()->get_page_templates( $post, $this->post_type ); if ( isset( $allowed_templates[ $template ] ) ) { return true; } return new WP_Error( 'rest_invalid_param', /* translators: 1: Parameter, 2: List of valid values. */ sprintf( __( '%1$s is not one of %2$s.' ), 'template', implode( ', ', array_keys( $allowed_templates ) ) ) ); } /** * Sets the template for a post. * * @since 4.7.0 * @since 4.9.0 Added the `$validate` parameter. * * @param string $template Page template filename. * @param int $post_id Post ID. * @param bool $validate Whether to validate that the template selected is valid. */ public function handle_template( $template, $post_id, $validate = false ) { if ( $validate && ! array_key_exists( $template, wp_get_theme()->get_page_templates( get_post( $post_id ) ) ) ) { $template = ''; } update_post_meta( $post_id, '_wp_page_template', $template ); } /** * Updates the post's terms from a REST request. * * @since 4.7.0 * * @param int $post_id The post ID to update the terms form. * @param WP_REST_Request $request The request object with post and terms data. * @return null|WP_Error WP_Error on an error assigning any of the terms, otherwise null. */ protected function handle_terms( $post_id, $request ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( ! isset( $request[ $base ] ) ) { continue; } $result = wp_set_object_terms( $post_id, $request[ $base ], $taxonomy->name ); if ( is_wp_error( $result ) ) { return $result; } } return null; } /** * Checks whether current user can assign all terms sent with the current request. * * @since 4.7.0 * * @param WP_REST_Request $request The request object with post and terms data. * @return bool Whether the current user can assign the provided terms. */ protected function check_assign_terms_permission( $request ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( ! isset( $request[ $base ] ) ) { continue; } foreach ( (array) $request[ $base ] as $term_id ) { // Invalid terms will be rejected later. if ( ! get_term( $term_id, $taxonomy->name ) ) { continue; } if ( ! current_user_can( 'assign_term', (int) $term_id ) ) { return false; } } } return true; } /** * Checks if a given post type can be viewed or managed. * * @since 4.7.0 * * @param WP_Post_Type|string $post_type Post type name or object. * @return bool Whether the post type is allowed in REST. */ protected function check_is_post_type_allowed( $post_type ) { if ( ! is_object( $post_type ) ) { $post_type = get_post_type_object( $post_type ); } if ( ! empty( $post_type ) && ! empty( $post_type->show_in_rest ) ) { return true; } return false; } /** * Checks if a post can be read. * * Correctly handles posts with the inherit status. * * @since 4.7.0 * * @param WP_Post $post Post object. * @return bool Whether the post can be read. */ public function check_read_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } // Is the post readable? if ( 'publish' === $post->post_status || current_user_can( 'read_post', $post->ID ) ) { return true; } $post_status_obj = get_post_status_object( $post->post_status ); if ( $post_status_obj && $post_status_obj->public ) { return true; } // Can we read the parent if we're inheriting? if ( 'inherit' === $post->post_status && $post->post_parent > 0 ) { $parent = get_post( $post->post_parent ); if ( $parent ) { return $this->check_read_permission( $parent ); } } /* * If there isn't a parent, but the status is set to inherit, assume * it's published (as per get_post_status()). */ if ( 'inherit' === $post->post_status ) { return true; } return false; } /** * Checks if a post can be edited. * * @since 4.7.0 * * @param WP_Post $post Post object. * @return bool Whether the post can be edited. */ protected function check_update_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( 'edit_post', $post->ID ); } /** * Checks if a post can be created. * * @since 4.7.0 * * @param WP_Post $post Post object. * @return bool Whether the post can be created. */ protected function check_create_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( $post_type->cap->create_posts ); } /** * Checks if a post can be deleted. * * @since 4.7.0 * * @param WP_Post $post Post object. * @return bool Whether the post can be deleted. */ protected function check_delete_permission( $post ) { $post_type = get_post_type_object( $post->post_type ); if ( ! $this->check_is_post_type_allowed( $post_type ) ) { return false; } return current_user_can( 'delete_post', $post->ID ); } /** * Prepares a single post output for response. * * @since 4.7.0 * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support. * * @global WP_Post $post Global post object. * * @param WP_Post $item Post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $post = $item; $GLOBALS['post'] = $post; setup_postdata( $post ); // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ return apply_filters( "rest_prepare_{$this->post_type}", new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); // Base fields for every post. $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $post->ID; } if ( rest_is_field_included( 'date', $fields ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( rest_is_field_included( 'date_gmt', $fields ) ) { /* * For drafts, `post_date_gmt` may not be set, indicating that the date * of the draft should be updated each time it is saved (see #38883). * In this case, shim the value based on the `post_date` field * with the site's timezone offset applied. */ if ( '0000-00-00 00:00:00' === $post->post_date_gmt ) { $post_date_gmt = get_gmt_from_date( $post->post_date ); } else { $post_date_gmt = $post->post_date_gmt; } $data['date_gmt'] = $this->prepare_date_response( $post_date_gmt ); } if ( rest_is_field_included( 'guid', $fields ) ) { $data['guid'] = array( /** This filter is documented in wp-includes/post-template.php */ 'rendered' => apply_filters( 'get_the_guid', $post->guid, $post->ID ), 'raw' => $post->guid, ); } if ( rest_is_field_included( 'modified', $fields ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( rest_is_field_included( 'modified_gmt', $fields ) ) { /* * For drafts, `post_modified_gmt` may not be set (see `post_date_gmt` comments * above). In this case, shim the value based on the `post_modified` field * with the site's timezone offset applied. */ if ( '0000-00-00 00:00:00' === $post->post_modified_gmt ) { $post_modified_gmt = gmdate( 'Y-m-d H:i:s', strtotime( $post->post_modified ) - (int) ( (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ); } else { $post_modified_gmt = $post->post_modified_gmt; } $data['modified_gmt'] = $this->prepare_date_response( $post_modified_gmt ); } if ( rest_is_field_included( 'password', $fields ) ) { $data['password'] = $post->post_password; } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $post->post_name; } if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = $post->post_status; } if ( rest_is_field_included( 'type', $fields ) ) { $data['type'] = $post->post_type; } if ( rest_is_field_included( 'link', $fields ) ) { $data['link'] = get_permalink( $post->ID ); } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $post->post_title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data['title']['rendered'] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } $has_password_filter = false; if ( $this->can_access_password_content( $post, $request ) ) { $this->password_check_passed[ $post->ID ] = true; // Allow access to the post, permissions already checked before. add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 ); $has_password_filter = true; } if ( rest_is_field_included( 'content', $fields ) ) { $data['content'] = array(); } if ( rest_is_field_included( 'content.raw', $fields ) ) { $data['content']['raw'] = $post->post_content; } if ( rest_is_field_included( 'content.rendered', $fields ) ) { /** This filter is documented in wp-includes/post-template.php */ $data['content']['rendered'] = post_password_required( $post ) ? '' : apply_filters( 'the_content', $post->post_content ); } if ( rest_is_field_included( 'content.protected', $fields ) ) { $data['content']['protected'] = (bool) $post->post_password; } if ( rest_is_field_included( 'content.block_version', $fields ) ) { $data['content']['block_version'] = block_version( $post->post_content ); } if ( rest_is_field_included( 'excerpt', $fields ) ) { if ( isset( $request['excerpt_length'] ) ) { $excerpt_length = $request['excerpt_length']; $override_excerpt_length = static function () use ( $excerpt_length ) { return $excerpt_length; }; add_filter( 'excerpt_length', $override_excerpt_length, 20 ); } /** This filter is documented in wp-includes/post-template.php */ $excerpt = apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); /** This filter is documented in wp-includes/post-template.php */ $excerpt = apply_filters( 'the_excerpt', $excerpt ); $data['excerpt'] = array( 'raw' => $post->post_excerpt, 'rendered' => post_password_required( $post ) ? '' : $excerpt, 'protected' => (bool) $post->post_password, ); if ( isset( $override_excerpt_length ) ) { remove_filter( 'excerpt_length', $override_excerpt_length, 20 ); } } if ( $has_password_filter ) { // Reset filter. remove_filter( 'post_password_required', array( $this, 'check_password_required' ) ); } if ( rest_is_field_included( 'author', $fields ) ) { $data['author'] = (int) $post->post_author; } if ( rest_is_field_included( 'featured_media', $fields ) ) { $data['featured_media'] = (int) get_post_thumbnail_id( $post->ID ); } if ( rest_is_field_included( 'parent', $fields ) ) { $data['parent'] = (int) $post->post_parent; } if ( rest_is_field_included( 'menu_order', $fields ) ) { $data['menu_order'] = (int) $post->menu_order; } if ( rest_is_field_included( 'comment_status', $fields ) ) { $data['comment_status'] = $post->comment_status; } if ( rest_is_field_included( 'ping_status', $fields ) ) { $data['ping_status'] = $post->ping_status; } if ( rest_is_field_included( 'sticky', $fields ) ) { $data['sticky'] = is_sticky( $post->ID ); } if ( rest_is_field_included( 'template', $fields ) ) { $template = get_page_template_slug( $post->ID ); if ( $template ) { $data['template'] = $template; } else { $data['template'] = ''; } } if ( rest_is_field_included( 'format', $fields ) ) { $data['format'] = get_post_format( $post->ID ); // Fill in blank post format. if ( empty( $data['format'] ) ) { $data['format'] = 'standard'; } } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $post->ID, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( rest_is_field_included( $base, $fields ) ) { $terms = get_the_terms( $post, $taxonomy->name ); $data[ $base ] = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); } } $post_type_obj = get_post_type_object( $post->post_type ); if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { $permalink_template_requested = rest_is_field_included( 'permalink_template', $fields ); $generated_slug_requested = rest_is_field_included( 'generated_slug', $fields ); if ( $permalink_template_requested || $generated_slug_requested ) { if ( ! function_exists( 'get_sample_permalink' ) ) { require_once ABSPATH . 'wp-admin/includes/post.php'; } $sample_permalink = get_sample_permalink( $post->ID, $post->post_title, '' ); if ( $permalink_template_requested ) { $data['permalink_template'] = $sample_permalink[0]; } if ( $generated_slug_requested ) { $data['generated_slug'] = $sample_permalink[1]; } } if ( rest_is_field_included( 'class_list', $fields ) ) { $data['class_list'] = get_post_class( array(), $post->ID ); } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $post ); $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $post, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } /** * Filters the post data for a REST API response. * * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. * * Possible hook names include: * * - `rest_prepare_post` * - `rest_prepare_page` * - `rest_prepare_attachment` * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. */ return apply_filters( "rest_prepare_{$this->post_type}", $response, $post, $request ); } /** * Overwrites the default protected and private title format. * * By default, WordPress will show password protected or private posts with a title of * "Protected: %s" or "Private: %s", as the REST API communicates the status of a post * in a machine-readable format, we remove the prefix. * * @since 4.7.0 * * @return string Title format. */ public function protected_title_format() { return '%s'; } /** * Prepares links for the request. * * @since 4.7.0 * * @param WP_Post $post Post object. * @return array Links for the given post. */ protected function prepare_links( $post ) { // Entity meta. $links = array( 'self' => array( 'href' => rest_url( rest_get_route_for_post( $post->ID ) ), ), 'collection' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $this->post_type ) ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'author' ) ) && ! empty( $post->post_author ) ) { $links['author'] = array( 'href' => rest_url( 'wp/v2/users/' . $post->post_author ), 'embeddable' => true, ); } if ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'comments' ) ) { $replies_url = rest_url( 'wp/v2/comments' ); $replies_url = add_query_arg( 'post', $post->ID, $replies_url ); $links['replies'] = array( 'href' => $replies_url, 'embeddable' => true, ); } if ( in_array( $post->post_type, array( 'post', 'page' ), true ) || post_type_supports( $post->post_type, 'revisions' ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $post->ID ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%s/%d/revisions', $this->namespace, $this->rest_base, $post->ID ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); if ( $revisions_count > 0 ) { $links['predecessor-version'] = array( 'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ), 'id' => $revisions['latest_id'], ); } } $post_type_obj = get_post_type_object( $post->post_type ); if ( $post_type_obj->hierarchical && ! empty( $post->post_parent ) ) { $links['up'] = array( 'href' => rest_url( rest_get_route_for_post( $post->post_parent ) ), 'embeddable' => true, ); } // If we have a featured media, add that. $featured_media = get_post_thumbnail_id( $post->ID ); if ( $featured_media ) { $image_url = rest_url( rest_get_route_for_post( $featured_media ) ); $links['https://api.w.org/featuredmedia'] = array( 'href' => $image_url, 'embeddable' => true, ); } if ( ! in_array( $post->post_type, array( 'attachment', 'nav_menu_item', 'revision' ), true ) ) { $attachments_url = rest_url( rest_get_route_for_post_type_items( 'attachment' ) ); $attachments_url = add_query_arg( 'parent', $post->ID, $attachments_url ); $links['https://api.w.org/attachment'] = array( 'href' => $attachments_url, ); } $taxonomies = get_object_taxonomies( $post->post_type ); if ( ! empty( $taxonomies ) ) { $links['https://api.w.org/term'] = array(); foreach ( $taxonomies as $tax ) { $taxonomy_route = rest_get_route_for_taxonomy_items( $tax ); // Skip taxonomies that are not public. if ( empty( $taxonomy_route ) ) { continue; } $terms_url = add_query_arg( 'post', $post->ID, rest_url( $taxonomy_route ) ); $links['https://api.w.org/term'][] = array( 'href' => $terms_url, 'taxonomy' => $tax, 'embeddable' => true, ); } } return $links; } /** * Gets the link relations available for the post and current user. * * @since 4.9.8 * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * @return array List of link relations. */ protected function get_available_actions( $post, $request ) { if ( 'edit' !== $request['context'] ) { return array(); } $rels = array(); $post_type = get_post_type_object( $post->post_type ); if ( 'attachment' !== $this->post_type && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'unfiltered_html' ) ) { $rels[] = 'https://api.w.org/action-unfiltered-html'; } if ( 'post' === $post_type->name ) { if ( current_user_can( $post_type->cap->edit_others_posts ) && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-sticky'; } } if ( post_type_supports( $post_type->name, 'author' ) ) { if ( current_user_can( $post_type->cap->edit_others_posts ) ) { $rels[] = 'https://api.w.org/action-assign-author'; } } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $tax ) { $tax_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name; $create_cap = is_taxonomy_hierarchical( $tax->name ) ? $tax->cap->edit_terms : $tax->cap->assign_terms; if ( current_user_can( $create_cap ) ) { $rels[] = 'https://api.w.org/action-create-' . $tax_base; } if ( current_user_can( $tax->cap->assign_terms ) ) { $rels[] = 'https://api.w.org/action-assign-' . $tax_base; } } return $rels; } /** * Retrieves the post's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', // Base properties for every Post. 'properties' => array( 'date' => array( 'description' => __( "The date the post was published, in the site's timezone." ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the post was published, as GMT.' ), 'type' => array( 'string', 'null' ), 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'guid' => array( 'description' => __( 'The globally unique identifier for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'GUID for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ), 'rendered' => array( 'description' => __( 'GUID for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ), 'id' => array( 'description' => __( 'Unique identifier for the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'link' => array( 'description' => __( 'URL to the post.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'modified' => array( 'description' => __( "The date the post was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'modified_gmt' => array( 'description' => __( 'The date the post was last modified, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the post unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'status' => array( 'description' => __( 'A named status for the post.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => array( $this, 'check_status' ), ), ), 'type' => array( 'description' => __( 'Type of post.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'password' => array( 'description' => __( 'A password to protect access to the content and excerpt.' ), 'type' => 'string', 'context' => array( 'edit' ), ), ), ); $post_type_obj = get_post_type_object( $this->post_type ); if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { $schema['properties']['permalink_template'] = array( 'description' => __( 'Permalink template for the post.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ); $schema['properties']['generated_slug'] = array( 'description' => __( 'Slug automatically generated from the post title.' ), 'type' => 'string', 'context' => array( 'edit' ), 'readonly' => true, ); $schema['properties']['class_list'] = array( 'description' => __( 'An array of the class names for the post container element.' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), 'readonly' => true, 'items' => array( 'type' => 'string', ), ); } if ( $post_type_obj->hierarchical ) { $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); } $post_type_attributes = array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'page-attributes', 'post-formats', 'custom-fields', ); $fixed_schemas = array( 'post' => array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'post-formats', 'custom-fields', ), 'page' => array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'comments', 'revisions', 'page-attributes', 'custom-fields', ), 'attachment' => array( 'title', 'author', 'comments', 'revisions', 'custom-fields', 'thumbnail', ), ); foreach ( $post_type_attributes as $attribute ) { if ( isset( $fixed_schemas[ $this->post_type ] ) && ! in_array( $attribute, $fixed_schemas[ $this->post_type ], true ) ) { continue; } elseif ( ! isset( $fixed_schemas[ $this->post_type ] ) && ! post_type_supports( $this->post_type, $attribute ) ) { continue; } switch ( $attribute ) { case 'title': $schema['properties']['title'] = array( 'description' => __( 'The title for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML title for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'editor': $schema['properties']['content'] = array( 'description' => __( 'The content for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Content for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML content for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'block_version' => array( 'description' => __( 'Version of the content block format used by the post.' ), 'type' => 'integer', 'context' => array( 'edit' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether the content is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'author': $schema['properties']['author'] = array( 'description' => __( 'The ID for the author of the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); break; case 'excerpt': $schema['properties']['excerpt'] = array( 'description' => __( 'The excerpt for the post.' ), 'type' => 'object', 'context' => array( 'view', 'edit', 'embed' ), 'arg_options' => array( 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). ), 'properties' => array( 'raw' => array( 'description' => __( 'Excerpt for the post, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), 'rendered' => array( 'description' => __( 'HTML excerpt for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether the excerpt is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); break; case 'thumbnail': $schema['properties']['featured_media'] = array( 'description' => __( 'The ID of the featured media for the post.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); break; case 'comments': $schema['properties']['comment_status'] = array( 'description' => __( 'Whether or not comments are open on the post.' ), 'type' => 'string', 'enum' => array( 'open', 'closed' ), 'context' => array( 'view', 'edit' ), ); $schema['properties']['ping_status'] = array( 'description' => __( 'Whether or not the post can be pinged.' ), 'type' => 'string', 'enum' => array( 'open', 'closed' ), 'context' => array( 'view', 'edit' ), ); break; case 'page-attributes': $schema['properties']['menu_order'] = array( 'description' => __( 'The order of the post in relation to other posts.' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ); break; case 'post-formats': // Get the native post formats and remove the array keys. $formats = array_values( get_post_format_slugs() ); $schema['properties']['format'] = array( 'description' => __( 'The format for the post.' ), 'type' => 'string', 'enum' => $formats, 'context' => array( 'view', 'edit' ), ); break; case 'custom-fields': $schema['properties']['meta'] = $this->meta->get_field_schema(); break; } } if ( 'post' === $this->post_type ) { $schema['properties']['sticky'] = array( 'description' => __( 'Whether or not the post should be treated as sticky.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ); } $schema['properties']['template'] = array( 'description' => __( 'The theme file to use to display the post.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => array( $this, 'check_template' ), ), ); $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( array_key_exists( $base, $schema['properties'] ) ) { $taxonomy_field_name_with_conflict = ! empty( $taxonomy->rest_base ) ? 'rest_base' : 'name'; _doing_it_wrong( 'register_taxonomy', sprintf( /* translators: 1: The taxonomy name, 2: The property name, either 'rest_base' or 'name', 3: The conflicting value. */ __( 'The "%1$s" taxonomy "%2$s" property (%3$s) conflicts with an existing property on the REST API Posts Controller. Specify a custom "rest_base" when registering the taxonomy to avoid this error.' ), $taxonomy->name, $taxonomy_field_name_with_conflict, $base ), '5.4.0' ); } $schema['properties'][ $base ] = array( /* translators: %s: Taxonomy name. */ 'description' => sprintf( __( 'The terms assigned to the post in the %s taxonomy.' ), $taxonomy->name ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ); } $schema_links = $this->get_schema_links(); if ( $schema_links ) { $schema['links'] = $schema_links; } // Take a snapshot of which fields are in the schema pre-filtering. $schema_fields = array_keys( $schema['properties'] ); /** * Filters the post's schema. * * The dynamic portion of the filter, `$this->post_type`, refers to the * post type slug for the controller. * * Possible hook names include: * * - `rest_post_item_schema` * - `rest_page_item_schema` * - `rest_attachment_item_schema` * * @since 5.4.0 * * @param array $schema Item schema data. */ $schema = apply_filters( "rest_{$this->post_type}_item_schema", $schema ); // Emit a _doing_it_wrong warning if user tries to add new properties using this filter. $new_fields = array_diff( array_keys( $schema['properties'] ), $schema_fields ); if ( count( $new_fields ) > 0 ) { _doing_it_wrong( __METHOD__, sprintf( /* translators: %s: register_rest_field */ __( 'Please use %s to add new schema properties.' ), 'register_rest_field' ), '5.4.0' ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves Link Description Objects that should be added to the Schema for the posts collection. * * @since 4.9.8 * * @return array */ protected function get_schema_links() { $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" ); $links = array(); if ( 'attachment' !== $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-publish', 'title' => __( 'The current user can publish this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'status' => array( 'type' => 'string', 'enum' => array( 'publish', 'future' ), ), ), ), ); } $links[] = array( 'rel' => 'https://api.w.org/action-unfiltered-html', 'title' => __( 'The current user can post unfiltered HTML markup and JavaScript.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'content' => array( 'raw' => array( 'type' => 'string', ), ), ), ), ); if ( 'post' === $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-sticky', 'title' => __( 'The current user can sticky this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'sticky' => array( 'type' => 'boolean', ), ), ), ); } if ( post_type_supports( $this->post_type, 'author' ) ) { $links[] = array( 'rel' => 'https://api.w.org/action-assign-author', 'title' => __( 'The current user can change the author on this post.' ), 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( 'author' => array( 'type' => 'integer', ), ), ), ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $tax ) { $tax_base = ! empty( $tax->rest_base ) ? $tax->rest_base : $tax->name; /* translators: %s: Taxonomy name. */ $assign_title = sprintf( __( 'The current user can assign terms in the %s taxonomy.' ), $tax->name ); /* translators: %s: Taxonomy name. */ $create_title = sprintf( __( 'The current user can create terms in the %s taxonomy.' ), $tax->name ); $links[] = array( 'rel' => 'https://api.w.org/action-assign-' . $tax_base, 'title' => $assign_title, 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( $tax_base => array( 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), ), ), ); $links[] = array( 'rel' => 'https://api.w.org/action-create-' . $tax_base, 'title' => $create_title, 'href' => $href, 'targetSchema' => array( 'type' => 'object', 'properties' => array( $tax_base => array( 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), ), ), ); } return $links; } /** * Retrieves the query params for the posts collection. * * @since 4.7.0 * @since 5.4.0 The `tax_relation` query parameter was added. * @since 5.7.0 The `modified_after` and `modified_before` query parameters were added. * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['after'] = array( 'description' => __( 'Limit response to posts published after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['modified_after'] = array( 'description' => __( 'Limit response to posts modified after a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); if ( post_type_supports( $this->post_type, 'author' ) ) { $query_params['author'] = array( 'description' => __( 'Limit result set to posts assigned to specific authors.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['author_exclude'] = array( 'description' => __( 'Ensure result set excludes posts assigned to specific authors.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); } $query_params['before'] = array( 'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['modified_before'] = array( 'description' => __( 'Limit response to posts modified before a given ISO8601 compliant date.' ), 'type' => 'string', 'format' => 'date-time', ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) { $query_params['menu_order'] = array( 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), 'type' => 'integer', ); } $query_params['search_semantics'] = array( 'description' => __( 'How to interpret the search input.' ), 'type' => 'string', 'enum' => array( 'exact' ), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by post attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title', ), ); if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) { $query_params['orderby']['enum'][] = 'menu_order'; } $post_type = get_post_type_object( $this->post_type ); if ( $post_type->hierarchical || 'attachment' === $this->post_type ) { $query_params['parent'] = array( 'description' => __( 'Limit result set to items with particular parent IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['parent_exclude'] = array( 'description' => __( 'Limit result set to all items except those of a particular parent ID.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); } $query_params['search_columns'] = array( 'default' => array(), 'description' => __( 'Array of column names to be searched.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'post_title', 'post_content', 'post_excerpt' ), 'type' => 'string', ), ); $query_params['slug'] = array( 'description' => __( 'Limit result set to posts with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['status'] = array( 'default' => 'publish', 'description' => __( 'Limit result set to posts assigned one or more statuses.' ), 'type' => 'array', 'items' => array( 'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ), 'type' => 'string', ), 'sanitize_callback' => array( $this, 'sanitize_post_statuses' ), ); $query_params = $this->prepare_taxonomy_limit_schema( $query_params ); if ( 'post' === $this->post_type ) { $query_params['sticky'] = array( 'description' => __( 'Limit result set to items that are sticky.' ), 'type' => 'boolean', ); $query_params['ignore_sticky'] = array( 'description' => __( 'Whether to ignore sticky posts or not.' ), 'type' => 'boolean', 'default' => true, ); } if ( post_type_supports( $this->post_type, 'post-formats' ) ) { $query_params['format'] = array( 'description' => __( 'Limit result set to items assigned one or more given formats.' ), 'type' => 'array', 'uniqueItems' => true, 'items' => array( 'enum' => array_values( get_post_format_slugs() ), 'type' => 'string', ), ); } /** * Filters collection parameters for the posts controller. * * The dynamic part of the filter `$this->post_type` refers to the post * type slug for the controller. * * This filter registers the collection parameter, but does not map the * collection parameter to an internal WP_Query parameter. Use the * `rest_{$this->post_type}_query` filter to set WP_Query parameters. * * @since 4.7.0 * * @param array $query_params JSON Schema-formatted collection parameters. * @param WP_Post_Type $post_type Post type object. */ return apply_filters( "rest_{$this->post_type}_collection_params", $query_params, $post_type ); } /** * Sanitizes and validates the list of post statuses, including whether the * user can query private statuses. * * @since 4.7.0 * * @param string|array $statuses One or more post statuses. * @param WP_REST_Request $request Full details about the request. * @param string $parameter Additional parameter to pass to validation. * @return array|WP_Error A list of valid statuses, otherwise WP_Error object. */ public function sanitize_post_statuses( $statuses, $request, $parameter ) { $statuses = wp_parse_slug_list( $statuses ); // The default status is different in WP_REST_Attachments_Controller. $attributes = $request->get_attributes(); $default_status = $attributes['args']['status']['default']; foreach ( $statuses as $status ) { if ( $status === $default_status ) { continue; } $post_type_obj = get_post_type_object( $this->post_type ); if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { $result = rest_validate_request_arg( $status, $request, $parameter ); if ( is_wp_error( $result ) ) { return $result; } } else { return new WP_Error( 'rest_forbidden_status', __( 'Status is forbidden.' ), array( 'status' => rest_authorization_required_code() ) ); } } return $statuses; } /** * Prepares the 'tax_query' for a collection of posts. * * @since 5.7.0 * * @param array $args WP_Query arguments. * @param WP_REST_Request $request Full details about the request. * @return array Updated query arguments. */ private function prepare_tax_query( array $args, WP_REST_Request $request ) { $relation = $request['tax_relation']; if ( $relation ) { $args['tax_query'] = array( 'relation' => $relation ); } $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $tax_include = $request[ $base ]; $tax_exclude = $request[ $base . '_exclude' ]; if ( $tax_include ) { $terms = array(); $include_children = false; $operator = 'IN'; if ( rest_is_array( $tax_include ) ) { $terms = $tax_include; } elseif ( rest_is_object( $tax_include ) ) { $terms = empty( $tax_include['terms'] ) ? array() : $tax_include['terms']; $include_children = ! empty( $tax_include['include_children'] ); if ( isset( $tax_include['operator'] ) && 'AND' === $tax_include['operator'] ) { $operator = 'AND'; } } if ( $terms ) { $args['tax_query'][] = array( 'taxonomy' => $taxonomy->name, 'field' => 'term_id', 'terms' => $terms, 'include_children' => $include_children, 'operator' => $operator, ); } } if ( $tax_exclude ) { $terms = array(); $include_children = false; if ( rest_is_array( $tax_exclude ) ) { $terms = $tax_exclude; } elseif ( rest_is_object( $tax_exclude ) ) { $terms = empty( $tax_exclude['terms'] ) ? array() : $tax_exclude['terms']; $include_children = ! empty( $tax_exclude['include_children'] ); } if ( $terms ) { $args['tax_query'][] = array( 'taxonomy' => $taxonomy->name, 'field' => 'term_id', 'terms' => $terms, 'include_children' => $include_children, 'operator' => 'NOT IN', ); } } } return $args; } /** * Prepares the collection schema for including and excluding items by terms. * * @since 5.7.0 * * @param array $query_params Collection schema. * @return array Updated schema. */ private function prepare_taxonomy_limit_schema( array $query_params ) { $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); if ( ! $taxonomies ) { return $query_params; } $query_params['tax_relation'] = array( 'description' => __( 'Limit result set based on relationship between multiple taxonomies.' ), 'type' => 'string', 'enum' => array( 'AND', 'OR' ), ); $limit_schema = array( 'type' => array( 'object', 'array' ), 'oneOf' => array( array( 'title' => __( 'Term ID List' ), 'description' => __( 'Match terms with the listed IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), ), array( 'title' => __( 'Term ID Taxonomy Query' ), 'description' => __( 'Perform an advanced term query.' ), 'type' => 'object', 'properties' => array( 'terms' => array( 'description' => __( 'Term IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ), 'include_children' => array( 'description' => __( 'Whether to include child terms in the terms limiting the result set.' ), 'type' => 'boolean', 'default' => false, ), ), 'additionalProperties' => false, ), ), ); $include_schema = array_merge( array( /* translators: %s: Taxonomy name. */ 'description' => __( 'Limit result set to items with specific terms assigned in the %s taxonomy.' ), ), $limit_schema ); // 'operator' is supported only for 'include' queries. $include_schema['oneOf'][1]['properties']['operator'] = array( 'description' => __( 'Whether items must be assigned all or any of the specified terms.' ), 'type' => 'string', 'enum' => array( 'AND', 'OR' ), 'default' => 'OR', ); $exclude_schema = array_merge( array( /* translators: %s: Taxonomy name. */ 'description' => __( 'Limit result set to items except those with specific terms assigned in the %s taxonomy.' ), ), $limit_schema ); foreach ( $taxonomies as $taxonomy ) { $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $base_exclude = $base . '_exclude'; $query_params[ $base ] = $include_schema; $query_params[ $base ]['description'] = sprintf( $query_params[ $base ]['description'], $base ); $query_params[ $base_exclude ] = $exclude_schema; $query_params[ $base_exclude ]['description'] = sprintf( $query_params[ $base_exclude ]['description'], $base ); if ( ! $taxonomy->hierarchical ) { unset( $query_params[ $base ]['oneOf'][1]['properties']['include_children'] ); unset( $query_params[ $base_exclude ]['oneOf'][1]['properties']['include_children'] ); } } return $query_params; } } <?php /** * REST API: WP_REST_Users_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage users via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Users_Controller extends WP_REST_Controller { /** * Instance of a user meta fields object. * * @since 4.7.0 * @var WP_REST_User_Meta_Fields */ protected $meta; /** * Whether the controller supports batching. * * @since 6.6.0 * @var array */ protected $allow_batch = array( 'v1' => true ); /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'users'; $this->meta = new WP_REST_User_Meta_Fields(); } /** * Registers the routes for users. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'id' => array( 'description' => __( 'Unique identifier for the user.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as users do not support trashing.' ), ), 'reassign' => array( 'type' => 'integer', 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 'required' => true, 'sanitize_callback' => array( $this, 'check_reassign' ), ), ), ), 'allow_batch' => $this->allow_batch, 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/me', array( array( 'methods' => WP_REST_Server::READABLE, 'permission_callback' => '__return_true', 'callback' => array( $this, 'get_current_item' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_current_item' ), 'permission_callback' => array( $this, 'update_current_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_current_item' ), 'permission_callback' => array( $this, 'delete_current_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as users do not support trashing.' ), ), 'reassign' => array( 'type' => 'integer', 'description' => __( 'Reassign the deleted user\'s posts and links to this user ID.' ), 'required' => true, 'sanitize_callback' => array( $this, 'check_reassign' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks for a valid value for the reassign parameter when deleting users. * * The value can be an integer, 'false', false, or ''. * * @since 4.7.0 * * @param int|bool $value The value passed to the reassign parameter. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter that is being sanitized. * @return int|bool|WP_Error */ public function check_reassign( $value, $request, $param ) { if ( is_numeric( $value ) ) { return $value; } if ( empty( $value ) || false === $value || 'false' === $value ) { return false; } return new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); } /** * Permissions check for getting all users. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, otherwise WP_Error object. */ public function get_items_permissions_check( $request ) { // Check if roles is specified in GET request and if user can list users. if ( ! empty( $request['roles'] ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by role.' ), array( 'status' => rest_authorization_required_code() ) ); } // Check if capabilities is specified in GET request and if user can list users. if ( ! empty( $request['capabilities'] ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to filter users by capability.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit users.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( in_array( $request['orderby'], array( 'email', 'registered_date' ), true ) && ! current_user_can( 'list_users' ) ) { return new WP_Error( 'rest_forbidden_orderby', __( 'Sorry, you are not allowed to order users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'authors' === $request['who'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( post_type_supports( $type->name, 'author' ) && current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_forbidden_who', __( 'Sorry, you are not allowed to query users by this parameter.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves all users. * * @since 4.7.0 * @since 6.8.0 Added support for the search_columns query param. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); /* * This array defines mappings between public API query parameters whose * values are accepted as-passed, and their internal WP_Query parameter * name equivalents (some are the same). Only values which are also * present in $registered will be set. */ $parameter_mappings = array( 'exclude' => 'exclude', 'include' => 'include', 'order' => 'order', 'per_page' => 'number', 'search' => 'search', 'roles' => 'role__in', 'capabilities' => 'capability__in', 'slug' => 'nicename__in', ); $prepared_args = array(); /* * For each known parameter which is both registered and present in the request, * set the parameter's value on the query $prepared_args. */ foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $prepared_args[ $wp_param ] = $request[ $api_param ]; } } if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) { $prepared_args['offset'] = $request['offset']; } else { $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number']; } if ( isset( $registered['orderby'] ) ) { $orderby_possibles = array( 'id' => 'ID', 'include' => 'include', 'name' => 'display_name', 'registered_date' => 'registered', 'slug' => 'user_nicename', 'include_slugs' => 'nicename__in', 'email' => 'user_email', 'url' => 'user_url', ); $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ]; } if ( isset( $registered['who'] ) && ! empty( $request['who'] ) && 'authors' === $request['who'] ) { $prepared_args['who'] = 'authors'; } elseif ( ! current_user_can( 'list_users' ) ) { $prepared_args['has_published_posts'] = get_post_types( array( 'show_in_rest' => true ), 'names' ); } if ( ! empty( $request['has_published_posts'] ) ) { $prepared_args['has_published_posts'] = ( true === $request['has_published_posts'] ) ? get_post_types( array( 'show_in_rest' => true ), 'names' ) : (array) $request['has_published_posts']; } if ( ! empty( $prepared_args['search'] ) ) { if ( ! current_user_can( 'list_users' ) ) { $prepared_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'display_name' ); } $search_columns = $request->get_param( 'search_columns' ); $valid_columns = isset( $prepared_args['search_columns'] ) ? $prepared_args['search_columns'] : array( 'ID', 'user_login', 'user_nicename', 'user_email', 'display_name' ); $search_columns_mapping = array( 'id' => 'ID', 'username' => 'user_login', 'slug' => 'user_nicename', 'email' => 'user_email', 'name' => 'display_name', ); $search_columns = array_map( static function ( $column ) use ( $search_columns_mapping ) { return $search_columns_mapping[ $column ]; }, $search_columns ); $search_columns = array_intersect( $search_columns, $valid_columns ); if ( ! empty( $search_columns ) ) { $prepared_args['search_columns'] = $search_columns; } $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; } $is_head_request = $request->is_method( 'HEAD' ); if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only user IDs are required. $prepared_args['fields'] = 'id'; } /** * Filters WP_User_Query arguments when querying users via the REST API. * * @link https://developer.wordpress.org/reference/classes/wp_user_query/ * * @since 4.7.0 * * @param array $prepared_args Array of arguments for WP_User_Query. * @param WP_REST_Request $request The REST API request. */ $prepared_args = apply_filters( 'rest_user_query', $prepared_args, $request ); $query = new WP_User_Query( $prepared_args ); if ( ! $is_head_request ) { $users = array(); foreach ( $query->get_results() as $user ) { if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { continue; } $data = $this->prepare_item_for_response( $user, $request ); $users[] = $this->prepare_response_for_collection( $data ); } } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $users ); // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; $page = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 ); $prepared_args['fields'] = 'ID'; $total_users = $query->get_total(); if ( $total_users < 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $prepared_args['number'], $prepared_args['offset'] ); $count_query = new WP_User_Query( $prepared_args ); $total_users = $count_query->get_total(); } $response->header( 'X-WP-Total', (int) $total_users ); $max_pages = (int) ceil( $total_users / $per_page ); $response->header( 'X-WP-TotalPages', $max_pages ); $base = add_query_arg( urlencode_deep( $request->get_query_params() ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Get the user, if the ID is valid. * * @since 4.7.2 * * @param int $id Supplied ID. * @return WP_User|WP_Error True if ID is valid, WP_Error otherwise. */ protected function get_user( $id ) { $error = new WP_Error( 'rest_user_invalid_id', __( 'Invalid user ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $user = get_userdata( (int) $id ); if ( empty( $user ) || ! $user->exists() ) { return $error; } if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) { return $error; } return $user; } /** * Checks if a given request has access to read a user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. */ public function get_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $types = get_post_types( array( 'show_in_rest' => true ), 'names' ); if ( get_current_user_id() === $user->ID ) { return true; } if ( 'edit' === $request['context'] && ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'edit_user', $user->ID ) && ! current_user_can( 'list_users' ) && ! count_user_posts( $user->ID, $types ) ) { return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to list users.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves a single user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $user = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $user ); return $response; } /** * Retrieves the current user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_current_item( $request ) { $current_user_id = get_current_user_id(); if ( empty( $current_user_id ) ) { return new WP_Error( 'rest_not_logged_in', __( 'You are not currently logged in.' ), array( 'status' => 401 ) ); } $user = wp_get_current_user(); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); return $response; } /** * Checks if a given request has access create users. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { if ( ! current_user_can( 'create_users' ) ) { return new WP_Error( 'rest_cannot_create_user', __( 'Sorry, you are not allowed to create new users.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Creates a single user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_user_exists', __( 'Cannot create existing user.' ), array( 'status' => 400 ) ); } $schema = $this->get_item_schema(); if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { $check_permission = $this->check_role_update( $request['id'], $request['roles'] ); if ( is_wp_error( $check_permission ) ) { return $check_permission; } } $user = $this->prepare_item_for_database( $request ); if ( is_multisite() ) { $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email ); if ( is_wp_error( $ret['errors'] ) && $ret['errors']->has_errors() ) { $error = new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400 ) ); foreach ( $ret['errors']->errors as $code => $messages ) { foreach ( $messages as $message ) { $error->add( $code, $message ); } $error_data = $error->get_error_data( $code ); if ( $error_data ) { $error->add_data( $error_data, $code ); } } return $error; } } if ( is_multisite() ) { $user_id = wpmu_create_user( $user->user_login, $user->user_pass, $user->user_email ); if ( ! $user_id ) { return new WP_Error( 'rest_user_create', __( 'Error creating new user.' ), array( 'status' => 500 ) ); } $user->ID = $user_id; $user_id = wp_update_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } $result = add_user_to_blog( get_site()->id, $user_id, '' ); if ( is_wp_error( $result ) ) { return $result; } } else { $user_id = wp_insert_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } } $user = get_user_by( 'id', $user_id ); /** * Fires immediately after a user is created or updated via the REST API. * * @since 4.7.0 * * @param WP_User $user Inserted or updated user object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a user, false when updating. */ do_action( 'rest_insert_user', $user, $request, true ); if ( ! empty( $request['roles'] ) && ! empty( $schema['properties']['roles'] ) ) { array_map( array( $user, 'add_role' ), $request['roles'] ); } if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $user_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $user = get_user_by( 'id', $user_id ); $fields_update = $this->update_additional_fields_for_object( $user, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** * Fires after a user is completely created or updated via the REST API. * * @since 5.0.0 * * @param WP_User $user Inserted or updated user object. * @param WP_REST_Request $request Request object. * @param bool $creating True when creating a user, false when updating. */ do_action( 'rest_after_insert_user', $user, $request, true ); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user_id ) ) ); return $response; } /** * Checks if a given request has access to update a user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } if ( ! empty( $request['roles'] ) ) { if ( ! current_user_can( 'promote_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_edit_roles', __( 'Sorry, you are not allowed to edit roles of this user.' ), array( 'status' => rest_authorization_required_code() ) ); } $request_params = array_keys( $request->get_params() ); sort( $request_params ); /* * If only 'id' and 'roles' are specified (we are only trying to * edit roles), then only the 'promote_user' cap is required. */ if ( array( 'id', 'roles' ) === $request_params ) { return true; } } if ( ! current_user_can( 'edit_user', $user->ID ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Updates a single user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $id = $user->ID; $owner_id = false; if ( is_string( $request['email'] ) ) { $owner_id = email_exists( $request['email'] ); } if ( $owner_id && $owner_id !== $id ) { return new WP_Error( 'rest_user_invalid_email', __( 'Invalid email address.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['username'] ) && $request['username'] !== $user->user_login ) { return new WP_Error( 'rest_user_invalid_argument', __( 'Username is not editable.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['slug'] ) && $request['slug'] !== $user->user_nicename && get_user_by( 'slug', $request['slug'] ) ) { return new WP_Error( 'rest_user_invalid_slug', __( 'Invalid slug.' ), array( 'status' => 400 ) ); } if ( ! empty( $request['roles'] ) ) { $check_permission = $this->check_role_update( $id, $request['roles'] ); if ( is_wp_error( $check_permission ) ) { return $check_permission; } } $user = $this->prepare_item_for_database( $request ); // Ensure we're operating on the same user we already checked. $user->ID = $id; $user_id = wp_update_user( wp_slash( (array) $user ) ); if ( is_wp_error( $user_id ) ) { return $user_id; } $user = get_user_by( 'id', $user_id ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ do_action( 'rest_insert_user', $user, $request, false ); if ( ! empty( $request['roles'] ) ) { array_map( array( $user, 'add_role' ), $request['roles'] ); } $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $user = get_user_by( 'id', $user_id ); $fields_update = $this->update_additional_fields_for_object( $user, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ do_action( 'rest_after_insert_user', $user, $request, false ); $response = $this->prepare_item_for_response( $user, $request ); $response = rest_ensure_response( $response ); return $response; } /** * Checks if a given request has access to update the current user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_current_item_permissions_check( $request ) { $request['id'] = get_current_user_id(); return $this->update_item_permissions_check( $request ); } /** * Updates the current user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_current_item( $request ) { $request['id'] = get_current_user_id(); return $this->update_item( $request ); } /** * Checks if a given request has access delete a user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } if ( ! current_user_can( 'delete_user', $user->ID ) ) { return new WP_Error( 'rest_user_cannot_delete', __( 'Sorry, you are not allowed to delete this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes a single user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { // We don't support delete requests in multisite. if ( is_multisite() ) { return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 501 ) ); } $user = $this->get_user( $request['id'] ); if ( is_wp_error( $user ) ) { return $user; } $id = $user->ID; $reassign = false === $request['reassign'] ? null : absint( $request['reassign'] ); $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for users. if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( "Users do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } if ( ! empty( $reassign ) ) { if ( $reassign === $id || ! get_userdata( $reassign ) ) { return new WP_Error( 'rest_user_invalid_reassign', __( 'Invalid user ID for reassignment.' ), array( 'status' => 400 ) ); } } $request->set_param( 'context', 'edit' ); $previous = $this->prepare_item_for_response( $user, $request ); // Include user admin functions to get access to wp_delete_user(). require_once ABSPATH . 'wp-admin/includes/user.php'; $result = wp_delete_user( $id, $reassign ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The user cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); /** * Fires immediately after a user is deleted via the REST API. * * @since 4.7.0 * * @param WP_User $user The user data. * @param WP_REST_Response $response The response returned from the API. * @param WP_REST_Request $request The request sent to the API. */ do_action( 'rest_delete_user', $user, $response, $request ); return $response; } /** * Checks if a given request has access to delete the current user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_current_item_permissions_check( $request ) { $request['id'] = get_current_user_id(); return $this->delete_item_permissions_check( $request ); } /** * Deletes the current user. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_current_item( $request ) { $request['id'] = get_current_user_id(); return $this->delete_item( $request ); } /** * Prepares a single user output for response. * * @since 4.7.0 * @since 5.9.0 Renamed `$user` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_User $item User object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $user = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ return apply_filters( 'rest_prepare_user', new WP_REST_Response( array() ), $user, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'id', $fields, true ) ) { $data['id'] = $user->ID; } if ( in_array( 'username', $fields, true ) ) { $data['username'] = $user->user_login; } if ( in_array( 'name', $fields, true ) ) { $data['name'] = $user->display_name; } if ( in_array( 'first_name', $fields, true ) ) { $data['first_name'] = $user->first_name; } if ( in_array( 'last_name', $fields, true ) ) { $data['last_name'] = $user->last_name; } if ( in_array( 'email', $fields, true ) ) { $data['email'] = $user->user_email; } if ( in_array( 'url', $fields, true ) ) { $data['url'] = $user->user_url; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $user->description; } if ( in_array( 'link', $fields, true ) ) { $data['link'] = get_author_posts_url( $user->ID, $user->user_nicename ); } if ( in_array( 'locale', $fields, true ) ) { $data['locale'] = get_user_locale( $user ); } if ( in_array( 'nickname', $fields, true ) ) { $data['nickname'] = $user->nickname; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $user->user_nicename; } if ( in_array( 'roles', $fields, true ) && ( current_user_can( 'list_users' ) || current_user_can( 'edit_user', $user->ID ) ) ) { // Defensively call array_values() to ensure an array is returned. $data['roles'] = array_values( $user->roles ); } if ( in_array( 'registered_date', $fields, true ) ) { $data['registered_date'] = gmdate( 'c', strtotime( $user->user_registered ) ); } if ( in_array( 'capabilities', $fields, true ) ) { $data['capabilities'] = (object) $user->allcaps; } if ( in_array( 'extra_capabilities', $fields, true ) ) { $data['extra_capabilities'] = (object) $user->caps; } if ( in_array( 'avatar_urls', $fields, true ) ) { $data['avatar_urls'] = rest_get_avatar_urls( $user ); } if ( in_array( 'meta', $fields, true ) ) { $data['meta'] = $this->meta->get_value( $user->ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'embed'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $user ) ); } /** * Filters user data returned from the REST API. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_User $user User object used to create response. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_prepare_user', $response, $user, $request ); } /** * Prepares links for the user request. * * @since 4.7.0 * * @param WP_User $user User object. * @return array Links for the given user. */ protected function prepare_links( $user ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $user->ID ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); return $links; } /** * Prepares a single user for creation or update. * * @since 4.7.0 * * @param WP_REST_Request $request Request object. * @return object User object. */ protected function prepare_item_for_database( $request ) { $prepared_user = new stdClass(); $schema = $this->get_item_schema(); // Required arguments. if ( isset( $request['email'] ) && ! empty( $schema['properties']['email'] ) ) { $prepared_user->user_email = $request['email']; } if ( isset( $request['username'] ) && ! empty( $schema['properties']['username'] ) ) { $prepared_user->user_login = $request['username']; } if ( isset( $request['password'] ) && ! empty( $schema['properties']['password'] ) ) { $prepared_user->user_pass = $request['password']; } // Optional arguments. if ( isset( $request['id'] ) ) { $prepared_user->ID = absint( $request['id'] ); } if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_user->display_name = $request['name']; } if ( isset( $request['first_name'] ) && ! empty( $schema['properties']['first_name'] ) ) { $prepared_user->first_name = $request['first_name']; } if ( isset( $request['last_name'] ) && ! empty( $schema['properties']['last_name'] ) ) { $prepared_user->last_name = $request['last_name']; } if ( isset( $request['nickname'] ) && ! empty( $schema['properties']['nickname'] ) ) { $prepared_user->nickname = $request['nickname']; } if ( isset( $request['slug'] ) && ! empty( $schema['properties']['slug'] ) ) { $prepared_user->user_nicename = $request['slug']; } if ( isset( $request['description'] ) && ! empty( $schema['properties']['description'] ) ) { $prepared_user->description = $request['description']; } if ( isset( $request['url'] ) && ! empty( $schema['properties']['url'] ) ) { $prepared_user->user_url = $request['url']; } if ( isset( $request['locale'] ) && ! empty( $schema['properties']['locale'] ) ) { $prepared_user->locale = $request['locale']; } // Setting roles will be handled outside of this function. if ( isset( $request['roles'] ) ) { $prepared_user->role = false; } /** * Filters user data before insertion via the REST API. * * @since 4.7.0 * * @param object $prepared_user User object. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_pre_insert_user', $prepared_user, $request ); } /** * Determines if the current user is allowed to make the desired roles change. * * @since 4.7.0 * * @global WP_Roles $wp_roles WordPress role management object. * * @param int $user_id User ID. * @param array $roles New user roles. * @return true|WP_Error True if the current user is allowed to make the role change, * otherwise a WP_Error object. */ protected function check_role_update( $user_id, $roles ) { global $wp_roles; foreach ( $roles as $role ) { if ( ! isset( $wp_roles->role_objects[ $role ] ) ) { return new WP_Error( 'rest_user_invalid_role', /* translators: %s: Role key. */ sprintf( __( 'The role %s does not exist.' ), $role ), array( 'status' => 400 ) ); } $potential_role = $wp_roles->role_objects[ $role ]; /* * Don't let anyone with 'edit_users' (admins) edit their own role to something without it. * Multisite super admins can freely edit their blog roles -- they possess all caps. */ if ( ! ( is_multisite() && current_user_can( 'manage_sites' ) ) && get_current_user_id() === $user_id && ! $potential_role->has_cap( 'edit_users' ) ) { return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => rest_authorization_required_code() ) ); } // Include user admin functions to get access to get_editable_roles(). require_once ABSPATH . 'wp-admin/includes/user.php'; // The new role must be editable by the logged-in user. $editable_roles = get_editable_roles(); if ( empty( $editable_roles[ $role ] ) ) { return new WP_Error( 'rest_user_invalid_role', __( 'Sorry, you are not allowed to give users that role.' ), array( 'status' => 403 ) ); } } return true; } /** * Check a username for the REST API. * * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. * * @since 4.7.0 * * @param string $value The username submitted in the request. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter name. * @return string|WP_Error The sanitized username, if valid, otherwise an error. */ public function check_username( $value, $request, $param ) { $username = (string) $value; if ( ! validate_username( $username ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'This username is invalid because it uses illegal characters. Please enter a valid username.' ), array( 'status' => 400 ) ); } /** This filter is documented in wp-includes/user.php */ $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ), true ) ) { return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) ); } return $username; } /** * Check a user password for the REST API. * * Performs a couple of checks like edit_user() in wp-admin/includes/user.php. * * @since 4.7.0 * * @param string $value The password submitted in the request. * @param WP_REST_Request $request Full details about the request. * @param string $param The parameter name. * @return string|WP_Error The sanitized password, if valid, otherwise an error. */ public function check_user_password( #[\SensitiveParameter] $value, $request, $param ) { $password = (string) $value; if ( empty( $password ) ) { return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) ); } if ( str_contains( $password, '\\' ) ) { return new WP_Error( 'rest_user_invalid_password', sprintf( /* translators: %s: The '\' character. */ __( 'Passwords cannot contain the "%s" character.' ), '\\' ), array( 'status' => 400 ) ); } return $password; } /** * Retrieves the user's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'user', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'Unique identifier for the user.' ), 'type' => 'integer', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'username' => array( 'description' => __( 'Login name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'required' => true, 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_username' ), ), ), 'name' => array( 'description' => __( 'Display name for the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'first_name' => array( 'description' => __( 'First name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'last_name' => array( 'description' => __( 'Last name for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'email' => array( 'description' => __( 'The email address for the user.' ), 'type' => 'string', 'format' => 'email', 'context' => array( 'edit' ), 'required' => true, ), 'url' => array( 'description' => __( 'URL of the user.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ), 'description' => array( 'description' => __( 'Description of the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), ), 'link' => array( 'description' => __( 'Author URL of the user.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'locale' => array( 'description' => __( 'Locale for the user.' ), 'type' => 'string', 'enum' => array_merge( array( '', 'en_US' ), get_available_languages() ), 'context' => array( 'edit' ), ), 'nickname' => array( 'description' => __( 'The nickname for the user.' ), 'type' => 'string', 'context' => array( 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the user.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), 'registered_date' => array( 'description' => __( 'Registration date for the user.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'edit' ), 'readonly' => true, ), 'roles' => array( 'description' => __( 'Roles assigned to the user.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'edit' ), ), 'password' => array( 'description' => __( 'Password for the user (never included).' ), 'type' => 'string', 'context' => array(), // Password is never displayed. 'required' => true, 'arg_options' => array( 'sanitize_callback' => array( $this, 'check_user_password' ), ), ), 'capabilities' => array( 'description' => __( 'All capabilities assigned to the user.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'extra_capabilities' => array( 'description' => __( 'Any extra capabilities assigned to the user.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), ), ); if ( get_option( 'show_avatars' ) ) { $avatar_properties = array(); $avatar_sizes = rest_get_avatar_sizes(); foreach ( $avatar_sizes as $size ) { $avatar_properties[ $size ] = array( /* translators: %d: Avatar image size in pixels. */ 'description' => sprintf( __( 'Avatar URL with image size of %d pixels.' ), $size ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'embed', 'view', 'edit' ), ); } $schema['properties']['avatar_urls'] = array( 'description' => __( 'Avatar URLs for the user.' ), 'type' => 'object', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, 'properties' => $avatar_properties, ); } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'default' => 'asc', 'description' => __( 'Order sort attribute ascending or descending.' ), 'enum' => array( 'asc', 'desc' ), 'type' => 'string', ); $query_params['orderby'] = array( 'default' => 'name', 'description' => __( 'Sort collection by user attribute.' ), 'enum' => array( 'id', 'include', 'name', 'registered_date', 'slug', 'include_slugs', 'email', 'url', ), 'type' => 'string', ); $query_params['slug'] = array( 'description' => __( 'Limit result set to users with one or more specific slugs.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['roles'] = array( 'description' => __( 'Limit result set to users matching at least one specific role provided. Accepts csv list or single role.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['capabilities'] = array( 'description' => __( 'Limit result set to users matching at least one specific capability provided. Accepts csv list or single capability.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ); $query_params['who'] = array( 'description' => __( 'Limit result set to users who are considered authors.' ), 'type' => 'string', 'enum' => array( 'authors', ), ); $query_params['has_published_posts'] = array( 'description' => __( 'Limit result set to users who have published posts.' ), 'type' => array( 'boolean', 'array' ), 'items' => array( 'type' => 'string', 'enum' => get_post_types( array( 'show_in_rest' => true ), 'names' ), ), ); $query_params['search_columns'] = array( 'default' => array(), 'description' => __( 'Array of column names to be searched.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'email', 'name', 'id', 'username', 'slug' ), 'type' => 'string', ), ); /** * Filters REST API collection parameters for the users controller. * * This filter registers the collection parameter, but does not map the * collection parameter to an internal WP_User_Query parameter. Use the * `rest_user_query` filter to set WP_User_Query arguments. * * @since 4.7.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_user_collection_params', $query_params ); } } <?php /** * REST API: WP_REST_Template_Revisions_Controller class * * @package WordPress * @subpackage REST_API * @since 6.4.0 */ /** * Core class used to access template revisions via the REST API. * * @since 6.4.0 * * @see WP_REST_Controller */ class WP_REST_Template_Revisions_Controller extends WP_REST_Revisions_Controller { /** * Parent post type. * * @since 6.4.0 * @var string */ private $parent_post_type; /** * Parent controller. * * @since 6.4.0 * @var WP_REST_Controller */ private $parent_controller; /** * The base of the parent controller's route. * * @since 6.4.0 * @var string */ private $parent_base; /** * Constructor. * * @since 6.4.0 * * @param string $parent_post_type Post type of the parent. */ 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(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Templates_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; } /** * Registers the routes for revisions based on post types supporting revisions. * * @since 6.4.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s', $this->parent_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', // Matches the template name. '[\/\w%-]+', $this->rest_base ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<parent>%s%s)/%s/%s', $this->parent_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)', // Matches the template name. '[\/\w%-]+', $this->rest_base, '(?P<id>[\d]+)' ), array( 'args' => array( 'parent' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ), ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as revisions do not support trashing.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Gets the parent post, if the template ID is valid. * * @since 6.4.0 * * @param string $parent_template_id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_parent( $parent_template_id ) { $template = get_block_template( $parent_template_id, $this->parent_post_type ); if ( ! $template ) { return new WP_Error( 'rest_post_invalid_parent', __( 'Invalid template parent ID.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } $parent_post_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0; if ( $parent_post_id <= 0 ) { return new WP_Error( 'rest_invalid_template', __( 'Templates based on theme files can\'t have revisions.' ), array( 'status' => WP_Http::BAD_REQUEST ) ); } return get_post( $template->wp_id ); } /** * Prepares the item for the REST response. * * @since 6.4.0 * * @param WP_Post $item Post revision object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { $template = _build_block_template_result_from_post( $item ); $response = $this->parent_controller->prepare_item_for_response( $template, $request ); // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { return $response; } $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $item->post_parent; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $template ); $response->add_links( $links ); } return $response; } /** * Checks if a given request has access to delete a revision. * * @since 6.4.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'delete_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this revision.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Prepares links for the request. * * @since 6.4.0 * * @param WP_Block_Template $template Template. * @return array Links for the given post. */ protected function prepare_links( $template ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ), ), 'parent' => array( 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ), ), ); return $links; } /** * Retrieves the item's schema, conforming to JSON Schema. * * @since 6.4.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = $this->parent_controller->get_item_schema(); $schema['properties']['parent'] = array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * Synced patterns REST API: WP_REST_Blocks_Controller class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Controller which provides a REST endpoint for the editor to read, create, * edit, and delete synced patterns (formerly called reusable blocks). * Patterns are stored as posts with the wp_block post type. * * @since 5.0.0 * * @see WP_REST_Posts_Controller * @see WP_REST_Controller */ class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller { /** * Checks if a pattern can be read. * * @since 5.0.0 * * @param WP_Post $post Post object that backs the block. * @return bool Whether the pattern can be read. */ public function check_read_permission( $post ) { // By default the read_post capability is mapped to edit_posts. if ( ! current_user_can( 'read_post', $post->ID ) ) { return false; } return parent::check_read_permission( $post ); } /** * Filters a response based on the context defined in the schema. * * @since 5.0.0 * @since 6.3.0 Adds the `wp_pattern_sync_status` postmeta property to the top level of response. * * @param array $data Response data to filter. * @param string $context Context defined in the schema. * @return array Filtered response. */ public function filter_response_by_context( $data, $context ) { $data = parent::filter_response_by_context( $data, $context ); /* * Remove `title.rendered` and `content.rendered` from the response. * It doesn't make sense for a pattern to have rendered content on its own, * since rendering a block requires it to be inside a post or a page. */ unset( $data['title']['rendered'] ); unset( $data['content']['rendered'] ); // Add the core wp_pattern_sync_status meta as top level property to the response. $data['wp_pattern_sync_status'] = isset( $data['meta']['wp_pattern_sync_status'] ) ? $data['meta']['wp_pattern_sync_status'] : ''; unset( $data['meta']['wp_pattern_sync_status'] ); return $data; } /** * Retrieves the pattern's schema, conforming to JSON Schema. * * @since 5.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); /* * Allow all contexts to access `title.raw` and `content.raw`. * Clients always need the raw markup of a pattern to do anything useful, * e.g. parse it or display it in an editor. */ $schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' ); $schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' ); /* * Remove `title.rendered` and `content.rendered` from the schema. * It doesn't make sense for a pattern to have rendered content on its own, * since rendering a block requires it to be inside a post or a page. */ unset( $schema['properties']['title']['properties']['rendered'] ); unset( $schema['properties']['content']['properties']['rendered'] ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Post_Statuses_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to access post statuses via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller { /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'statuses'; } /** * Registers the routes for post statuses. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<status>[\w-]+)', array( 'args' => array( 'status' => array( 'description' => __( 'An alphanumeric identifier for the status.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read post statuses. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to manage post statuses.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves all post statuses, depending on user context. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $data = array(); $statuses = get_post_stati( array( 'internal' => false ), 'object' ); $statuses['trash'] = get_post_status_object( 'trash' ); foreach ( $statuses as $obj ) { $ret = $this->check_read_permission( $obj ); if ( ! $ret ) { continue; } $status = $this->prepare_item_for_response( $obj, $request ); $data[ $obj->name ] = $this->prepare_response_for_collection( $status ); } return rest_ensure_response( $data ); } /** * Checks if a given request has access to read a post status. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $status = get_post_status_object( $request['status'] ); if ( empty( $status ) ) { return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) ); } $check = $this->check_read_permission( $status ); if ( ! $check ) { return new WP_Error( 'rest_cannot_read_status', __( 'Cannot view status.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Checks whether a given post status should be visible. * * @since 4.7.0 * * @param object $status Post status. * @return bool True if the post status is visible, otherwise false. */ protected function check_read_permission( $status ) { if ( true === $status->public ) { return true; } if ( false === $status->internal || 'trash' === $status->name ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } } return false; } /** * Retrieves a specific post status. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $obj = get_post_status_object( $request['status'] ); if ( empty( $obj ) ) { return new WP_Error( 'rest_status_invalid', __( 'Invalid status.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $obj, $request ); return rest_ensure_response( $data ); } /** * Prepares a post status object for serialization. * * @since 4.7.0 * @since 5.9.0 Renamed `$status` to `$item` to match parent class for PHP 8 named parameter support. * * @param stdClass $item Post status data. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Post status data. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $status = $item; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'name', $fields, true ) ) { $data['name'] = $status->label; } if ( in_array( 'private', $fields, true ) ) { $data['private'] = (bool) $status->private; } if ( in_array( 'protected', $fields, true ) ) { $data['protected'] = (bool) $status->protected; } if ( in_array( 'public', $fields, true ) ) { $data['public'] = (bool) $status->public; } if ( in_array( 'queryable', $fields, true ) ) { $data['queryable'] = (bool) $status->publicly_queryable; } if ( in_array( 'show_in_list', $fields, true ) ) { $data['show_in_list'] = (bool) $status->show_in_admin_all_list; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $status->name; } if ( in_array( 'date_floating', $fields, true ) ) { $data['date_floating'] = $status->date_floating; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); $rest_url = rest_url( rest_get_route_for_post_type_items( 'post' ) ); if ( 'publish' === $status->name ) { $response->add_link( 'archives', $rest_url ); } else { $response->add_link( 'archives', add_query_arg( 'status', $status->name, $rest_url ) ); } /** * Filters a post status returned from the REST API. * * Allows modification of the status data right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param object $status The original post status object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_status', $response, $status, $request ); } /** * Retrieves the post status' schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'status', 'type' => 'object', 'properties' => array( 'name' => array( 'description' => __( 'The title for the status.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'private' => array( 'description' => __( 'Whether posts with this status should be private.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'protected' => array( 'description' => __( 'Whether posts with this status should be protected.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'public' => array( 'description' => __( 'Whether posts of this status should be shown in the front end of the site.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'queryable' => array( 'description' => __( 'Whether posts with this status should be publicly-queryable.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'show_in_list' => array( 'description' => __( 'Whether to include posts in the edit listing for their post type.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the status.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'date_floating' => array( 'description' => __( 'Whether posts of this status may have floating published dates.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } } <?php /** * REST API: WP_REST_Edit_Site_Export_Controller class * * @package WordPress * @subpackage REST_API */ /** * Controller which provides REST endpoint for exporting current templates * and template parts. * * @since 5.9.0 * * @see WP_REST_Controller */ class WP_REST_Edit_Site_Export_Controller extends WP_REST_Controller { /** * Constructor. * * @since 5.9.0 */ public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'export'; } /** * Registers the site export route. * * @since 5.9.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'export' ), 'permission_callback' => array( $this, 'permissions_check' ), ), ) ); } /** * Checks whether a given request has permission to export. * * @since 5.9.0 * * @return true|WP_Error True if the request has access, or WP_Error object. */ public function permissions_check() { if ( current_user_can( 'export' ) ) { return true; } return new WP_Error( 'rest_cannot_export_templates', __( 'Sorry, you are not allowed to export templates and template parts.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Output a ZIP file with an export of the current templates * and template parts from the site editor, and close the connection. * * @since 5.9.0 * * @return void|WP_Error */ public function export() { // Generate the export file. $filename = wp_generate_block_templates_export_file(); if ( is_wp_error( $filename ) ) { $filename->add_data( array( 'status' => 500 ) ); return $filename; } $theme_name = basename( get_stylesheet() ); header( 'Content-Type: application/zip' ); header( 'Content-Disposition: attachment; filename=' . $theme_name . '.zip' ); header( 'Content-Length: ' . filesize( $filename ) ); flush(); readfile( $filename ); unlink( $filename ); exit; } } <?php /** * REST API: WP_REST_Taxonomies_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage taxonomies via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Taxonomies_Controller extends WP_REST_Controller { /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'taxonomies'; } /** * Registers the routes for taxonomies. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<taxonomy>[\w-]+)', array( 'args' => array( 'taxonomy' => array( 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read taxonomies. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { if ( ! empty( $request['type'] ) ) { $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); } else { $taxonomies = get_taxonomies( '', 'objects' ); } foreach ( $taxonomies as $taxonomy ) { if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->assign_terms ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves all public taxonomies. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); if ( isset( $registered['type'] ) && ! empty( $request['type'] ) ) { $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); } else { $taxonomies = get_taxonomies( '', 'objects' ); } $data = array(); foreach ( $taxonomies as $tax_type => $value ) { if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->assign_terms ) ) ) { continue; } $tax = $this->prepare_item_for_response( $value, $request ); $tax = $this->prepare_response_for_collection( $tax ); $data[ $tax_type ] = $tax; } if ( empty( $data ) ) { // Response should still be returned as a JSON object when it is empty. $data = (object) $data; } return rest_ensure_response( $data ); } /** * Checks if a given request has access to a taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has read access for the item, otherwise false or WP_Error object. */ public function get_item_permissions_check( $request ) { $tax_obj = get_taxonomy( $request['taxonomy'] ); if ( $tax_obj ) { if ( empty( $tax_obj->show_in_rest ) ) { return false; } if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->assign_terms ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); } } return true; } /** * Retrieves a specific taxonomy. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $tax_obj = get_taxonomy( $request['taxonomy'] ); if ( empty( $tax_obj ) ) { return new WP_Error( 'rest_taxonomy_invalid', __( 'Invalid taxonomy.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $tax_obj, $request ); return rest_ensure_response( $data ); } /** * Prepares a taxonomy object for serialization. * * @since 4.7.0 * @since 5.9.0 Renamed `$taxonomy` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_Taxonomy $item Taxonomy data. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $taxonomy = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php */ return apply_filters( 'rest_prepare_taxonomy', new WP_REST_Response( array() ), $taxonomy, $request ); } $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'name', $fields, true ) ) { $data['name'] = $taxonomy->label; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $taxonomy->name; } if ( in_array( 'capabilities', $fields, true ) ) { $data['capabilities'] = $taxonomy->cap; } if ( in_array( 'description', $fields, true ) ) { $data['description'] = $taxonomy->description; } if ( in_array( 'labels', $fields, true ) ) { $data['labels'] = $taxonomy->labels; } if ( in_array( 'types', $fields, true ) ) { $data['types'] = array_values( $taxonomy->object_type ); } if ( in_array( 'show_cloud', $fields, true ) ) { $data['show_cloud'] = $taxonomy->show_tagcloud; } if ( in_array( 'hierarchical', $fields, true ) ) { $data['hierarchical'] = $taxonomy->hierarchical; } if ( in_array( 'rest_base', $fields, true ) ) { $data['rest_base'] = $base; } if ( in_array( 'rest_namespace', $fields, true ) ) { $data['rest_namespace'] = $taxonomy->rest_namespace; } if ( in_array( 'visibility', $fields, true ) ) { $data['visibility'] = array( 'public' => (bool) $taxonomy->public, 'publicly_queryable' => (bool) $taxonomy->publicly_queryable, 'show_admin_column' => (bool) $taxonomy->show_admin_column, 'show_in_nav_menus' => (bool) $taxonomy->show_in_nav_menus, 'show_in_quick_edit' => (bool) $taxonomy->show_in_quick_edit, 'show_ui' => (bool) $taxonomy->show_ui, ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $taxonomy ) ); } /** * Filters a taxonomy returned from the REST API. * * Allows modification of the taxonomy data right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Taxonomy $item The original taxonomy object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_taxonomy', $response, $taxonomy, $request ); } /** * Prepares links for the request. * * @since 6.1.0 * * @param WP_Taxonomy $taxonomy The taxonomy. * @return array Links for the given taxonomy. */ protected function prepare_links( $taxonomy ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'https://api.w.org/items' => array( 'href' => rest_url( rest_get_route_for_taxonomy_items( $taxonomy->name ) ), ), ); } /** * Retrieves the taxonomy's schema, conforming to JSON Schema. * * @since 4.7.0 * @since 5.0.0 The `visibility` property was added. * @since 5.9.0 The `rest_namespace` property was added. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'taxonomy', 'type' => 'object', 'properties' => array( 'capabilities' => array( 'description' => __( 'All capabilities used by the taxonomy.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'A human-readable description of the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hierarchical' => array( 'description' => __( 'Whether or not the taxonomy should have children.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'labels' => array( 'description' => __( 'Human-readable labels for the taxonomy for various contexts.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The title for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'show_cloud' => array( 'description' => __( 'Whether or not the term cloud should be displayed.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'types' => array( 'description' => __( 'Types associated with the taxonomy.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rest_base' => array( 'description' => __( 'REST base route for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rest_namespace' => array( 'description' => __( 'REST namespace route for the taxonomy.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'visibility' => array( 'description' => __( 'The visibility settings for the taxonomy.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, 'properties' => array( 'public' => array( 'description' => __( 'Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.' ), 'type' => 'boolean', ), 'publicly_queryable' => array( 'description' => __( 'Whether the taxonomy is publicly queryable.' ), 'type' => 'boolean', ), 'show_ui' => array( 'description' => __( 'Whether to generate a default UI for managing this taxonomy.' ), 'type' => 'boolean', ), 'show_admin_column' => array( 'description' => __( 'Whether to allow automatic creation of taxonomy columns on associated post-types table.' ), 'type' => 'boolean', ), 'show_in_nav_menus' => array( 'description' => __( 'Whether to make the taxonomy available for selection in navigation menus.' ), 'type' => 'boolean', ), 'show_in_quick_edit' => array( 'description' => __( 'Whether to show the taxonomy in the quick/bulk edit panel.' ), 'type' => 'boolean', ), ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { $new_params = array(); $new_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); $new_params['type'] = array( 'description' => __( 'Limit results to taxonomies associated with a specific post type.' ), 'type' => 'string', ); return $new_params; } } <?php /** * REST API: WP_REST_Revisions_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to access revisions via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Revisions_Controller extends WP_REST_Controller { /** * Parent post type. * * @since 4.7.0 * @var string */ private $parent_post_type; /** * Instance of a revision meta fields object. * * @since 6.4.0 * @var WP_REST_Post_Meta_Fields */ protected $meta; /** * Parent controller. * * @since 4.7.0 * @var WP_REST_Controller */ private $parent_controller; /** * The base of the parent controller's route. * * @since 4.7.0 * @var string */ private $parent_base; /** * Constructor. * * @since 4.7.0 * * @param string $parent_post_type Post type of the parent. */ public function __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(); if ( ! $parent_controller ) { $parent_controller = new WP_REST_Posts_Controller( $parent_post_type ); } $this->parent_controller = $parent_controller; $this->rest_base = 'revisions'; $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; $this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2'; $this->meta = new WP_REST_Post_Meta_Fields( $parent_post_type ); } /** * Registers the routes for revisions based on post types supporting revisions. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 'args' => array( 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), 'args' => array( 'force' => array( 'type' => 'boolean', 'default' => false, 'description' => __( 'Required to be true, as revisions do not support trashing.' ), ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get the parent post, if the ID is valid. * * @since 4.7.2 * * @param int $parent_post_id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_parent( $parent_post_id ) { $error = new WP_Error( 'rest_post_invalid_parent', __( 'Invalid post parent ID.' ), array( 'status' => 404 ) ); if ( (int) $parent_post_id <= 0 ) { return $error; } $parent_post = get_post( (int) $parent_post_id ); if ( empty( $parent_post ) || empty( $parent_post->ID ) || $this->parent_post_type !== $parent_post->post_type ) { return $error; } return $parent_post; } /** * Checks if a given request has access to get revisions. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'edit_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to view revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Get the revision, if the ID is valid. * * @since 4.7.2 * * @param int $id Supplied ID. * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. */ protected function get_revision( $id ) { $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid revision ID.' ), array( 'status' => 404 ) ); if ( (int) $id <= 0 ) { return $error; } $revision = get_post( (int) $id ); if ( empty( $revision ) || empty( $revision->ID ) || 'revision' !== $revision->post_type ) { return $error; } return $revision; } /** * Gets a collection of revisions. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } // Ensure a search string is set in case the orderby is set to 'relevance'. if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) { return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) ); } // Ensure an include parameter is set in case the orderby is set to 'include'. if ( ! empty( $request['orderby'] ) && 'include' === $request['orderby'] && empty( $request['include'] ) ) { return new WP_Error( 'rest_orderby_include_missing_include', __( 'You need to define an include parameter to order by include.' ), array( 'status' => 400 ) ); } $is_head_request = $request->is_method( 'HEAD' ); if ( wp_revisions_enabled( $parent ) ) { $registered = $this->get_collection_params(); $args = array( 'post_parent' => $parent->ID, 'post_type' => 'revision', 'post_status' => 'inherit', 'posts_per_page' => -1, 'orderby' => 'date ID', 'order' => 'DESC', 'suppress_filters' => true, ); $parameter_mappings = array( 'exclude' => 'post__not_in', 'include' => 'post__in', 'offset' => 'offset', 'order' => 'order', 'orderby' => 'orderby', 'page' => 'paged', 'per_page' => 'posts_per_page', 'search' => 's', ); foreach ( $parameter_mappings as $api_param => $wp_param ) { if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) { $args[ $wp_param ] = $request[ $api_param ]; } } // For backward-compatibility, 'date' needs to resolve to 'date ID'. if ( isset( $args['orderby'] ) && 'date' === $args['orderby'] ) { $args['orderby'] = 'date ID'; } if ( $is_head_request ) { // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. $args['fields'] = 'ids'; // Disable priming post meta for HEAD requests to improve performance. $args['update_post_term_cache'] = false; $args['update_post_meta_cache'] = false; } /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ $args = apply_filters( 'rest_revision_query', $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); $revisions_query = new WP_Query(); $revisions = $revisions_query->query( $query_args ); $offset = isset( $query_args['offset'] ) ? (int) $query_args['offset'] : 0; $page = isset( $query_args['paged'] ) ? (int) $query_args['paged'] : 0; $total_revisions = $revisions_query->found_posts; if ( $total_revisions < 1 ) { // Out-of-bounds, run the query again without LIMIT for total count. unset( $query_args['paged'], $query_args['offset'] ); $count_query = new WP_Query(); $count_query->query( $query_args ); $total_revisions = $count_query->found_posts; } if ( $revisions_query->query_vars['posts_per_page'] > 0 ) { $max_pages = (int) ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] ); } else { $max_pages = $total_revisions > 0 ? 1 : 0; } if ( $total_revisions > 0 ) { if ( $offset >= $total_revisions ) { return new WP_Error( 'rest_revision_invalid_offset_number', __( 'The offset number requested is larger than or equal to the number of available revisions.' ), array( 'status' => 400 ) ); } elseif ( ! $offset && $page > $max_pages ) { return new WP_Error( 'rest_revision_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } } } else { $revisions = array(); $total_revisions = 0; $max_pages = 0; $page = (int) $request['page']; } if ( ! $is_head_request ) { $response = array(); foreach ( $revisions as $revision ) { $data = $this->prepare_item_for_response( $revision, $request ); $response[] = $this->prepare_response_for_collection( $data ); } $response = rest_ensure_response( $response ); } else { $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); $base_path = rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ); $base = add_query_arg( urlencode_deep( $request_params ), $base_path ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Checks if a given request has access to get a specific revision. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { return $this->get_items_permissions_check( $request ); } /** * Retrieves one revision from the collection. * * @since 4.7.0 * @since 6.5.0 Added a condition to check that parent id matches revision parent id. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } if ( (int) $parent->ID !== (int) $revision->post_parent ) { return new WP_Error( 'rest_revision_parent_id_mismatch', /* translators: %d: A post id. */ sprintf( __( 'The revision does not belong to the specified parent with id of "%d"' ), $parent->ID ), array( 'status' => 404 ) ); } $response = $this->prepare_item_for_response( $revision, $request ); return rest_ensure_response( $response ); } /** * Checks if a given request has access to delete a revision. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { $parent = $this->get_parent( $request['parent'] ); if ( is_wp_error( $parent ) ) { return $parent; } if ( ! current_user_can( 'delete_post', $parent->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete revisions of this post.' ), array( 'status' => rest_authorization_required_code() ) ); } $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } $response = $this->get_items_permissions_check( $request ); if ( ! $response || is_wp_error( $response ) ) { return $response; } if ( ! current_user_can( 'delete_post', $revision->ID ) ) { return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this revision.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Deletes a single revision. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $revision = $this->get_revision( $request['id'] ); if ( is_wp_error( $revision ) ) { return $revision; } $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for revisions. if ( ! $force ) { return new WP_Error( 'rest_trash_not_supported', /* translators: %s: force=true */ sprintf( __( "Revisions do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $previous = $this->prepare_item_for_response( $revision, $request ); $result = wp_delete_post( $request['id'], true ); /** * Fires after a revision is deleted via the REST API. * * @since 4.7.0 * * @param WP_Post|false|null $result The revision object (if it was deleted or moved to the Trash successfully) * or false or null (failure). If the revision was moved to the Trash, $result represents * its new state; if it was deleted, $result represents its state before deletion. * @param WP_REST_Request $request The request sent to the API. */ do_action( 'rest_delete_revision', $result, $request ); if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The post cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); return $response; } /** * Determines the allowed query_vars for a get_items() response and prepares * them for WP_Query. * * @since 5.0.0 * * @param array $prepared_args Optional. Prepared WP_Query arguments. Default empty array. * @param WP_REST_Request $request Optional. Full details about the request. * @return array Items query arguments. */ protected function prepare_items_query( $prepared_args = array(), $request = null ) { $query_args = array(); foreach ( $prepared_args as $key => $value ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } // Map to proper WP_Query orderby param. if ( isset( $query_args['orderby'] ) && isset( $request['orderby'] ) ) { $orderby_mappings = array( 'id' => 'ID', 'include' => 'post__in', 'slug' => 'post_name', 'include_slugs' => 'post_name__in', ); if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) { $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ]; } } return $query_args; } /** * Prepares the revision for the REST response. * * @since 4.7.0 * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support. * * @global WP_Post $post Global post object. * * @param WP_Post $item Post revision object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $post = $item; $GLOBALS['post'] = $post; setup_postdata( $post ); // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php */ return apply_filters( 'rest_prepare_revision', new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); $data = array(); if ( in_array( 'author', $fields, true ) ) { $data['author'] = (int) $post->post_author; } if ( in_array( 'date', $fields, true ) ) { $data['date'] = $this->prepare_date_response( $post->post_date_gmt, $post->post_date ); } if ( in_array( 'date_gmt', $fields, true ) ) { $data['date_gmt'] = $this->prepare_date_response( $post->post_date_gmt ); } if ( in_array( 'id', $fields, true ) ) { $data['id'] = $post->ID; } if ( in_array( 'modified', $fields, true ) ) { $data['modified'] = $this->prepare_date_response( $post->post_modified_gmt, $post->post_modified ); } if ( in_array( 'modified_gmt', $fields, true ) ) { $data['modified_gmt'] = $this->prepare_date_response( $post->post_modified_gmt ); } if ( in_array( 'parent', $fields, true ) ) { $data['parent'] = (int) $post->post_parent; } if ( in_array( 'slug', $fields, true ) ) { $data['slug'] = $post->post_name; } if ( in_array( 'guid', $fields, true ) ) { $data['guid'] = array( /** This filter is documented in wp-includes/post-template.php */ 'rendered' => apply_filters( 'get_the_guid', $post->guid, $post->ID ), 'raw' => $post->guid, ); } if ( in_array( 'title', $fields, true ) ) { $data['title'] = array( 'raw' => $post->post_title, 'rendered' => get_the_title( $post->ID ), ); } if ( in_array( 'content', $fields, true ) ) { $data['content'] = array( 'raw' => $post->post_content, /** This filter is documented in wp-includes/post-template.php */ 'rendered' => apply_filters( 'the_content', $post->post_content ), ); } if ( in_array( 'excerpt', $fields, true ) ) { $data['excerpt'] = array( 'raw' => $post->post_excerpt, 'rendered' => $this->prepare_excerpt_response( $post->post_excerpt, $post ), ); } if ( rest_is_field_included( 'meta', $fields ) ) { $data['meta'] = $this->meta->get_value( $post->ID, $request ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( ! empty( $data['parent'] ) ) { $response->add_link( 'parent', rest_url( rest_get_route_for_post( $data['parent'] ) ) ); } /** * Filters a revision returned from the REST API. * * Allows modification of the revision right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Post $post The original revision object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_revision', $response, $post, $request ); } /** * Checks the post_date_gmt or modified_gmt and prepare any post or * modified date for single post output. * * @since 4.7.0 * * @param string $date_gmt GMT publication time. * @param string|null $date Optional. Local publication time. Default null. * @return string|null ISO8601/RFC3339 formatted datetime, otherwise null. */ protected function prepare_date_response( $date_gmt, $date = null ) { if ( '0000-00-00 00:00:00' === $date_gmt ) { return null; } if ( isset( $date ) ) { return mysql_to_rfc3339( $date ); } return mysql_to_rfc3339( $date_gmt ); } /** * Retrieves the revision's schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => "{$this->parent_post_type}-revision", 'type' => 'object', // Base properties for every Revision. 'properties' => array( 'author' => array( 'description' => __( 'The ID for the author of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'date' => array( 'description' => __( "The date the revision was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), 'date_gmt' => array( 'description' => __( 'The date the revision was published, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'guid' => array( 'description' => __( 'GUID for the revision, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'id' => array( 'description' => __( 'Unique identifier for the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'modified' => array( 'description' => __( "The date the revision was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'modified_gmt' => array( 'description' => __( 'The date the revision was last modified, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), 'parent' => array( 'description' => __( 'The ID for the parent of the revision.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the revision unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $parent_schema = $this->parent_controller->get_item_schema(); if ( ! empty( $parent_schema['properties']['title'] ) ) { $schema['properties']['title'] = $parent_schema['properties']['title']; } if ( ! empty( $parent_schema['properties']['content'] ) ) { $schema['properties']['content'] = $parent_schema['properties']['content']; } if ( ! empty( $parent_schema['properties']['excerpt'] ) ) { $schema['properties']['excerpt'] = $parent_schema['properties']['excerpt']; } if ( ! empty( $parent_schema['properties']['guid'] ) ) { $schema['properties']['guid'] = $parent_schema['properties']['guid']; } $schema['properties']['meta'] = $this->meta->get_field_schema(); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; unset( $query_params['per_page']['default'] ); $query_params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), ); $query_params['offset'] = array( 'description' => __( 'Offset the result set by a specific number of items.' ), 'type' => 'integer', ); $query_params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.' ), 'type' => 'string', 'default' => 'date', 'enum' => array( 'date', 'id', 'include', 'relevance', 'slug', 'include_slugs', 'title', ), ); return $query_params; } /** * Checks the post excerpt and prepare it for single post output. * * @since 4.7.0 * * @param string $excerpt The post excerpt. * @param WP_Post $post Post revision object. * @return string Prepared excerpt or empty string. */ protected function prepare_excerpt_response( $excerpt, $post ) { /** This filter is documented in wp-includes/post-template.php */ $excerpt = apply_filters( 'the_excerpt', $excerpt, $post ); if ( empty( $excerpt ) ) { return ''; } return $excerpt; } } <?php /** * Rest Font Collections Controller. * * This file contains the class for the REST API Font Collections Controller. * * @package WordPress * @subpackage REST_API * @since 6.5.0 */ /** * Font Library Controller class. * * @since 6.5.0 */ class WP_REST_Font_Collections_Controller extends WP_REST_Controller { /** * Constructor. * * @since 6.5.0 */ public function __construct() { $this->rest_base = 'font-collections'; $this->namespace = 'wp/v2'; } /** * Registers the routes for the objects of the controller. * * @since 6.5.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<slug>[\/\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Gets the font collections available. * * @since 6.5.0 * * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $collections_all = WP_Font_Library::get_instance()->get_font_collections(); $page = $request['page']; $per_page = $request['per_page']; $total_items = count( $collections_all ); $max_pages = (int) ceil( $total_items / $per_page ); if ( $page > $max_pages && $total_items > 0 ) { return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } $collections_page = array_slice( $collections_all, ( $page - 1 ) * $per_page, $per_page ); $is_head_request = $request->is_method( 'HEAD' ); $items = array(); foreach ( $collections_page as $collection ) { $item = $this->prepare_item_for_response( $collection, $request ); // If there's an error loading a collection, skip it and continue loading valid collections. if ( is_wp_error( $item ) ) { continue; } /* * Skip preparing the response body for HEAD requests. * Cannot exit earlier due to backward compatibility reasons, * as validation occurs in the prepare_item_for_response method. */ if ( $is_head_request ) { continue; } $item = $this->prepare_response_for_collection( $item ); $items[] = $item; } $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $items ); $response->header( 'X-WP-Total', (int) $total_items ); $response->header( 'X-WP-TotalPages', $max_pages ); $request_params = $request->get_query_params(); $collection_url = rest_url( $this->namespace . '/' . $this->rest_base ); $base = add_query_arg( urlencode_deep( $request_params ), $collection_url ); if ( $page > 1 ) { $prev_page = $page - 1; if ( $prev_page > $max_pages ) { $prev_page = $max_pages; } $prev_link = add_query_arg( 'page', $prev_page, $base ); $response->link_header( 'prev', $prev_link ); } if ( $max_pages > $page ) { $next_page = $page + 1; $next_link = add_query_arg( 'page', $next_page, $base ); $response->link_header( 'next', $next_link ); } return $response; } /** * Gets a font collection. * * @since 6.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $slug = $request->get_param( 'slug' ); $collection = WP_Font_Library::get_instance()->get_font_collection( $slug ); if ( ! $collection ) { return new WP_Error( 'rest_font_collection_not_found', __( 'Font collection not found.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $collection, $request ); } /** * Prepare a single collection output for response. * * @since 6.5.0 * * @param WP_Font_Collection $item Font collection object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $item->slug; } // If any data fields are requested, get the collection data. $data_fields = array( 'name', 'description', 'font_families', 'categories' ); if ( ! empty( array_intersect( $fields, $data_fields ) ) ) { $collection_data = $item->get_data(); if ( is_wp_error( $collection_data ) ) { $collection_data->add_data( array( 'status' => 500 ) ); return $collection_data; } /** * Don't prepare the response body for HEAD requests. * Can't exit at the beginning of the method due to the potential need to return a WP_Error object. */ if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } foreach ( $data_fields as $field ) { if ( rest_is_field_included( $field, $fields ) ) { $data[ $field ] = $collection_data[ $field ]; } } } /** * Don't prepare the response body for HEAD requests. * Can't exit at the beginning of the method due to the potential need to return a WP_Error object. */ if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $response->data = $this->add_additional_fields_to_object( $response->data, $request ); $response->data = $this->filter_response_by_context( $response->data, $context ); /** * Filters the font collection data for a REST API response. * * @since 6.5.0 * * @param WP_REST_Response $response The response object. * @param WP_Font_Collection $item The font collection object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_font_collection', $response, $item, $request ); } /** * Retrieves the font collection's schema, conforming to JSON Schema. * * @since 6.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'font-collection', 'type' => 'object', 'properties' => array( 'slug' => array( 'description' => __( 'Unique identifier for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The name for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'description' => array( 'description' => __( 'The description for the font collection.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'font_families' => array( 'description' => __( 'The font families for the font collection.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), ), 'categories' => array( 'description' => __( 'The categories for the font collection.' ), 'type' => 'array', 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Prepares links for the request. * * @since 6.5.0 * * @param WP_Font_Collection $collection Font collection data * @return array Links for the given font collection. */ protected function prepare_links( $collection ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $collection->slug ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); } /** * Retrieves the search params for the font collections. * * @since 6.5.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); unset( $query_params['search'] ); /** * Filters REST API collection parameters for the font collections controller. * * @since 6.5.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_font_collections_collection_params', $query_params ); } /** * Checks whether the user has permissions to use the Fonts Collections. * * @since 6.5.0 * * @return true|WP_Error True if the request has write access for the item, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable if ( current_user_can( 'edit_theme_options' ) ) { return true; } return new WP_Error( 'rest_cannot_read', __( 'Sorry, you are not allowed to access font collections.' ), array( 'status' => rest_authorization_required_code(), ) ); } } <?php /** * REST API: WP_REST_Themes_Controller class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Core class used to manage themes via the REST API. * * @since 5.0.0 * * @see WP_REST_Controller */ class WP_REST_Themes_Controller extends WP_REST_Controller { /** * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ const PATTERN = '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?'; /** * Constructor. * * @since 5.0.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'themes'; } /** * Registers the routes for themes. * * @since 5.0.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/(?P<stylesheet>%s)', $this->rest_base, self::PATTERN ), array( 'args' => array( 'stylesheet' => array( 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_stylesheet_callback' ), ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Sanitize the stylesheet to decode endpoint. * * @since 5.9.0 * * @param string $stylesheet The stylesheet name. * @return string Sanitized stylesheet. */ public function _sanitize_stylesheet_callback( $stylesheet ) { return urldecode( $stylesheet ); } /** * Checks if a given request has access to read the theme. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. */ public function get_items_permissions_check( $request ) { if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) { return true; } $registered = $this->get_collection_params(); if ( isset( $registered['status'], $request['status'] ) && is_array( $request['status'] ) && array( 'active' ) === $request['status'] ) { return $this->check_read_active_theme_permission(); } return new WP_Error( 'rest_cannot_view_themes', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Checks if a given request has access to read the theme. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. */ public function get_item_permissions_check( $request ) { if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) { return true; } $wp_theme = wp_get_theme( $request['stylesheet'] ); $current_theme = wp_get_theme(); if ( $this->is_same_theme( $wp_theme, $current_theme ) ) { return $this->check_read_active_theme_permission(); } return new WP_Error( 'rest_cannot_view_themes', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Checks if a theme can be read. * * @since 5.7.0 * * @return true|WP_Error True if the theme can be read, WP_Error object otherwise. */ protected function check_read_active_theme_permission() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view_active_theme', __( 'Sorry, you are not allowed to view the active theme.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Retrieves a single theme. * * @since 5.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $wp_theme = wp_get_theme( $request['stylesheet'] ); if ( ! $wp_theme->exists() ) { return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $wp_theme, $request ); return rest_ensure_response( $data ); } /** * Retrieves a collection of themes. * * @since 5.0.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { $themes = array(); $active_themes = wp_get_themes(); $current_theme = wp_get_theme(); $status = $request['status']; foreach ( $active_themes as $theme ) { $theme_status = ( $this->is_same_theme( $theme, $current_theme ) ) ? 'active' : 'inactive'; if ( is_array( $status ) && ! in_array( $theme_status, $status, true ) ) { continue; } $prepared = $this->prepare_item_for_response( $theme, $request ); $themes[] = $this->prepare_response_for_collection( $prepared ); } $response = rest_ensure_response( $themes ); $response->header( 'X-WP-Total', count( $themes ) ); $response->header( 'X-WP-TotalPages', 1 ); return $response; } /** * Prepares a single theme output for response. * * @since 5.0.0 * @since 5.9.0 Renamed `$theme` to `$item` to match parent class for PHP 8 named parameter support. * @since 6.6.0 Added `stylesheet_uri` and `template_uri` fields. * * @param WP_Theme $item Theme object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $theme = $item; $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'stylesheet', $fields ) ) { $data['stylesheet'] = $theme->get_stylesheet(); } if ( rest_is_field_included( 'template', $fields ) ) { /** * Use the get_template() method, not the 'Template' header, for finding the template. * The 'Template' header is only good for what was written in the style.css, while * get_template() takes into account where WordPress actually located the theme and * whether it is actually valid. */ $data['template'] = $theme->get_template(); } $plain_field_mappings = array( 'requires_php' => 'RequiresPHP', 'requires_wp' => 'RequiresWP', 'textdomain' => 'TextDomain', 'version' => 'Version', ); foreach ( $plain_field_mappings as $field => $header ) { if ( rest_is_field_included( $field, $fields ) ) { $data[ $field ] = $theme->get( $header ); } } if ( rest_is_field_included( 'screenshot', $fields ) ) { // Using $theme->get_screenshot() with no args to get absolute URL. $data['screenshot'] = $theme->get_screenshot() ? $theme->get_screenshot() : ''; } $rich_field_mappings = array( 'author' => 'Author', 'author_uri' => 'AuthorURI', 'description' => 'Description', 'name' => 'Name', 'tags' => 'Tags', 'theme_uri' => 'ThemeURI', ); foreach ( $rich_field_mappings as $field => $header ) { if ( rest_is_field_included( "{$field}.raw", $fields ) ) { $data[ $field ]['raw'] = $theme->display( $header, false, true ); } if ( rest_is_field_included( "{$field}.rendered", $fields ) ) { $data[ $field ]['rendered'] = $theme->display( $header ); } } $current_theme = wp_get_theme(); if ( rest_is_field_included( 'status', $fields ) ) { $data['status'] = ( $this->is_same_theme( $theme, $current_theme ) ) ? 'active' : 'inactive'; } if ( rest_is_field_included( 'theme_supports', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { foreach ( get_registered_theme_features() as $feature => $config ) { if ( ! is_array( $config['show_in_rest'] ) ) { continue; } $name = $config['show_in_rest']['name']; if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) { continue; } if ( ! current_theme_supports( $feature ) ) { $data['theme_supports'][ $name ] = $config['show_in_rest']['schema']['default']; continue; } $support = get_theme_support( $feature ); if ( isset( $config['show_in_rest']['prepare_callback'] ) ) { $prepare = $config['show_in_rest']['prepare_callback']; } else { $prepare = array( $this, 'prepare_theme_support' ); } $prepared = $prepare( $support, $config, $feature, $request ); if ( is_wp_error( $prepared ) ) { continue; } $data['theme_supports'][ $name ] = $prepared; } } if ( rest_is_field_included( 'is_block_theme', $fields ) ) { $data['is_block_theme'] = $theme->is_block_theme(); } if ( rest_is_field_included( 'stylesheet_uri', $fields ) ) { if ( $this->is_same_theme( $theme, $current_theme ) ) { $data['stylesheet_uri'] = get_stylesheet_directory_uri(); } else { $data['stylesheet_uri'] = $theme->get_stylesheet_directory_uri(); } } if ( rest_is_field_included( 'template_uri', $fields ) ) { if ( $this->is_same_theme( $theme, $current_theme ) ) { $data['template_uri'] = get_template_directory_uri(); } else { $data['template_uri'] = $theme->get_template_directory_uri(); } } if ( rest_is_field_included( 'default_template_types', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { $default_template_types = array(); foreach ( get_default_block_template_types() as $slug => $template_type ) { $template_type['slug'] = (string) $slug; $default_template_types[] = $template_type; } $data['default_template_types'] = $default_template_types; } if ( rest_is_field_included( 'default_template_part_areas', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) { $data['default_template_part_areas'] = get_allowed_block_template_part_areas(); } $data = $this->add_additional_fields_to_object( $data, $request ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $theme ) ); } /** * Filters theme data returned from the REST API. * * @since 5.0.0 * * @param WP_REST_Response $response The response object. * @param WP_Theme $theme Theme object used to create response. * @param WP_REST_Request $request Request object. */ return apply_filters( 'rest_prepare_theme', $response, $theme, $request ); } /** * Prepares links for the request. * * @since 5.7.0 * * @param WP_Theme $theme Theme data. * @return array Links for the given block type. */ protected function prepare_links( $theme ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $theme->get_stylesheet() ) ), ), 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), ); if ( $this->is_same_theme( $theme, wp_get_theme() ) ) { // This creates a record for the active theme if not existent. $id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id(); } else { $user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme ); $id = isset( $user_cpt['ID'] ) ? $user_cpt['ID'] : null; } if ( $id ) { $links['https://api.w.org/user-global-styles'] = array( 'href' => rest_url( 'wp/v2/global-styles/' . $id ), ); } return $links; } /** * Helper function to compare two themes. * * @since 5.7.0 * * @param WP_Theme $theme_a First theme to compare. * @param WP_Theme $theme_b Second theme to compare. * @return bool */ protected function is_same_theme( $theme_a, $theme_b ) { return $theme_a->get_stylesheet() === $theme_b->get_stylesheet(); } /** * Prepares the theme support value for inclusion in the REST API response. * * @since 5.5.0 * * @param mixed $support The raw value from get_theme_support(). * @param array $args The feature's registration args. * @param string $feature The feature name. * @param WP_REST_Request $request The request object. * @return mixed The prepared support value. */ protected function prepare_theme_support( $support, $args, $feature, $request ) { $schema = $args['show_in_rest']['schema']; if ( 'boolean' === $schema['type'] ) { return true; } if ( is_array( $support ) && ! $args['variadic'] ) { $support = $support[0]; } return rest_sanitize_value_from_schema( $support, $schema ); } /** * Retrieves the theme's schema, conforming to JSON Schema. * * @since 5.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'theme', 'type' => 'object', 'properties' => array( 'stylesheet' => array( 'description' => __( 'The theme\'s stylesheet. This uniquely identifies the theme.' ), 'type' => 'string', 'readonly' => true, ), 'stylesheet_uri' => array( 'description' => __( 'The uri for the theme\'s stylesheet directory.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'template' => array( 'description' => __( 'The theme\'s template. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet.' ), 'type' => 'string', 'readonly' => true, ), 'template_uri' => array( 'description' => __( 'The uri for the theme\'s template directory. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet directory.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'author' => array( 'description' => __( 'The theme author.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme author\'s name, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'HTML for the theme author, transformed for display.' ), 'type' => 'string', ), ), ), 'author_uri' => array( 'description' => __( 'The website of the theme author.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The website of the theme author, as found in the theme header.' ), 'type' => 'string', 'format' => 'uri', ), 'rendered' => array( 'description' => __( 'The website of the theme author, transformed for display.' ), 'type' => 'string', 'format' => 'uri', ), ), ), 'description' => array( 'description' => __( 'A description of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme description, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The theme description, transformed for display.' ), 'type' => 'string', ), ), ), 'is_block_theme' => array( 'description' => __( 'Whether the theme is a block-based theme.' ), 'type' => 'boolean', 'readonly' => true, ), 'name' => array( 'description' => __( 'The name of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme name, as found in the theme header.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The theme name, transformed for display.' ), 'type' => 'string', ), ), ), 'requires_php' => array( 'description' => __( 'The minimum PHP version required for the theme to work.' ), 'type' => 'string', 'readonly' => true, ), 'requires_wp' => array( 'description' => __( 'The minimum WordPress version required for the theme to work.' ), 'type' => 'string', 'readonly' => true, ), 'screenshot' => array( 'description' => __( 'The theme\'s screenshot URL.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, ), 'tags' => array( 'description' => __( 'Tags indicating styles and features of the theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The theme tags, as found in the theme header.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), ), 'rendered' => array( 'description' => __( 'The theme tags, transformed for display.' ), 'type' => 'string', ), ), ), 'textdomain' => array( 'description' => __( 'The theme\'s text domain.' ), 'type' => 'string', 'readonly' => true, ), 'theme_supports' => array( 'description' => __( 'Features supported by this theme.' ), 'type' => 'object', 'readonly' => true, 'properties' => array(), ), 'theme_uri' => array( 'description' => __( 'The URI of the theme\'s webpage.' ), 'type' => 'object', 'readonly' => true, 'properties' => array( 'raw' => array( 'description' => __( 'The URI of the theme\'s webpage, as found in the theme header.' ), 'type' => 'string', 'format' => 'uri', ), 'rendered' => array( 'description' => __( 'The URI of the theme\'s webpage, transformed for display.' ), 'type' => 'string', 'format' => 'uri', ), ), ), 'version' => array( 'description' => __( 'The theme\'s current version.' ), 'type' => 'string', 'readonly' => true, ), 'status' => array( 'description' => __( 'A named status for the theme.' ), 'type' => 'string', 'enum' => array( 'inactive', 'active' ), ), 'default_template_types' => array( 'description' => __( 'A list of default template types.' ), 'type' => 'array', 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'slug' => array( 'type' => 'string', ), 'title' => array( 'type' => 'string', ), 'description' => array( 'type' => 'string', ), ), ), ), 'default_template_part_areas' => array( 'description' => __( 'A list of allowed area values for template parts.' ), 'type' => 'array', 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'area' => array( 'type' => 'string', ), 'label' => array( 'type' => 'string', ), 'description' => array( 'type' => 'string', ), 'icon' => array( 'type' => 'string', ), 'area_tag' => array( 'type' => 'string', ), ), ), ), ), ); foreach ( get_registered_theme_features() as $feature => $config ) { if ( ! is_array( $config['show_in_rest'] ) ) { continue; } $name = $config['show_in_rest']['name']; $schema['properties']['theme_supports']['properties'][ $name ] = $config['show_in_rest']['schema']; } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the search params for the themes collection. * * @since 5.0.0 * * @return array Collection parameters. */ public function get_collection_params() { $query_params = array( 'status' => array( 'description' => __( 'Limit result set to themes assigned one or more statuses.' ), 'type' => 'array', 'items' => array( 'enum' => array( 'active', 'inactive' ), 'type' => 'string', ), ), ); /** * Filters REST API collection parameters for the themes controller. * * @since 5.0.0 * * @param array $query_params JSON Schema-formatted collection parameters. */ return apply_filters( 'rest_themes_collection_params', $query_params ); } /** * Sanitizes and validates the list of theme status. * * @since 5.0.0 * @deprecated 5.7.0 * * @param string|array $statuses One or more theme statuses. * @param WP_REST_Request $request Full details about the request. * @param string $parameter Additional parameter to pass to validation. * @return array|WP_Error A list of valid statuses, otherwise WP_Error object. */ public function sanitize_theme_status( $statuses, $request, $parameter ) { _deprecated_function( __METHOD__, '5.7.0' ); $statuses = wp_parse_slug_list( $statuses ); foreach ( $statuses as $status ) { $result = rest_validate_request_arg( $status, $request, $parameter ); if ( is_wp_error( $result ) ) { return $result; } } return $statuses; } } <?php /** * REST API: WP_REST_Site_Health_Controller class * * @package WordPress * @subpackage REST_API * @since 5.6.0 */ /** * Core class for interacting with Site Health tests. * * @since 5.6.0 * * @see WP_REST_Controller */ class WP_REST_Site_Health_Controller extends WP_REST_Controller { /** * An instance of the site health class. * * @since 5.6.0 * * @var WP_Site_Health */ private $site_health; /** * Site Health controller constructor. * * @since 5.6.0 * * @param WP_Site_Health $site_health An instance of the site health class. */ public function __construct( $site_health ) { $this->namespace = 'wp-site-health/v1'; $this->rest_base = 'tests'; $this->site_health = $site_health; } /** * Registers API routes. * * @since 5.6.0 * @since 6.1.0 Adds page-cache async test. * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'background-updates' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_background_updates' ), 'permission_callback' => function () { return $this->validate_request_permission( 'background_updates' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'loopback-requests' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_loopback_requests' ), 'permission_callback' => function () { return $this->validate_request_permission( 'loopback_requests' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'https-status' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_https_status' ), 'permission_callback' => function () { return $this->validate_request_permission( 'https_status' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'dotorg-communication' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_dotorg_communication' ), 'permission_callback' => function () { return $this->validate_request_permission( 'dotorg_communication' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'authorization-header' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_authorization_header' ), 'permission_callback' => function () { return $this->validate_request_permission( 'authorization_header' ); }, ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, sprintf( '/%s', 'directory-sizes' ), array( 'methods' => 'GET', 'callback' => array( $this, 'get_directory_sizes' ), 'permission_callback' => function () { return $this->validate_request_permission( 'directory_sizes' ) && ! is_multisite(); }, ) ); register_rest_route( $this->namespace, sprintf( '/%s/%s', $this->rest_base, 'page-cache' ), array( array( 'methods' => 'GET', 'callback' => array( $this, 'test_page_cache' ), 'permission_callback' => function () { return $this->validate_request_permission( 'page_cache' ); }, ), ) ); } /** * Validates if the current user can request this REST endpoint. * * @since 5.6.0 * * @param string $check The endpoint check being ran. * @return bool */ protected function validate_request_permission( $check ) { $default_capability = 'view_site_health_checks'; /** * Filters the capability needed to run a given Site Health check. * * @since 5.6.0 * * @param string $default_capability The default capability required for this check. * @param string $check The Site Health check being performed. */ $capability = apply_filters( "site_health_test_rest_capability_{$check}", $default_capability, $check ); return current_user_can( $capability ); } /** * Checks if background updates work as expected. * * @since 5.6.0 * * @return array */ public function test_background_updates() { $this->load_admin_textdomain(); return $this->site_health->get_test_background_updates(); } /** * Checks that the site can reach the WordPress.org API. * * @since 5.6.0 * * @return array */ public function test_dotorg_communication() { $this->load_admin_textdomain(); return $this->site_health->get_test_dotorg_communication(); } /** * Checks that loopbacks can be performed. * * @since 5.6.0 * * @return array */ public function test_loopback_requests() { $this->load_admin_textdomain(); return $this->site_health->get_test_loopback_requests(); } /** * Checks that the site's frontend can be accessed over HTTPS. * * @since 5.7.0 * * @return array */ public function test_https_status() { $this->load_admin_textdomain(); return $this->site_health->get_test_https_status(); } /** * Checks that the authorization header is valid. * * @since 5.6.0 * * @return array */ public function test_authorization_header() { $this->load_admin_textdomain(); return $this->site_health->get_test_authorization_header(); } /** * Checks that full page cache is active. * * @since 6.1.0 * * @return array The test result. */ public function test_page_cache() { $this->load_admin_textdomain(); return $this->site_health->get_test_page_cache(); } /** * Gets the current directory sizes for this install. * * @since 5.6.0 * * @return array|WP_Error */ public function get_directory_sizes() { if ( ! class_exists( 'WP_Debug_Data' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-debug-data.php'; } $this->load_admin_textdomain(); $sizes_data = WP_Debug_Data::get_sizes(); $all_sizes = array( 'raw' => 0 ); foreach ( $sizes_data as $name => $value ) { $name = sanitize_text_field( $name ); $data = array(); if ( isset( $value['size'] ) ) { if ( is_string( $value['size'] ) ) { $data['size'] = sanitize_text_field( $value['size'] ); } else { $data['size'] = (int) $value['size']; } } if ( isset( $value['debug'] ) ) { if ( is_string( $value['debug'] ) ) { $data['debug'] = sanitize_text_field( $value['debug'] ); } else { $data['debug'] = (int) $value['debug']; } } if ( ! empty( $value['raw'] ) ) { $data['raw'] = (int) $value['raw']; } $all_sizes[ $name ] = $data; } if ( isset( $all_sizes['total_size']['debug'] ) && 'not available' === $all_sizes['total_size']['debug'] ) { return new WP_Error( 'not_available', __( 'Directory sizes could not be returned.' ), array( 'status' => 500 ) ); } return $all_sizes; } /** * Loads the admin textdomain for Site Health tests. * * The {@see WP_Site_Health} class is defined in WP-Admin, while the REST API operates in a front-end context. * This means that the translations for Site Health won't be loaded by default in {@see load_default_textdomain()}. * * @since 5.6.0 */ protected function load_admin_textdomain() { // Accounts for inner REST API requests in the admin. if ( ! is_admin() ) { $locale = determine_locale(); load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo", $locale ); } } /** * Gets the schema for each site health test. * * @since 5.6.0 * * @return array The test schema. */ public function get_item_schema() { if ( $this->schema ) { return $this->schema; } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'wp-site-health-test', 'type' => 'object', 'properties' => array( 'test' => array( 'type' => 'string', 'description' => __( 'The name of the test being run.' ), 'readonly' => true, ), 'label' => array( 'type' => 'string', 'description' => __( 'A label describing the test.' ), 'readonly' => true, ), 'status' => array( 'type' => 'string', 'description' => __( 'The status of the test.' ), 'enum' => array( 'good', 'recommended', 'critical' ), 'readonly' => true, ), 'badge' => array( 'type' => 'object', 'description' => __( 'The category this test is grouped in.' ), 'properties' => array( 'label' => array( 'type' => 'string', 'readonly' => true, ), 'color' => array( 'type' => 'string', 'enum' => array( 'blue', 'orange', 'red', 'green', 'purple', 'gray' ), 'readonly' => true, ), ), 'readonly' => true, ), 'description' => array( 'type' => 'string', 'description' => __( 'A more descriptive explanation of what the test looks for, and why it is important for the user.' ), 'readonly' => true, ), 'actions' => array( 'type' => 'string', 'description' => __( 'HTML containing an action to direct the user to where they can resolve the issue.' ), 'readonly' => true, ), ), ); return $this->schema; } } <?php /** * REST API: WP_REST_Menus_Controller class * * @package WordPress * @subpackage REST_API * @since 5.9.0 */ /** * Core class used to managed menu terms associated via the REST API. * * @since 5.9.0 * * @see WP_REST_Controller */ class WP_REST_Menus_Controller extends WP_REST_Terms_Controller { /** * Checks if a request has access to read menus. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return bool|WP_Error True if the request has read access, otherwise false or WP_Error object. */ public function get_items_permissions_check( $request ) { $has_permission = parent::get_items_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } /** * Checks if a request has access to read or edit the specified menu. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object. */ public function get_item_permissions_check( $request ) { $has_permission = parent::get_item_permissions_check( $request ); if ( true !== $has_permission ) { return $has_permission; } return $this->check_has_read_only_access( $request ); } /** * Gets the term, if the ID is valid. * * @since 5.9.0 * * @param int $id Supplied ID. * @return WP_Term|WP_Error Term object if ID is valid, WP_Error otherwise. */ protected function get_term( $id ) { $term = parent::get_term( $id ); if ( is_wp_error( $term ) ) { return $term; } $nav_term = wp_get_nav_menu_object( $term ); $nav_term->auto_add = $this->get_menu_auto_add( $nav_term->term_id ); return $nav_term; } /** * Checks whether the current user has read permission for the endpoint. * * This allows for any user that can `edit_theme_options` or edit any REST API available post type. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the current user has permission, WP_Error object otherwise. */ protected function check_has_read_only_access( $request ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-menu-items-controller.php */ $read_only_access = apply_filters( 'rest_menu_read_access', false, $request, $this ); if ( $read_only_access ) { return true; } if ( current_user_can( 'edit_theme_options' ) ) { return true; } if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view menus.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Prepares a single term output for response. * * @since 5.9.0 * * @param WP_Term $term Term object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $term, $request ) { $nav_menu = wp_get_nav_menu_object( $term ); $response = parent::prepare_item_for_response( $nav_menu, $request ); $fields = $this->get_fields_for_response( $request ); $data = $response->get_data(); if ( rest_is_field_included( 'locations', $fields ) ) { $data['locations'] = $this->get_menu_locations( $nav_menu->term_id ); } if ( rest_is_field_included( 'auto_add', $fields ) ) { $data['auto_add'] = $this->get_menu_auto_add( $nav_menu->term_id ); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $term ) ); } /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $term, $request ); } /** * Prepares links for the request. * * @since 5.9.0 * * @param WP_Term $term Term object. * @return array Links for the given term. */ protected function prepare_links( $term ) { $links = parent::prepare_links( $term ); $locations = $this->get_menu_locations( $term->term_id ); foreach ( $locations as $location ) { $url = rest_url( sprintf( 'wp/v2/menu-locations/%s', $location ) ); $links['https://api.w.org/menu-location'][] = array( 'href' => $url, 'embeddable' => true, ); } return $links; } /** * Prepares a single term for create or update. * * @since 5.9.0 * * @param WP_REST_Request $request Request object. * @return object Prepared term data. */ public function prepare_item_for_database( $request ) { $prepared_term = parent::prepare_item_for_database( $request ); $schema = $this->get_item_schema(); if ( isset( $request['name'] ) && ! empty( $schema['properties']['name'] ) ) { $prepared_term->{'menu-name'} = $request['name']; } return $prepared_term; } /** * Creates a single term in a taxonomy. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = wp_get_nav_menu_object( (int) $request['parent'] ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); $term = wp_update_nav_menu_object( 0, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $term ) ) { /* * If we're going to inform the client that the term already exists, * give them the identifier for future use. */ if ( in_array( 'menu_exists', $term->get_error_codes(), true ) ) { $existing_term = get_term_by( 'name', $prepared_term->{'menu-name'}, $this->taxonomy ); $term->add_data( $existing_term->term_id, 'menu_exists' ); $term->add_data( array( 'status' => 400, 'term_id' => $existing_term->term_id, ) ); } else { $term->add_data( array( 'status' => 400 ) ); } return $term; } $term = $this->get_term( $term ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_insert_{$this->taxonomy}", $term, $request, true ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $locations_update = $this->handle_locations( $term->term_id, $request ); if ( is_wp_error( $locations_update ) ) { return $locations_update; } $this->handle_auto_add( $term->term_id, $request ); $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'view' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, true ); $response = $this->prepare_item_for_response( $term, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); $response->header( 'Location', rest_url( $this->namespace . '/' . $this->rest_base . '/' . $term->term_id ) ); return $response; } /** * Updates a single term from a taxonomy. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); } } $prepared_term = $this->prepare_item_for_database( $request ); // Only update the term if we have something to update. if ( ! empty( $prepared_term ) ) { if ( ! isset( $prepared_term->{'menu-name'} ) ) { // wp_update_nav_menu_object() requires that the menu-name is always passed. $prepared_term->{'menu-name'} = $term->name; } $update = wp_update_nav_menu_object( $term->term_id, wp_slash( (array) $prepared_term ) ); if ( is_wp_error( $update ) ) { return $update; } } $term = get_term( $term->term_id, $this->taxonomy ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_insert_{$this->taxonomy}", $term, $request, false ); $schema = $this->get_item_schema(); if ( ! empty( $schema['properties']['meta'] ) && isset( $request['meta'] ) ) { $meta_update = $this->meta->update_value( $request['meta'], $term->term_id ); if ( is_wp_error( $meta_update ) ) { return $meta_update; } } $locations_update = $this->handle_locations( $term->term_id, $request ); if ( is_wp_error( $locations_update ) ) { return $locations_update; } $this->handle_auto_add( $term->term_id, $request ); $fields_update = $this->update_additional_fields_for_object( $term, $request ); if ( is_wp_error( $fields_update ) ) { return $fields_update; } $request->set_param( 'context', 'view' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, false ); $response = $this->prepare_item_for_response( $term, $request ); return rest_ensure_response( $response ); } /** * Deletes a single term from a taxonomy. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { $term = $this->get_term( $request['id'] ); if ( is_wp_error( $term ) ) { return $term; } // We don't support trashing for terms. if ( ! $request['force'] ) { /* translators: %s: force=true */ return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Menus do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); } $request->set_param( 'context', 'view' ); $previous = $this->prepare_item_for_response( $term, $request ); $result = wp_delete_nav_menu( $term ); if ( ! $result || is_wp_error( $result ) ) { return new WP_Error( 'rest_cannot_delete', __( 'The menu cannot be deleted.' ), array( 'status' => 500 ) ); } $response = new WP_REST_Response(); $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data(), ) ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_delete_{$this->taxonomy}", $term, $response, $request ); return $response; } /** * Returns the value of a menu's auto_add setting. * * @since 5.9.0 * * @param int $menu_id The menu id to query. * @return bool The value of auto_add. */ protected function get_menu_auto_add( $menu_id ) { $nav_menu_option = (array) get_option( 'nav_menu_options', array( 'auto_add' => array() ) ); return in_array( $menu_id, $nav_menu_option['auto_add'], true ); } /** * Updates the menu's auto add from a REST request. * * @since 5.9.0 * * @param int $menu_id The menu id to update. * @param WP_REST_Request $request Full details about the request. * @return bool True if the auto add setting was successfully updated. */ protected function handle_auto_add( $menu_id, $request ) { if ( ! isset( $request['auto_add'] ) ) { return true; } $nav_menu_option = (array) get_option( 'nav_menu_options', array( 'auto_add' => array() ) ); if ( ! isset( $nav_menu_option['auto_add'] ) ) { $nav_menu_option['auto_add'] = array(); } $auto_add = $request['auto_add']; $i = array_search( $menu_id, $nav_menu_option['auto_add'], true ); if ( $auto_add && false === $i ) { $nav_menu_option['auto_add'][] = $menu_id; } elseif ( ! $auto_add && false !== $i ) { array_splice( $nav_menu_option['auto_add'], $i, 1 ); } $update = update_option( 'nav_menu_options', $nav_menu_option ); /** This action is documented in wp-includes/nav-menu.php */ do_action( 'wp_update_nav_menu', $menu_id ); return $update; } /** * Returns the names of the locations assigned to the menu. * * @since 5.9.0 * * @param int $menu_id The menu id. * @return string[] The locations assigned to the menu. */ protected function get_menu_locations( $menu_id ) { $locations = get_nav_menu_locations(); $menu_locations = array(); foreach ( $locations as $location => $assigned_menu_id ) { if ( $menu_id === $assigned_menu_id ) { $menu_locations[] = $location; } } return $menu_locations; } /** * Updates the menu's locations from a REST request. * * @since 5.9.0 * * @param int $menu_id The menu id to update. * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True on success, a WP_Error on an error updating any of the locations. */ protected function handle_locations( $menu_id, $request ) { if ( ! isset( $request['locations'] ) ) { return true; } $menu_locations = get_registered_nav_menus(); $menu_locations = array_keys( $menu_locations ); $new_locations = array(); foreach ( $request['locations'] as $location ) { if ( ! in_array( $location, $menu_locations, true ) ) { return new WP_Error( 'rest_invalid_menu_location', __( 'Invalid menu location.' ), array( 'status' => 400, 'location' => $location, ) ); } $new_locations[ $location ] = $menu_id; } $assigned_menu = get_nav_menu_locations(); foreach ( $assigned_menu as $location => $term_id ) { if ( $term_id === $menu_id ) { unset( $assigned_menu[ $location ] ); } } $new_assignments = array_merge( $assigned_menu, $new_locations ); set_theme_mod( 'nav_menu_locations', $new_assignments ); return true; } /** * Retrieves the term's schema, conforming to JSON Schema. * * @since 5.9.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = parent::get_item_schema(); unset( $schema['properties']['count'], $schema['properties']['link'], $schema['properties']['taxonomy'] ); $schema['properties']['locations'] = array( 'description' => __( 'The locations assigned to the menu.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'validate_callback' => static function ( $locations, $request, $param ) { $valid = rest_validate_request_arg( $locations, $request, $param ); if ( true !== $valid ) { return $valid; } $locations = rest_sanitize_request_arg( $locations, $request, $param ); foreach ( $locations as $location ) { if ( ! array_key_exists( $location, get_registered_nav_menus() ) ) { return new WP_Error( 'rest_invalid_menu_location', __( 'Invalid menu location.' ), array( 'location' => $location, ) ); } } return true; }, ), ); $schema['properties']['auto_add'] = array( 'description' => __( 'Whether to automatically add top level pages to this menu.' ), 'context' => array( 'view', 'edit' ), 'type' => 'boolean', ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * WP_REST_Navigation_Fallback_Controller class * * REST Controller to create/fetch a fallback Navigation Menu. * * @package WordPress * @subpackage REST_API * @since 6.3.0 */ /** * REST Controller to fetch a fallback Navigation Block Menu. If needed it creates one. * * @since 6.3.0 */ class WP_REST_Navigation_Fallback_Controller extends WP_REST_Controller { /** * The Post Type for the Controller * * @since 6.3.0 * * @var string */ private $post_type; /** * Constructs the controller. * * @since 6.3.0 */ public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'navigation-fallback'; $this->post_type = 'wp_navigation'; } /** * Registers the controllers routes. * * @since 6.3.0 */ public function register_routes() { // Lists a single nav item based on the given id or slug. register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ), ), 'schema' => array( $this, 'get_item_schema' ), ) ); } /** * Checks if a given request has access to read fallbacks. * * @since 6.3.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $post_type = get_post_type_object( $this->post_type ); // Getting fallbacks requires creating and reading `wp_navigation` posts. if ( ! current_user_can( $post_type->cap->create_posts ) || ! current_user_can( 'edit_theme_options' ) || ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create Navigation Menus as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( $post_type->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit Navigation Menus as this user.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Gets the most appropriate fallback Navigation Menu. * * @since 6.3.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $post = WP_Navigation_Fallback::get_fallback(); if ( empty( $post ) ) { return rest_ensure_response( new WP_Error( 'no_fallback_menu', __( 'No fallback menu found.' ), array( 'status' => 404 ) ) ); } $response = $this->prepare_item_for_response( $post, $request ); return $response; } /** * Retrieves the fallbacks' schema, conforming to JSON Schema. * * @since 6.3.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'navigation-fallback', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'The unique identifier for the Navigation Menu.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Matches the post data to the schema we want. * * @since 6.3.0 * * @param WP_Post $item The wp_navigation Post object whose response is being prepared. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response The response data. */ public function prepare_item_for_response( $item, $request ) { $data = array(); $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = (int) $item->ID; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $item ); $response->add_links( $links ); } return $response; } /** * Prepares the links for the request. * * @since 6.3.0 * * @param WP_Post $post the Navigation Menu post object. * @return array Links for the given request. */ private function prepare_links( $post ) { return array( 'self' => array( 'href' => rest_url( rest_get_route_for_post( $post->ID ) ), 'embeddable' => true, ), ); } } <?php /** * REST API: WP_REST_URL_Details_Controller class * * @package WordPress * @subpackage REST_API * @since 5.9.0 */ /** * Controller which provides REST endpoint for retrieving information * from a remote site's HTML response. * * @since 5.9.0 * * @see WP_REST_Controller */ class WP_REST_URL_Details_Controller extends WP_REST_Controller { /** * Constructs the controller. * * @since 5.9.0 */ public function __construct() { $this->namespace = 'wp-block-editor/v1'; $this->rest_base = 'url-details'; } /** * Registers the necessary REST API routes. * * @since 5.9.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'parse_url_details' ), 'args' => array( 'url' => array( 'required' => true, 'description' => __( 'The URL to process.' ), 'validate_callback' => 'wp_http_validate_url', 'sanitize_callback' => 'sanitize_url', 'type' => 'string', 'format' => 'uri', ), ), 'permission_callback' => array( $this, 'permissions_check' ), 'schema' => array( $this, 'get_public_item_schema' ), ), ) ); } /** * Retrieves the item's schema, conforming to JSON Schema. * * @since 5.9.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'url-details', 'type' => 'object', 'properties' => array( 'title' => array( 'description' => sprintf( /* translators: %s: HTML title tag. */ __( 'The contents of the %s element from the URL.' ), '<title>' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'icon' => array( 'description' => sprintf( /* translators: %s: HTML link tag. */ __( 'The favicon image link of the %s element from the URL.' ), '<link rel="icon">' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'description' => array( 'description' => sprintf( /* translators: %s: HTML meta tag. */ __( 'The content of the %s element from the URL.' ), '<meta name="description">' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'image' => array( 'description' => sprintf( /* translators: 1: HTML meta tag, 2: HTML meta tag. */ __( 'The Open Graph image link of the %1$s or %2$s element from the URL.' ), '<meta property="og:image">', '<meta property="og:image:url">' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the contents of the title tag from the HTML response. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error The parsed details as a response object. WP_Error if there are errors. */ public function parse_url_details( $request ) { $url = untrailingslashit( $request['url'] ); if ( empty( $url ) ) { return new WP_Error( 'rest_invalid_url', __( 'Invalid URL' ), array( 'status' => 404 ) ); } // Transient per URL. $cache_key = $this->build_cache_key_for_url( $url ); // Attempt to retrieve cached response. $cached_response = $this->get_cache( $cache_key ); if ( ! empty( $cached_response ) ) { $remote_url_response = $cached_response; } else { $remote_url_response = $this->get_remote_url( $url ); // Exit if we don't have a valid body or it's empty. if ( is_wp_error( $remote_url_response ) || empty( $remote_url_response ) ) { return $remote_url_response; } // Cache the valid response. $this->set_cache( $cache_key, $remote_url_response ); } $html_head = $this->get_document_head( $remote_url_response ); $meta_elements = $this->get_meta_with_content_elements( $html_head ); $data = $this->add_additional_fields_to_object( array( 'title' => $this->get_title( $html_head ), 'icon' => $this->get_icon( $html_head, $url ), 'description' => $this->get_description( $meta_elements ), 'image' => $this->get_image( $meta_elements, $url ), ), $request ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); /** * Filters the URL data for the response. * * @since 5.9.0 * * @param WP_REST_Response $response The response object. * @param string $url The requested URL. * @param WP_REST_Request $request Request object. * @param string $remote_url_response HTTP response body from the remote URL. */ return apply_filters( 'rest_prepare_url_details', $response, $url, $request, $remote_url_response ); } /** * Checks whether a given request has permission to read remote URLs. * * @since 5.9.0 * * @return true|WP_Error True if the request has permission, else WP_Error. */ public function permissions_check() { if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view_url_details', __( 'Sorry, you are not allowed to process remote URLs.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Retrieves the document title from a remote URL. * * @since 5.9.0 * * @param string $url The website URL whose HTML to access. * @return string|WP_Error The HTTP response from the remote URL on success. * WP_Error if no response or no content. */ private function get_remote_url( $url ) { /* * Provide a modified UA string to workaround web properties which block WordPress "Pingbacks". * Why? The UA string used for pingback requests contains `WordPress/` which is very similar * to that used as the default UA string by the WP HTTP API. Therefore requests from this * REST endpoint are being unintentionally blocked as they are misidentified as pingback requests. * By slightly modifying the UA string, but still retaining the "WordPress" identification (via "WP") * we are able to work around this issue. * Example UA string: `WP-URLDetails/5.9-alpha-51389 (+http://localhost:8888)`. */ $modified_user_agent = 'WP-URLDetails/' . get_bloginfo( 'version' ) . ' (+' . get_bloginfo( 'url' ) . ')'; $args = array( 'limit_response_size' => 150 * KB_IN_BYTES, 'user-agent' => $modified_user_agent, ); /** * Filters the HTTP request args for URL data retrieval. * * Can be used to adjust response size limit and other WP_Http::request() args. * * @since 5.9.0 * * @param array $args Arguments used for the HTTP request. * @param string $url The attempted URL. */ $args = apply_filters( 'rest_url_details_http_request_args', $args, $url ); $response = wp_safe_remote_get( $url, $args ); if ( WP_Http::OK !== wp_remote_retrieve_response_code( $response ) ) { // Not saving the error response to cache since the error might be temporary. return new WP_Error( 'no_response', __( 'URL not found. Response returned a non-200 status code for this URL.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } $remote_body = wp_remote_retrieve_body( $response ); if ( empty( $remote_body ) ) { return new WP_Error( 'no_content', __( 'Unable to retrieve body from response at this URL.' ), array( 'status' => WP_Http::NOT_FOUND ) ); } return $remote_body; } /** * Parses the title tag contents from the provided HTML. * * @since 5.9.0 * * @param string $html The HTML from the remote website at URL. * @return string The title tag contents on success. Empty string if not found. */ private function get_title( $html ) { $pattern = '#<title[^>]*>(.*?)<\s*/\s*title>#is'; preg_match( $pattern, $html, $match_title ); if ( empty( $match_title[1] ) || ! is_string( $match_title[1] ) ) { return ''; } $title = trim( $match_title[1] ); return $this->prepare_metadata_for_output( $title ); } /** * Parses the site icon from the provided HTML. * * @since 5.9.0 * * @param string $html The HTML from the remote website at URL. * @param string $url The target website URL. * @return string The icon URI on success. Empty string if not found. */ private function get_icon( $html, $url ) { // Grab the icon's link element. $pattern = '#<link\s[^>]*rel=(?:[\"\']??)\s*(?:icon|shortcut icon|icon shortcut)\s*(?:[\"\']??)[^>]*\/?>#isU'; preg_match( $pattern, $html, $element ); if ( empty( $element[0] ) || ! is_string( $element[0] ) ) { return ''; } $element = trim( $element[0] ); // Get the icon's href value. $pattern = '#href=([\"\']??)([^\" >]*?)\\1[^>]*#isU'; preg_match( $pattern, $element, $icon ); if ( empty( $icon[2] ) || ! is_string( $icon[2] ) ) { return ''; } $icon = trim( $icon[2] ); // If the icon is a data URL, return it. $parsed_icon = parse_url( $icon ); if ( isset( $parsed_icon['scheme'] ) && 'data' === $parsed_icon['scheme'] ) { return $icon; } // Attempt to convert relative URLs to absolute. if ( ! is_string( $url ) || '' === $url ) { return $icon; } $parsed_url = parse_url( $url ); if ( isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) ) { $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/'; $icon = WP_Http::make_absolute_url( $icon, $root_url ); } return $icon; } /** * Parses the meta description from the provided HTML. * * @since 5.9.0 * * @param array $meta_elements { * A multidimensional indexed array on success, else empty array. * * @type string[] $0 Meta elements with a content attribute. * @type string[] $1 Content attribute's opening quotation mark. * @type string[] $2 Content attribute's value for each meta element. * } * @return string The meta description contents on success. Empty string if not found. */ private function get_description( $meta_elements ) { // Bail out if there are no meta elements. if ( empty( $meta_elements[0] ) ) { return ''; } $description = $this->get_metadata_from_meta_element( $meta_elements, 'name', '(?:description|og:description)' ); // Bail out if description not found. if ( '' === $description ) { return ''; } return $this->prepare_metadata_for_output( $description ); } /** * Parses the Open Graph (OG) Image from the provided HTML. * * See: https://ogp.me/. * * @since 5.9.0 * * @param array $meta_elements { * A multidimensional indexed array on success, else empty array. * * @type string[] $0 Meta elements with a content attribute. * @type string[] $1 Content attribute's opening quotation mark. * @type string[] $2 Content attribute's value for each meta element. * } * @param string $url The target website URL. * @return string The OG image on success. Empty string if not found. */ private function get_image( $meta_elements, $url ) { $image = $this->get_metadata_from_meta_element( $meta_elements, 'property', '(?:og:image|og:image:url)' ); // Bail out if image not found. if ( '' === $image ) { return ''; } // Attempt to convert relative URLs to absolute. $parsed_url = parse_url( $url ); if ( isset( $parsed_url['scheme'] ) && isset( $parsed_url['host'] ) ) { $root_url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . '/'; $image = WP_Http::make_absolute_url( $image, $root_url ); } return $image; } /** * Prepares the metadata by: * - stripping all HTML tags and tag entities. * - converting non-tag entities into characters. * * @since 5.9.0 * * @param string $metadata The metadata content to prepare. * @return string The prepared metadata. */ private function prepare_metadata_for_output( $metadata ) { $metadata = html_entity_decode( $metadata, ENT_QUOTES, get_bloginfo( 'charset' ) ); $metadata = wp_strip_all_tags( $metadata ); return $metadata; } /** * Utility function to build cache key for a given URL. * * @since 5.9.0 * * @param string $url The URL for which to build a cache key. * @return string The cache key. */ private function build_cache_key_for_url( $url ) { return 'g_url_details_response_' . md5( $url ); } /** * Utility function to retrieve a value from the cache at a given key. * * @since 5.9.0 * * @param string $key The cache key. * @return mixed The value from the cache. */ private function get_cache( $key ) { return get_site_transient( $key ); } /** * Utility function to cache a given data set at a given cache key. * * @since 5.9.0 * * @param string $key The cache key under which to store the value. * @param string $data The data to be stored at the given cache key. * @return bool True when transient set. False if not set. */ private function set_cache( $key, $data = '' ) { $ttl = HOUR_IN_SECONDS; /** * Filters the cache expiration. * * Can be used to adjust the time until expiration in seconds for the cache * of the data retrieved for the given URL. * * @since 5.9.0 * * @param int $ttl The time until cache expiration in seconds. */ $cache_expiration = apply_filters( 'rest_url_details_cache_expiration', $ttl ); return set_site_transient( $key, $data, $cache_expiration ); } /** * Retrieves the head element section. * * @since 5.9.0 * * @param string $html The string of HTML to parse. * @return string The `<head>..</head>` section on success. Given `$html` if not found. */ private function get_document_head( $html ) { $head_html = $html; // Find the opening `<head>` tag. $head_start = strpos( $html, '<head' ); if ( false === $head_start ) { // Didn't find it. Return the original HTML. return $html; } // Find the closing `</head>` tag. $head_end = strpos( $head_html, '</head>' ); if ( false === $head_end ) { // Didn't find it. Find the opening `<body>` tag. $head_end = strpos( $head_html, '<body' ); // Didn't find it. Return the original HTML. if ( false === $head_end ) { return $html; } } // Extract the HTML from opening tag to the closing tag. Then add the closing tag. $head_html = substr( $head_html, $head_start, $head_end ); $head_html .= '</head>'; return $head_html; } /** * Gets all the meta tag elements that have a 'content' attribute. * * @since 5.9.0 * * @param string $html The string of HTML to be parsed. * @return array { * A multidimensional indexed array on success, else empty array. * * @type string[] $0 Meta elements with a content attribute. * @type string[] $1 Content attribute's opening quotation mark. * @type string[] $2 Content attribute's value for each meta element. * } */ private function get_meta_with_content_elements( $html ) { /* * Parse all meta elements with a content attribute. * * Why first search for the content attribute rather than directly searching for name=description element? * tl;dr The content attribute's value will be truncated when it contains a > symbol. * * The content attribute's value (i.e. the description to get) can have HTML in it and be well-formed as * it's a string to the browser. Imagine what happens when attempting to match for the name=description * first. Hmm, if a > or /> symbol is in the content attribute's value, then it terminates the match * as the element's closing symbol. But wait, it's in the content attribute and is not the end of the * element. This is a limitation of using regex. It can't determine "wait a minute this is inside of quotation". * If this happens, what gets matched is not the entire element or all of the content. * * Why not search for the name=description and then content="(.*)"? * The attribute order could be opposite. Plus, additional attributes may exist including being between * the name and content attributes. * * Why not lookahead? * Lookahead is not constrained to stay within the element. The first <meta it finds may not include * the name or content, but rather could be from a different element downstream. */ $pattern = '#<meta\s' . /* * Allows for additional attributes before the content attribute. * Searches for anything other than > symbol. */ '[^>]*' . /* * Find the content attribute. When found, capture its value (.*). * * Allows for (a) single or double quotes and (b) whitespace in the value. * * Why capture the opening quotation mark, i.e. (["\']), and then backreference, * i.e \1, for the closing quotation mark? * To ensure the closing quotation mark matches the opening one. Why? Attribute values * can contain quotation marks, such as an apostrophe in the content. */ 'content=(["\']??)(.*)\1' . /* * Allows for additional attributes after the content attribute. * Searches for anything other than > symbol. */ '[^>]*' . /* * \/?> searches for the closing > symbol, which can be in either /> or > format. * # ends the pattern. */ '\/?>#' . /* * These are the options: * - i : case-insensitive * - s : allows newline characters for the . match (needed for multiline elements) * - U means non-greedy matching */ 'isU'; preg_match_all( $pattern, $html, $elements ); return $elements; } /** * Gets the metadata from a target meta element. * * @since 5.9.0 * * @param array $meta_elements { * A multi-dimensional indexed array on success, else empty array. * * @type string[] $0 Meta elements with a content attribute. * @type string[] $1 Content attribute's opening quotation mark. * @type string[] $2 Content attribute's value for each meta element. * } * @param string $attr Attribute that identifies the element with the target metadata. * @param string $attr_value The attribute's value that identifies the element with the target metadata. * @return string The metadata on success. Empty string if not found. */ private function get_metadata_from_meta_element( $meta_elements, $attr, $attr_value ) { // Bail out if there are no meta elements. if ( empty( $meta_elements[0] ) ) { return ''; } $metadata = ''; $pattern = '#' . /* * Target this attribute and value to find the metadata element. * * Allows for (a) no, single, double quotes and (b) whitespace in the value. * * Why capture the opening quotation mark, i.e. (["\']), and then backreference, * i.e \1, for the closing quotation mark? * To ensure the closing quotation mark matches the opening one. Why? Attribute values * can contain quotation marks, such as an apostrophe in the content. */ $attr . '=([\"\']??)\s*' . $attr_value . '\s*\1' . /* * These are the options: * - i : case-insensitive * - s : allows newline characters for the . match (needed for multiline elements) * - U means non-greedy matching */ '#isU'; // Find the metadata element. foreach ( $meta_elements[0] as $index => $element ) { preg_match( $pattern, $element, $match ); // This is not the metadata element. Skip it. if ( empty( $match ) ) { continue; } /* * Found the metadata element. * Get the metadata from its matching content array. */ if ( isset( $meta_elements[2][ $index ] ) && is_string( $meta_elements[2][ $index ] ) ) { $metadata = trim( $meta_elements[2][ $index ] ); } break; } return $metadata; } } <?php /** * REST API: WP_REST_Plugins_Controller class * * @package WordPress * @subpackage REST_API * @since 5.5.0 */ /** * Core class to access plugins via the REST API. * * @since 5.5.0 * * @see WP_REST_Controller */ class WP_REST_Plugins_Controller extends WP_REST_Controller { const PATTERN = '[^.\/]+(?:\/[^.\/]+)?'; /** * Plugins controller constructor. * * @since 5.5.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'plugins'; } /** * Registers the routes for the plugins controller. * * @since 5.5.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => array( 'slug' => array( 'type' => 'string', 'required' => true, 'description' => __( 'WordPress.org plugin directory slug.' ), 'pattern' => '[\w\-]+', ), 'status' => array( 'description' => __( 'The plugin activation status.' ), 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), 'default' => 'inactive', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<plugin>' . self::PATTERN . ')', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check' ), ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'plugin' => array( 'type' => 'string', 'pattern' => self::PATTERN, 'validate_callback' => array( $this, 'validate_plugin_param' ), 'sanitize_callback' => array( $this, 'sanitize_plugin_param' ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to get plugins. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_view_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves a collection of plugins. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $plugins = array(); foreach ( get_plugins() as $file => $data ) { if ( is_wp_error( $this->check_read_permission( $file ) ) ) { continue; } $data['_file'] = $file; if ( ! $this->does_plugin_match_request( $request, $data ) ) { continue; } $plugins[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $data, $request ) ); } return new WP_REST_Response( $plugins ); } /** * Checks if a given request has access to get a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } /** * Retrieves one plugin from the site. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } return $this->prepare_item_for_response( $data, $request ); } /** * Checks if the given plugin can be viewed by the current user. * * On multisite, this hides non-active network only plugins if the user does not have permission * to manage network plugins. * * @since 5.5.0 * * @param string $plugin The plugin file to check. * @return true|WP_Error True if can read, a WP_Error instance otherwise. */ protected function check_read_permission( $plugin ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! $this->is_plugin_installed( $plugin ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } if ( ! is_multisite() ) { return true; } if ( ! is_network_only_plugin( $plugin ) || is_plugin_active( $plugin ) || current_user_can( 'manage_network_plugins' ) ) { return true; } return new WP_Error( 'rest_cannot_view_plugin', __( 'Sorry, you are not allowed to manage this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } /** * Checks if a given request has access to upload plugins. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise. */ public function create_item_permissions_check( $request ) { if ( ! current_user_can( 'install_plugins' ) ) { return new WP_Error( 'rest_cannot_install_plugin', __( 'Sorry, you are not allowed to install plugins on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' !== $request['status'] && ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate plugins.' ), array( 'status' => rest_authorization_required_code(), ) ); } return true; } /** * Uploads a plugin and optionally activates it. * * @since 5.5.0 * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function create_item( $request ) { global $wp_filesystem; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; $slug = $request['slug']; // Verify filesystem is accessible first. $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false, 'language_packs' => true, ), ) ); if ( is_wp_error( $api ) ) { if ( str_contains( $api->get_error_message(), 'Plugin not found.' ) ) { $api->add_data( array( 'status' => 404 ) ); } else { $api->add_data( array( 'status' => 500 ) ); } return $api; } $skin = new WP_Ajax_Upgrader_Skin(); $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->install( $api->download_link ); if ( is_wp_error( $result ) ) { $result->add_data( array( 'status' => 500 ) ); return $result; } // This should be the same as $result above. if ( is_wp_error( $skin->result ) ) { $skin->result->add_data( array( 'status' => 500 ) ); return $skin->result; } if ( $skin->get_errors()->has_errors() ) { $error = $skin->get_errors(); $error->add_data( array( 'status' => 500 ) ); return $error; } if ( is_null( $result ) ) { // Pass through the error from WP_Filesystem if one was raised. if ( $wp_filesystem instanceof WP_Filesystem_Base && is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors() ) { return new WP_Error( 'unable_to_connect_to_filesystem', $wp_filesystem->errors->get_error_message(), array( 'status' => 500 ) ); } return new WP_Error( 'unable_to_connect_to_filesystem', __( 'Unable to connect to the filesystem. Please confirm your credentials.' ), array( 'status' => 500 ) ); } $file = $upgrader->plugin_info(); if ( ! $file ) { return new WP_Error( 'unable_to_determine_installed_plugin', __( 'Unable to determine what plugin was installed.' ), array( 'status' => 500 ) ); } if ( 'inactive' !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $file, $request['status'], 'inactive' ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } $changed_status = $this->handle_plugin_status( $file, $request['status'], 'inactive' ); if ( is_wp_error( $changed_status ) ) { return $changed_status; } } // Install translations. $installed_locales = array_values( get_available_languages() ); /** This filter is documented in wp-includes/update.php */ $installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales ); $language_packs = array_map( static function ( $item ) { return (object) $item; }, $api->language_packs ); $language_packs = array_filter( $language_packs, static function ( $pack ) use ( $installed_locales ) { return in_array( $pack->language, $installed_locales, true ); } ); if ( $language_packs ) { $lp_upgrader = new Language_Pack_Upgrader( $skin ); // Install all applicable language packs for the plugin. $lp_upgrader->bulk_upgrade( $language_packs ); } $path = WP_PLUGIN_DIR . '/' . $file; $data = get_plugin_data( $path, false, false ); $data['_file'] = $file; $response = $this->prepare_item_for_response( $data, $request ); $response->set_status( 201 ); $response->header( 'Location', rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $file, 0, - 4 ) ) ) ); return $response; } /** * Checks if a given request has access to update a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $can_change_status = $this->plugin_status_permission_check( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $can_change_status ) ) { return $can_change_status; } } return true; } /** * Updates one plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } $status = $this->get_plugin_status( $request['plugin'] ); if ( $request['status'] && $status !== $request['status'] ) { $handled = $this->handle_plugin_status( $request['plugin'], $request['status'], $status ); if ( is_wp_error( $handled ) ) { return $handled; } } $this->update_additional_fields_for_object( $data, $request ); $request['context'] = 'edit'; return $this->prepare_item_for_response( $data, $request ); } /** * Checks if a given request has access to delete a specific plugin. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise. */ public function delete_item_permissions_check( $request ) { if ( ! current_user_can( 'activate_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to manage plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! current_user_can( 'delete_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_plugins', __( 'Sorry, you are not allowed to delete plugins for this site.' ), array( 'status' => rest_authorization_required_code() ) ); } $can_read = $this->check_read_permission( $request['plugin'] ); if ( is_wp_error( $can_read ) ) { return $can_read; } return true; } /** * Deletes one plugin from the site. * * @since 5.5.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function delete_item( $request ) { require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/plugin.php'; $data = $this->get_plugin_data( $request['plugin'] ); if ( is_wp_error( $data ) ) { return $data; } if ( is_plugin_active( $request['plugin'] ) ) { return new WP_Error( 'rest_cannot_delete_active_plugin', __( 'Cannot delete an active plugin. Please deactivate it first.' ), array( 'status' => 400 ) ); } $filesystem_available = $this->is_filesystem_available(); if ( is_wp_error( $filesystem_available ) ) { return $filesystem_available; } $prepared = $this->prepare_item_for_response( $data, $request ); $deleted = delete_plugins( array( $request['plugin'] ) ); if ( is_wp_error( $deleted ) ) { $deleted->add_data( array( 'status' => 500 ) ); return $deleted; } return new WP_REST_Response( array( 'deleted' => true, 'previous' => $prepared->get_data(), ) ); } /** * Prepares the plugin for the REST response. * * @since 5.5.0 * * @param array $item Unmarked up and untranslated plugin data from {@see get_plugin_data()}. * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function prepare_item_for_response( $item, $request ) { $fields = $this->get_fields_for_response( $request ); $item = _get_plugin_data_markup_translate( $item['_file'], $item, false ); $marked = _get_plugin_data_markup_translate( $item['_file'], $item, true ); $data = array( 'plugin' => substr( $item['_file'], 0, - 4 ), 'status' => $this->get_plugin_status( $item['_file'] ), 'name' => $item['Name'], 'plugin_uri' => $item['PluginURI'], 'author' => $item['Author'], 'author_uri' => $item['AuthorURI'], 'description' => array( 'raw' => $item['Description'], 'rendered' => $marked['Description'], ), 'version' => $item['Version'], 'network_only' => $item['Network'], 'requires_wp' => $item['RequiresWP'], 'requires_php' => $item['RequiresPHP'], 'textdomain' => $item['TextDomain'], ); $data = $this->add_additional_fields_to_object( $data, $request ); $response = new WP_REST_Response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $item ) ); } /** * Filters plugin data for a REST API response. * * @since 5.5.0 * * @param WP_REST_Response $response The response object. * @param array $item The plugin item from {@see get_plugin_data()}. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_plugin', $response, $item, $request ); } /** * Prepares links for the request. * * @since 5.5.0 * * @param array $item The plugin item. * @return array[] */ protected function prepare_links( $item ) { return array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, substr( $item['_file'], 0, - 4 ) ) ), ), ); } /** * Gets the plugin header data for a plugin. * * @since 5.5.0 * * @param string $plugin The plugin file to get data for. * @return array|WP_Error The plugin data, or a WP_Error if the plugin is not installed. */ protected function get_plugin_data( $plugin ) { $plugins = get_plugins(); if ( ! isset( $plugins[ $plugin ] ) ) { return new WP_Error( 'rest_plugin_not_found', __( 'Plugin not found.' ), array( 'status' => 404 ) ); } $data = $plugins[ $plugin ]; $data['_file'] = $plugin; return $data; } /** * Get's the activation status for a plugin. * * @since 5.5.0 * * @param string $plugin The plugin file to check. * @return string Either 'network-active', 'active' or 'inactive'. */ protected function get_plugin_status( $plugin ) { if ( is_plugin_active_for_network( $plugin ) ) { return 'network-active'; } if ( is_plugin_active( $plugin ) ) { return 'active'; } return 'inactive'; } /** * Handle updating a plugin's status. * * @since 5.5.0 * * @param string $plugin The plugin file to update. * @param string $new_status The plugin's new status. * @param string $current_status The plugin's current status. * @return true|WP_Error */ protected function plugin_status_permission_check( $plugin, $new_status, $current_status ) { if ( is_multisite() && ( 'network-active' === $current_status || 'network-active' === $new_status ) && ! current_user_can( 'manage_network_plugins' ) ) { return new WP_Error( 'rest_cannot_manage_network_plugins', __( 'Sorry, you are not allowed to manage network plugins.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ( 'active' === $new_status || 'network-active' === $new_status ) && ! current_user_can( 'activate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_activate_plugin', __( 'Sorry, you are not allowed to activate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'inactive' === $new_status && ! current_user_can( 'deactivate_plugin', $plugin ) ) { return new WP_Error( 'rest_cannot_deactivate_plugin', __( 'Sorry, you are not allowed to deactivate this plugin.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Handle updating a plugin's status. * * @since 5.5.0 * * @param string $plugin The plugin file to update. * @param string $new_status The plugin's new status. * @param string $current_status The plugin's current status. * @return true|WP_Error */ protected function handle_plugin_status( $plugin, $new_status, $current_status ) { if ( 'inactive' === $new_status ) { deactivate_plugins( $plugin, false, 'network-active' === $current_status ); return true; } if ( 'active' === $new_status && 'network-active' === $current_status ) { return true; } $network_activate = 'network-active' === $new_status; if ( is_multisite() && ! $network_activate && is_network_only_plugin( $plugin ) ) { return new WP_Error( 'rest_network_only_plugin', __( 'Network only plugin must be network activated.' ), array( 'status' => 400 ) ); } $activated = activate_plugin( $plugin, '', $network_activate ); if ( is_wp_error( $activated ) ) { $activated->add_data( array( 'status' => 500 ) ); return $activated; } return true; } /** * Checks that the "plugin" parameter is a valid path. * * @since 5.5.0 * * @param string $file The plugin file parameter. * @return bool */ public function validate_plugin_param( $file ) { if ( ! is_string( $file ) || ! preg_match( '/' . self::PATTERN . '/u', $file ) ) { return false; } $validated = validate_file( plugin_basename( $file ) ); return 0 === $validated; } /** * Sanitizes the "plugin" parameter to be a proper plugin file with ".php" appended. * * @since 5.5.0 * * @param string $file The plugin file parameter. * @return string */ public function sanitize_plugin_param( $file ) { return plugin_basename( sanitize_text_field( $file . '.php' ) ); } /** * Checks if the plugin matches the requested parameters. * * @since 5.5.0 * * @param WP_REST_Request $request The request to require the plugin matches against. * @param array $item The plugin item. * @return bool */ protected function does_plugin_match_request( $request, $item ) { $search = $request['search']; if ( $search ) { $matched_search = false; foreach ( $item as $field ) { if ( is_string( $field ) && str_contains( strip_tags( $field ), $search ) ) { $matched_search = true; break; } } if ( ! $matched_search ) { return false; } } $status = $request['status']; if ( $status && ! in_array( $this->get_plugin_status( $item['_file'] ), $status, true ) ) { return false; } return true; } /** * Checks if the plugin is installed. * * @since 5.5.0 * * @param string $plugin The plugin file. * @return bool */ protected function is_plugin_installed( $plugin ) { return file_exists( WP_PLUGIN_DIR . '/' . $plugin ); } /** * Determine if the endpoints are available. * * Only the 'Direct' filesystem transport, and SSH/FTP when credentials are stored are supported at present. * * @since 5.5.0 * * @return true|WP_Error True if filesystem is available, WP_Error otherwise. */ protected function is_filesystem_available() { $filesystem_method = get_filesystem_method(); if ( 'direct' === $filesystem_method ) { return true; } ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() ); ob_end_clean(); if ( $filesystem_credentials_are_stored ) { return true; } return new WP_Error( 'fs_unavailable', __( 'The filesystem is currently unavailable for managing plugins.' ), array( 'status' => 500 ) ); } /** * Retrieves the plugin's schema, conforming to JSON Schema. * * @since 5.5.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $this->schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'plugin', 'type' => 'object', 'properties' => array( 'plugin' => array( 'description' => __( 'The plugin file.' ), 'type' => 'string', 'pattern' => self::PATTERN, 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'status' => array( 'description' => __( 'The plugin activation status.' ), 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), 'context' => array( 'view', 'edit', 'embed' ), ), 'name' => array( 'description' => __( 'The plugin name.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'plugin_uri' => array( 'description' => __( 'The plugin\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author' => array( 'description' => __( 'The plugin author.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'author_uri' => array( 'description' => __( 'Plugin author\'s website address.' ), 'type' => 'string', 'format' => 'uri', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'description' => array( 'description' => __( 'The plugin description.' ), 'type' => 'object', 'readonly' => true, 'context' => array( 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'The raw plugin description.' ), 'type' => 'string', ), 'rendered' => array( 'description' => __( 'The plugin description formatted for display.' ), 'type' => 'string', ), ), ), 'version' => array( 'description' => __( 'The plugin version number.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), 'network_only' => array( 'description' => __( 'Whether the plugin can only be activated network-wide.' ), 'type' => 'boolean', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_wp' => array( 'description' => __( 'Minimum required version of WordPress.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'requires_php' => array( 'description' => __( 'Minimum required version of PHP.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'textdomain' => array( 'description' => __( 'The plugin\'s text domain.' ), 'type' => 'string', 'readonly' => true, 'context' => array( 'view', 'edit' ), ), ), ); return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for the collections. * * @since 5.5.0 * * @return array Query parameters for the collection. */ public function get_collection_params() { $query_params = parent::get_collection_params(); $query_params['context']['default'] = 'view'; $query_params['status'] = array( 'description' => __( 'Limits results to plugins with the given status.' ), 'type' => 'array', 'items' => array( 'type' => 'string', 'enum' => is_multisite() ? array( 'inactive', 'active', 'network-active' ) : array( 'inactive', 'active' ), ), ); unset( $query_params['page'], $query_params['per_page'] ); return $query_params; } } <?php /** * Block Renderer REST API: WP_REST_Block_Renderer_Controller class * * @package WordPress * @subpackage REST_API * @since 5.0.0 */ /** * Controller which provides REST endpoint for rendering a block. * * @since 5.0.0 * * @see WP_REST_Controller */ class WP_REST_Block_Renderer_Controller extends WP_REST_Controller { /** * Constructs the controller. * * @since 5.0.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'block-renderer'; } /** * Registers the necessary REST API routes, one for each dynamic block. * * @since 5.0.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<name>[a-z0-9-]+/[a-z0-9-]+)', array( 'args' => array( 'name' => array( 'description' => __( 'Unique registered name for the block.' ), 'type' => 'string', ), ), array( 'methods' => array( WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ), 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 'attributes' => array( 'description' => __( 'Attributes for the block.' ), 'type' => 'object', 'default' => array(), 'validate_callback' => static function ( $value, $request ) { $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] ); if ( ! $block ) { // This will get rejected in ::get_item(). return true; } $schema = array( 'type' => 'object', 'properties' => $block->get_attributes(), 'additionalProperties' => false, ); return rest_validate_value_from_schema( $value, $schema ); }, 'sanitize_callback' => static function ( $value, $request ) { $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] ); if ( ! $block ) { // This will get rejected in ::get_item(). return true; } $schema = array( 'type' => 'object', 'properties' => $block->get_attributes(), 'additionalProperties' => false, ); return rest_sanitize_value_from_schema( $value, $schema ); }, ), 'post_id' => array( 'description' => __( 'ID of the post context.' ), 'type' => 'integer', ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to read blocks. * * @since 5.0.0 * * @global WP_Post $post Global post object. * * @param WP_REST_Request $request Request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { global $post; $post_id = isset( $request['post_id'] ) ? (int) $request['post_id'] : 0; if ( $post_id > 0 ) { $post = get_post( $post_id ); if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { return new WP_Error( 'block_cannot_read', __( 'Sorry, you are not allowed to read blocks of this post.' ), array( 'status' => rest_authorization_required_code(), ) ); } } else { if ( ! current_user_can( 'edit_posts' ) ) { return new WP_Error( 'block_cannot_read', __( 'Sorry, you are not allowed to read blocks as this user.' ), array( 'status' => rest_authorization_required_code(), ) ); } } return true; } /** * Returns block output from block's registered render_callback. * * @since 5.0.0 * * @global WP_Post $post Global post object. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { global $post; $post_id = isset( $request['post_id'] ) ? (int) $request['post_id'] : 0; if ( $post_id > 0 ) { $post = get_post( $post_id ); // Set up postdata since this will be needed if post_id was set. setup_postdata( $post ); } $registry = WP_Block_Type_Registry::get_instance(); $registered = $registry->get_registered( $request['name'] ); if ( null === $registered || ! $registered->is_dynamic() ) { return new WP_Error( 'block_invalid', __( 'Invalid block.' ), array( 'status' => 404, ) ); } $attributes = $request->get_param( 'attributes' ); // Create an array representation simulating the output of parse_blocks. $block = array( 'blockName' => $request['name'], 'attrs' => $attributes, 'innerHTML' => '', 'innerContent' => array(), ); // Render using render_block to ensure all relevant filters are used. $data = array( 'rendered' => render_block( $block ), ); return rest_ensure_response( $data ); } /** * Retrieves block's output schema, conforming to JSON Schema. * * @since 5.0.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->schema; } $this->schema = array( '$schema' => 'http://json-schema.org/schema#', 'title' => 'rendered-block', 'type' => 'object', 'properties' => array( 'rendered' => array( 'description' => __( 'The rendered block.' ), 'type' => 'string', 'required' => true, 'context' => array( 'edit' ), ), ), ); return $this->schema; } } <?php /** * REST API: WP_REST_Settings_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class used to manage a site's settings via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Settings_Controller extends WP_REST_Controller { /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'settings'; } /** * Registers the routes for the site's settings. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'args' => array(), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to read and manage settings. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return bool True if the request has read access for the item, otherwise false. */ public function get_item_permissions_check( $request ) { return current_user_can( 'manage_options' ); } /** * Retrieves the settings. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return array|WP_Error Array on success, or WP_Error object on failure. */ public function get_item( $request ) { $options = $this->get_registered_options(); $response = array(); foreach ( $options as $name => $args ) { /** * Filters the value of a setting recognized by the REST API. * * Allow hijacking the setting value and overriding the built-in behavior by returning a * non-null value. The returned value will be presented as the setting value instead. * * @since 4.7.0 * * @param mixed $result Value to use for the requested setting. Can be a scalar * matching the registered schema for the setting, or null to * follow the default get_option() behavior. * @param string $name Setting name (as shown in REST API responses). * @param array $args Arguments passed to register_setting() for this setting. */ $response[ $name ] = apply_filters( 'rest_pre_get_setting', null, $name, $args ); if ( is_null( $response[ $name ] ) ) { // Default to a null value as "null" in the response means "not set". $response[ $name ] = get_option( $args['option_name'], $args['schema']['default'] ); } /* * Because get_option() is lossy, we have to * cast values to the type they are registered with. */ $response[ $name ] = $this->prepare_value( $response[ $name ], $args['schema'] ); } return $response; } /** * Prepares a value for output based off a schema array. * * @since 4.7.0 * * @param mixed $value Value to prepare. * @param array $schema Schema to match. * @return mixed The prepared value. */ protected function prepare_value( $value, $schema ) { /* * If the value is not valid by the schema, set the value to null. * Null values are specifically non-destructive, so this will not cause * overwriting the current invalid value to null. */ if ( is_wp_error( rest_validate_value_from_schema( $value, $schema ) ) ) { return null; } return rest_sanitize_value_from_schema( $value, $schema ); } /** * Updates settings for the settings object. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return array|WP_Error Array on success, or error object on failure. */ public function update_item( $request ) { $options = $this->get_registered_options(); $params = $request->get_params(); foreach ( $options as $name => $args ) { if ( ! array_key_exists( $name, $params ) ) { continue; } /** * Filters whether to preempt a setting value update via the REST API. * * Allows hijacking the setting update logic and overriding the built-in behavior by * returning true. * * @since 4.7.0 * * @param bool $result Whether to override the default behavior for updating the * value of a setting. * @param string $name Setting name (as shown in REST API responses). * @param mixed $value Updated setting value. * @param array $args Arguments passed to register_setting() for this setting. */ $updated = apply_filters( 'rest_pre_update_setting', false, $name, $request[ $name ], $args ); if ( $updated ) { continue; } /* * A null value for an option would have the same effect as * deleting the option from the database, and relying on the * default value. */ if ( is_null( $request[ $name ] ) ) { /* * A null value is returned in the response for any option * that has a non-scalar value. * * To protect clients from accidentally including the null * values from a response object in a request, we do not allow * options with values that don't pass validation to be updated to null. * Without this added protection a client could mistakenly * delete all options that have invalid values from the * database. */ if ( is_wp_error( rest_validate_value_from_schema( get_option( $args['option_name'], false ), $args['schema'] ) ) ) { return new WP_Error( 'rest_invalid_stored_value', /* translators: %s: Property name. */ sprintf( __( 'The %s property has an invalid stored value, and cannot be updated to null.' ), $name ), array( 'status' => 500 ) ); } delete_option( $args['option_name'] ); } else { update_option( $args['option_name'], $request[ $name ] ); } } return $this->get_item( $request ); } /** * Retrieves all of the registered options for the Settings API. * * @since 4.7.0 * * @return array Array of registered options. */ protected function get_registered_options() { $rest_options = array(); foreach ( get_registered_settings() as $name => $args ) { if ( empty( $args['show_in_rest'] ) ) { continue; } $rest_args = array(); if ( is_array( $args['show_in_rest'] ) ) { $rest_args = $args['show_in_rest']; } $defaults = array( 'name' => ! empty( $rest_args['name'] ) ? $rest_args['name'] : $name, 'schema' => array(), ); $rest_args = array_merge( $defaults, $rest_args ); $default_schema = array( 'type' => empty( $args['type'] ) ? null : $args['type'], 'title' => empty( $args['label'] ) ? '' : $args['label'], 'description' => empty( $args['description'] ) ? '' : $args['description'], 'default' => isset( $args['default'] ) ? $args['default'] : null, ); $rest_args['schema'] = array_merge( $default_schema, $rest_args['schema'] ); $rest_args['option_name'] = $name; // Skip over settings that don't have a defined type in the schema. if ( empty( $rest_args['schema']['type'] ) ) { continue; } /* * Allow the supported types for settings, as we don't want invalid types * to be updated with arbitrary values that we can't do decent sanitizing for. */ if ( ! in_array( $rest_args['schema']['type'], array( 'number', 'integer', 'string', 'boolean', 'array', 'object' ), true ) ) { continue; } $rest_args['schema'] = rest_default_additional_properties_to_false( $rest_args['schema'] ); $rest_options[ $rest_args['name'] ] = $rest_args; } return $rest_options; } /** * Retrieves the site setting schema, conforming to JSON Schema. * * @since 4.7.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $options = $this->get_registered_options(); $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings', 'type' => 'object', 'properties' => array(), ); foreach ( $options as $option_name => $option ) { $schema['properties'][ $option_name ] = $option['schema']; $schema['properties'][ $option_name ]['arg_options'] = array( 'sanitize_callback' => array( $this, 'sanitize_callback' ), ); } $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Custom sanitize callback used for all options to allow the use of 'null'. * * By default, the schema of settings will throw an error if a value is set to * `null` as it's not a valid value for something like "type => string". We * provide a wrapper sanitizer to allow the use of `null`. * * @since 4.7.0 * * @param mixed $value The value for the setting. * @param WP_REST_Request $request The request object. * @param string $param The parameter name. * @return mixed|WP_Error */ public function sanitize_callback( $value, $request, $param ) { if ( is_null( $value ) ) { return $value; } return rest_parse_request_arg( $value, $request, $param ); } /** * Recursively add additionalProperties = false to all objects in a schema * if no additionalProperties setting is specified. * * This is needed to restrict properties of objects in settings values to only * registered items, as the REST API will allow additional properties by * default. * * @since 4.9.0 * @deprecated 6.1.0 Use {@see rest_default_additional_properties_to_false()} instead. * * @param array $schema The schema array. * @return array */ protected function set_additional_properties_to_false( $schema ) { _deprecated_function( __METHOD__, '6.1.0', 'rest_default_additional_properties_to_false()' ); return rest_default_additional_properties_to_false( $schema ); } } <?php /** * REST API: WP_REST_Post_Types_Controller class * * @package WordPress * @subpackage REST_API * @since 4.7.0 */ /** * Core class to access post types via the REST API. * * @since 4.7.0 * * @see WP_REST_Controller */ class WP_REST_Post_Types_Controller extends WP_REST_Controller { /** * Constructor. * * @since 4.7.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'types'; } /** * Registers the routes for post types. * * @since 4.7.0 * * @see register_rest_route() */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<type>[\w-]+)', array( 'args' => array( 'type' => array( 'description' => __( 'An alphanumeric identifier for the post type.' ), 'type' => 'string', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => '__return_true', 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks whether a given request has permission to read types. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { if ( 'edit' === $request['context'] ) { $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( current_user_can( $type->cap->edit_posts ) ) { return true; } } return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves all public post types. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $data = array(); $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); foreach ( $types as $type ) { if ( 'edit' === $request['context'] && ! current_user_can( $type->cap->edit_posts ) ) { continue; } $post_type = $this->prepare_item_for_response( $type, $request ); $data[ $type->name ] = $this->prepare_response_for_collection( $post_type ); } return rest_ensure_response( $data ); } /** * Retrieves a specific post type. * * @since 4.7.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $obj = get_post_type_object( $request['type'] ); if ( empty( $obj ) ) { return new WP_Error( 'rest_type_invalid', __( 'Invalid post type.' ), array( 'status' => 404 ) ); } if ( empty( $obj->show_in_rest ) ) { return new WP_Error( 'rest_cannot_read_type', __( 'Cannot view post type.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( 'edit' === $request['context'] && ! current_user_can( $obj->cap->edit_posts ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit posts in this post type.' ), array( 'status' => rest_authorization_required_code() ) ); } $data = $this->prepare_item_for_response( $obj, $request ); return rest_ensure_response( $data ); } /** * Prepares a post type object for serialization. * * @since 4.7.0 * @since 5.9.0 Renamed `$post_type` to `$item` to match parent class for PHP 8 named parameter support. * * @param WP_Post_Type $item Post type object. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { // Restores the more descriptive, specific name for use within this method. $post_type = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php */ return apply_filters( 'rest_prepare_post_type', new WP_REST_Response( array() ), $post_type, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $post_type->name, 'objects' ), array( 'show_in_rest' => true ) ); $taxonomies = wp_list_pluck( $taxonomies, 'name' ); $base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name; $namespace = ! empty( $post_type->rest_namespace ) ? $post_type->rest_namespace : 'wp/v2'; $supports = get_all_post_type_supports( $post_type->name ); $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'capabilities', $fields ) ) { $data['capabilities'] = $post_type->cap; } if ( rest_is_field_included( 'description', $fields ) ) { $data['description'] = $post_type->description; } if ( rest_is_field_included( 'hierarchical', $fields ) ) { $data['hierarchical'] = $post_type->hierarchical; } if ( rest_is_field_included( 'has_archive', $fields ) ) { $data['has_archive'] = $post_type->has_archive; } if ( rest_is_field_included( 'visibility', $fields ) ) { $data['visibility'] = array( 'show_in_nav_menus' => (bool) $post_type->show_in_nav_menus, 'show_ui' => (bool) $post_type->show_ui, ); } if ( rest_is_field_included( 'viewable', $fields ) ) { $data['viewable'] = is_post_type_viewable( $post_type ); } if ( rest_is_field_included( 'labels', $fields ) ) { $data['labels'] = $post_type->labels; } if ( rest_is_field_included( 'name', $fields ) ) { $data['name'] = $post_type->label; } if ( rest_is_field_included( 'slug', $fields ) ) { $data['slug'] = $post_type->name; } if ( rest_is_field_included( 'icon', $fields ) ) { $data['icon'] = $post_type->menu_icon; } if ( rest_is_field_included( 'supports', $fields ) ) { $data['supports'] = $supports; } if ( rest_is_field_included( 'taxonomies', $fields ) ) { $data['taxonomies'] = array_values( $taxonomies ); } if ( rest_is_field_included( 'rest_base', $fields ) ) { $data['rest_base'] = $base; } if ( rest_is_field_included( 'rest_namespace', $fields ) ) { $data['rest_namespace'] = $namespace; } if ( rest_is_field_included( 'template', $fields ) ) { $data['template'] = $post_type->template ?? array(); } if ( rest_is_field_included( 'template_lock', $fields ) ) { $data['template_lock'] = ! empty( $post_type->template_lock ) ? $post_type->template_lock : false; } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $post_type ) ); } /** * Filters a post type returned from the REST API. * * Allows modification of the post type data right before it is returned. * * @since 4.7.0 * * @param WP_REST_Response $response The response object. * @param WP_Post_Type $post_type The original post type object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( 'rest_prepare_post_type', $response, $post_type, $request ); } /** * Prepares links for the request. * * @since 6.1.0 * * @param WP_Post_Type $post_type The post type. * @return array Links for the given post type. */ protected function prepare_links( $post_type ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'https://api.w.org/items' => array( 'href' => rest_url( rest_get_route_for_post_type_items( $post_type->name ) ), ), ); } /** * Retrieves the post type's schema, conforming to JSON Schema. * * @since 4.7.0 * @since 4.8.0 The `supports` property was added. * @since 5.9.0 The `visibility` and `rest_namespace` properties were added. * @since 6.1.0 The `icon` property was added. * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'type', 'type' => 'object', 'properties' => array( 'capabilities' => array( 'description' => __( 'All capabilities used by the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'A human-readable description of the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'hierarchical' => array( 'description' => __( 'Whether or not the post type should have children.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'viewable' => array( 'description' => __( 'Whether or not the post type can be viewed.' ), 'type' => 'boolean', 'context' => array( 'edit' ), 'readonly' => true, ), 'labels' => array( 'description' => __( 'Human-readable labels for the post type for various contexts.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'The title for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'slug' => array( 'description' => __( 'An alphanumeric identifier for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'supports' => array( 'description' => __( 'All features, supported by the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, ), 'has_archive' => array( 'description' => __( 'If the value is a string, the value will be used as the archive slug. If the value is false the post type has no archive.' ), 'type' => array( 'string', 'boolean' ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'taxonomies' => array( 'description' => __( 'Taxonomies associated with post type.' ), 'type' => 'array', 'items' => array( 'type' => 'string', ), 'context' => array( 'view', 'edit' ), 'readonly' => true, ), 'rest_base' => array( 'description' => __( 'REST base route for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'rest_namespace' => array( 'description' => __( 'REST route\'s namespace for the post type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'visibility' => array( 'description' => __( 'The visibility settings for the post type.' ), 'type' => 'object', 'context' => array( 'edit' ), 'readonly' => true, 'properties' => array( 'show_ui' => array( 'description' => __( 'Whether to generate a default UI for managing this post type.' ), 'type' => 'boolean', ), 'show_in_nav_menus' => array( 'description' => __( 'Whether to make the post type available for selection in navigation menus.' ), 'type' => 'boolean', ), ), ), 'icon' => array( 'description' => __( 'The icon for the post type.' ), 'type' => array( 'string', 'null' ), 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), 'template' => array( 'type' => array( 'array' ), 'description' => __( 'The block template associated with the post type.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), 'template_lock' => array( 'type' => array( 'string', 'boolean' ), 'enum' => array( 'all', 'insert', 'contentOnly', false ), 'description' => __( 'The template_lock associated with the post type, or false if none.' ), 'readonly' => true, 'context' => array( 'view', 'edit', 'embed' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Retrieves the query params for collections. * * @since 4.7.0 * * @return array Collection parameters. */ public function get_collection_params() { return array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); } } <?php /** * REST API: WP_REST_Sidebars_Controller class * * Original code from {@link https://github.com/martin-pettersson/wp-rest-api-sidebars Martin Pettersson (martin_pettersson@outlook.com)}. * * @package WordPress * @subpackage REST_API * @since 5.8.0 */ /** * Core class used to manage a site's sidebars. * * @since 5.8.0 * * @see WP_REST_Controller */ class WP_REST_Sidebars_Controller extends WP_REST_Controller { /** * Tracks whether {@see retrieve_widgets()} has been called in the current request. * * @since 5.9.0 * @var bool */ protected $widgets_retrieved = false; /** * Sidebars controller constructor. * * @since 5.8.0 */ public function __construct() { $this->namespace = 'wp/v2'; $this->rest_base = 'sidebars'; } /** * Registers the controllers routes. * * @since 5.8.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => array( 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'The id of a registered sidebar' ), 'type' => 'string', ), 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Checks if a given request has access to get sidebars. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_items_permissions_check( $request ) { $this->retrieve_widgets(); foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { $sidebar = $this->get_sidebar( $id ); if ( ! $sidebar ) { continue; } if ( $this->check_read_permission( $sidebar ) ) { return true; } } return $this->do_permissions_check(); } /** * Retrieves the list of sidebars (active or inactive). * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success. */ public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. return new WP_REST_Response( array() ); } $this->retrieve_widgets(); $data = array(); $permissions_check = $this->do_permissions_check(); foreach ( wp_get_sidebars_widgets() as $id => $widgets ) { $sidebar = $this->get_sidebar( $id ); if ( ! $sidebar ) { continue; } if ( is_wp_error( $permissions_check ) && ! $this->check_read_permission( $sidebar ) ) { continue; } $data[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $sidebar, $request ) ); } return rest_ensure_response( $data ); } /** * Checks if a given request has access to get a single sidebar. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $this->retrieve_widgets(); $sidebar = $this->get_sidebar( $request['id'] ); if ( $sidebar && $this->check_read_permission( $sidebar ) ) { return true; } return $this->do_permissions_check(); } /** * Checks if a sidebar can be read publicly. * * @since 5.9.0 * * @param array $sidebar The registered sidebar configuration. * @return bool Whether the side can be read. */ protected function check_read_permission( $sidebar ) { return ! empty( $sidebar['show_in_rest'] ); } /** * Retrieves one sidebar from the collection. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ public function get_item( $request ) { $this->retrieve_widgets(); $sidebar = $this->get_sidebar( $request['id'] ); if ( ! $sidebar ) { return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) ); } return $this->prepare_item_for_response( $sidebar, $request ); } /** * Checks if a given request has access to update sidebars. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { return $this->do_permissions_check(); } /** * Updates a sidebar. * * @since 5.8.0 * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function update_item( $request ) { if ( isset( $request['widgets'] ) ) { $sidebars = wp_get_sidebars_widgets(); foreach ( $sidebars as $sidebar_id => $widgets ) { foreach ( $widgets as $i => $widget_id ) { // This automatically removes the passed widget IDs from any other sidebars in use. if ( $sidebar_id !== $request['id'] && in_array( $widget_id, $request['widgets'], true ) ) { unset( $sidebars[ $sidebar_id ][ $i ] ); } // This automatically removes omitted widget IDs to the inactive sidebar. if ( $sidebar_id === $request['id'] && ! in_array( $widget_id, $request['widgets'], true ) ) { $sidebars['wp_inactive_widgets'][] = $widget_id; } } } $sidebars[ $request['id'] ] = $request['widgets']; wp_set_sidebars_widgets( $sidebars ); } $request['context'] = 'edit'; $sidebar = $this->get_sidebar( $request['id'] ); /** * Fires after a sidebar is updated via the REST API. * * @since 5.8.0 * * @param array $sidebar The updated sidebar. * @param WP_REST_Request $request Request object. */ do_action( 'rest_save_sidebar', $sidebar, $request ); return $this->prepare_item_for_response( $sidebar, $request ); } /** * Checks if the user has permissions to make the request. * * @since 5.8.0 * * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ protected function do_permissions_check() { /* * Verify if the current user has edit_theme_options capability. * This capability is required to access the widgets screen. */ if ( ! current_user_can( 'edit_theme_options' ) ) { return new WP_Error( 'rest_cannot_manage_widgets', __( 'Sorry, you are not allowed to manage widgets on this site.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Retrieves the registered sidebar with the given id. * * @since 5.8.0 * * @param string|int $id ID of the sidebar. * @return array|null The discovered sidebar, or null if it is not registered. */ protected function get_sidebar( $id ) { return wp_get_sidebar( $id ); } /** * Looks for "lost" widgets once per request. * * @since 5.9.0 * * @see retrieve_widgets() */ protected function retrieve_widgets() { if ( ! $this->widgets_retrieved ) { retrieve_widgets(); $this->widgets_retrieved = true; } } /** * Prepares a single sidebar output for response. * * @since 5.8.0 * @since 5.9.0 Renamed `$raw_sidebar` to `$item` to match parent class for PHP 8 named parameter support. * * @global array $wp_registered_sidebars The registered sidebars. * @global array $wp_registered_widgets The registered widgets. * * @param array $item Sidebar instance. * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Prepared response object. */ public function prepare_item_for_response( $item, $request ) { global $wp_registered_sidebars, $wp_registered_widgets; // Restores the more descriptive, specific name for use within this method. $raw_sidebar = $item; // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php */ return apply_filters( 'rest_prepare_sidebar', new WP_REST_Response( array() ), $raw_sidebar, $request ); } $id = $raw_sidebar['id']; $sidebar = array( 'id' => $id ); if ( isset( $wp_registered_sidebars[ $id ] ) ) { $registered_sidebar = $wp_registered_sidebars[ $id ]; $sidebar['status'] = 'active'; $sidebar['name'] = isset( $registered_sidebar['name'] ) ? $registered_sidebar['name'] : ''; $sidebar['description'] = isset( $registered_sidebar['description'] ) ? wp_sidebar_description( $id ) : ''; $sidebar['class'] = isset( $registered_sidebar['class'] ) ? $registered_sidebar['class'] : ''; $sidebar['before_widget'] = isset( $registered_sidebar['before_widget'] ) ? $registered_sidebar['before_widget'] : ''; $sidebar['after_widget'] = isset( $registered_sidebar['after_widget'] ) ? $registered_sidebar['after_widget'] : ''; $sidebar['before_title'] = isset( $registered_sidebar['before_title'] ) ? $registered_sidebar['before_title'] : ''; $sidebar['after_title'] = isset( $registered_sidebar['after_title'] ) ? $registered_sidebar['after_title'] : ''; } else { $sidebar['status'] = 'inactive'; $sidebar['name'] = $raw_sidebar['name']; $sidebar['description'] = ''; $sidebar['class'] = ''; } if ( wp_is_block_theme() ) { $sidebar['status'] = 'inactive'; } $fields = $this->get_fields_for_response( $request ); if ( rest_is_field_included( 'widgets', $fields ) ) { $sidebars = wp_get_sidebars_widgets(); $widgets = array_filter( isset( $sidebars[ $sidebar['id'] ] ) ? $sidebars[ $sidebar['id'] ] : array(), static function ( $widget_id ) use ( $wp_registered_widgets ) { return isset( $wp_registered_widgets[ $widget_id ] ); } ); $sidebar['widgets'] = array_values( $widgets ); } $schema = $this->get_item_schema(); $data = array(); foreach ( $schema['properties'] as $property_id => $property ) { if ( isset( $sidebar[ $property_id ] ) && true === rest_validate_value_from_schema( $sidebar[ $property_id ], $property ) ) { $data[ $property_id ] = $sidebar[ $property_id ]; } elseif ( isset( $property['default'] ) ) { $data[ $property_id ] = $property['default']; } } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_links( $this->prepare_links( $sidebar ) ); } /** * Filters the REST API response for a sidebar. * * @since 5.8.0 * * @param WP_REST_Response $response The response object. * @param array $raw_sidebar The raw sidebar data. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_prepare_sidebar', $response, $raw_sidebar, $request ); } /** * Prepares links for the sidebar. * * @since 5.8.0 * * @param array $sidebar Sidebar. * @return array Links for the given widget. */ protected function prepare_links( $sidebar ) { return array( 'collection' => array( 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), ), 'self' => array( 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $sidebar['id'] ) ), ), 'https://api.w.org/widget' => array( 'href' => add_query_arg( 'sidebar', $sidebar['id'], rest_url( '/wp/v2/widgets' ) ), 'embeddable' => true, ), ); } /** * Retrieves the block type' schema, conforming to JSON Schema. * * @since 5.8.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'sidebar', 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'name' => array( 'description' => __( 'Unique name identifying the sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'description' => array( 'description' => __( 'Description of sidebar.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'class' => array( 'description' => __( 'Extra CSS class to assign to the sidebar in the Widgets interface.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'before_widget' => array( 'description' => __( 'HTML content to prepend to each widget\'s HTML output when assigned to this sidebar. Default is an opening list item element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'after_widget' => array( 'description' => __( 'HTML content to append to each widget\'s HTML output when assigned to this sidebar. Default is a closing list item element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'before_title' => array( 'description' => __( 'HTML content to prepend to the sidebar title when displayed. Default is an opening h2 element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'after_title' => array( 'description' => __( 'HTML content to append to the sidebar title when displayed. Default is a closing h2 element.' ), 'type' => 'string', 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'status' => array( 'description' => __( 'Status of sidebar.' ), 'type' => 'string', 'enum' => array( 'active', 'inactive' ), 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'widgets' => array( 'description' => __( 'Nested widgets.' ), 'type' => 'array', 'items' => array( 'type' => array( 'object', 'string' ), ), 'default' => array(), 'context' => array( 'embed', 'view', 'edit' ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } } <?php /** * REST API: WP_REST_Global_Styles_Controller class * * @package WordPress * @subpackage REST_API * @since 5.9.0 */ /** * Base Global Styles REST API Controller. */ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller { /** * Whether the controller supports batching. * * @since 6.6.0 * @var array */ protected $allow_batch = array( 'v1' => false ); /** * Constructor. * * @since 6.6.0 * * @param string $post_type Post type. */ public function __construct( $post_type = 'wp_global_styles' ) { parent::__construct( $post_type ); } /** * Registers the controllers routes. * * @since 5.9.0 */ public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base . '/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)/variations', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_theme_items' ), 'permission_callback' => array( $this, 'get_theme_items_permissions_check' ), 'args' => array( 'stylesheet' => array( 'description' => __( 'The theme identifier' ), 'type' => 'string', ), ), 'allow_batch' => $this->allow_batch, ), ) ); // List themes global styles. register_rest_route( $this->namespace, // The route. sprintf( '/%s/themes/(?P<stylesheet>%s)', $this->rest_base, /* * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. * Excludes invalid directory name characters: `/:<>*?"|`. */ '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?' ), array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_theme_item' ), 'permission_callback' => array( $this, 'get_theme_item_permissions_check' ), 'args' => array( 'stylesheet' => array( 'description' => __( 'The theme identifier' ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), ), ), 'allow_batch' => $this->allow_batch, ), ) ); // Lists/updates a single global style variation based on the given id. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\/\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check' ), 'args' => array( 'id' => array( 'description' => __( 'The id of a template' ), 'type' => 'string', 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), 'allow_batch' => $this->allow_batch, ) ); } /** * Sanitize the global styles ID or stylesheet to decode endpoint. * For example, `wp/v2/global-styles/twentytwentytwo%200.4.0` * would be decoded to `twentytwentytwo 0.4.0`. * * @since 5.9.0 * * @param string $id_or_stylesheet Global styles ID or stylesheet. * @return string Sanitized global styles ID or stylesheet. */ public function _sanitize_global_styles_callback( $id_or_stylesheet ) { return urldecode( $id_or_stylesheet ); } /** * Get the post, if the ID is valid. * * @since 5.9.0 * * @param int $id Supplied ID. * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. */ protected function get_post( $id ) { $error = new WP_Error( 'rest_global_styles_not_found', __( 'No global styles config exist with that id.' ), array( 'status' => 404 ) ); $id = (int) $id; if ( $id <= 0 ) { return $error; } $post = get_post( $id ); if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { return $error; } return $post; } /** * Checks if a given request has access to read a single global style. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access, WP_Error object otherwise. */ public function get_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } if ( ! $this->check_read_permission( $post ) ) { return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to view this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Checks if a global style can be read. * * @since 5.9.0 * * @param WP_Post $post Post object. * @return bool Whether the post can be read. */ public function check_read_permission( $post ) { return current_user_can( 'read_post', $post->ID ); } /** * Checks if a given request has access to write a single global styles config. * * @since 5.9.0 * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has write access for the item, WP_Error object otherwise. */ public function update_item_permissions_check( $request ) { $post = $this->get_post( $request['id'] ); if ( is_wp_error( $post ) ) { return $post; } if ( $post && ! $this->check_update_permission( $post ) ) { return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to edit this global style.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } /** * Prepares a single global styles config for update. * * @since 5.9.0 * @since 6.2.0 Added validation of styles.css property. * @since 6.6.0 Added registration of block style variations from theme.json sources (theme.json, user theme.json, partials). * * @param WP_REST_Request $request Request object. * @return stdClass|WP_Error Prepared item on success. WP_Error on when the custom CSS is not valid. */ protected function prepare_item_for_database( $request ) { $changes = new stdClass(); $changes->ID = $request['id']; $post = get_post( $request['id'] ); $existing_config = array(); if ( $post ) { $existing_config = json_decode( $post->post_content, true ); $json_decoding_error = json_last_error(); if ( JSON_ERROR_NONE !== $json_decoding_error || ! isset( $existing_config['isGlobalStylesUserThemeJSON'] ) || ! $existing_config['isGlobalStylesUserThemeJSON'] ) { $existing_config = array(); } } if ( isset( $request['styles'] ) || isset( $request['settings'] ) ) { $config = array(); if ( isset( $request['styles'] ) ) { if ( isset( $request['styles']['css'] ) ) { $css_validation_result = $this->validate_custom_css( $request['styles']['css'] ); if ( is_wp_error( $css_validation_result ) ) { return $css_validation_result; } } $config['styles'] = $request['styles']; } elseif ( isset( $existing_config['styles'] ) ) { $config['styles'] = $existing_config['styles']; } // Register theme-defined variations e.g. from block style variation partials under `/styles`. $variations = WP_Theme_JSON_Resolver::get_style_variations( 'block' ); wp_register_block_style_variations_from_theme_json_partials( $variations ); if ( isset( $request['settings'] ) ) { $config['settings'] = $request['settings']; } elseif ( isset( $existing_config['settings'] ) ) { $config['settings'] = $existing_config['settings']; } $config['isGlobalStylesUserThemeJSON'] = true; $config['version'] = WP_Theme_JSON::LATEST_SCHEMA; $changes->post_content = wp_json_encode( $config ); } // Post title. if ( isset( $request['title'] ) ) { if ( is_string( $request['title'] ) ) { $changes->post_title = $request['title']; } elseif ( ! empty( $request['title']['raw'] ) ) { $changes->post_title = $request['title']['raw']; } } return $changes; } /** * Prepare a global styles config output for response. * * @since 5.9.0 * @since 6.6.0 Added custom relative theme file URIs to `_links`. * * @param WP_Post $post Global Styles post object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $post, $request ) { $raw_config = json_decode( $post->post_content, true ); $is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; $config = array(); $theme_json = null; if ( $is_global_styles_user_theme_json ) { $theme_json = new WP_Theme_JSON( $raw_config, 'custom' ); $config = $theme_json->get_raw_data(); } // Base fields for every post. $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'id', $fields ) ) { $data['id'] = $post->ID; } if ( rest_is_field_included( 'title', $fields ) ) { $data['title'] = array(); } if ( rest_is_field_included( 'title.raw', $fields ) ) { $data['title']['raw'] = $post->post_title; } if ( rest_is_field_included( 'title.rendered', $fields ) ) { add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); add_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); $data['title']['rendered'] = get_the_title( $post->ID ); remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) ); } if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass(); } if ( rest_is_field_included( 'styles', $fields ) ) { $data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass(); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); // Wrap the data in a response object. $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = $this->prepare_links( $post->ID ); // Only return resolved URIs for get requests to user theme JSON. if ( $theme_json ) { $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme_json ); if ( ! empty( $resolved_theme_uris ) ) { $links['https://api.w.org/theme-file'] = $resolved_theme_uris; } } $response->add_links( $links ); if ( ! empty( $links['self']['href'] ) ) { $actions = $this->get_available_actions( $post, $request ); $self = $links['self']['href']; foreach ( $actions as $rel ) { $response->add_link( $rel, $self ); } } } return $response; } /** * Prepares links for the request. * * @since 5.9.0 * @since 6.3.0 Adds revisions count and rest URL href to version-history. * * @param integer $id ID. * @return array Links for the given post. */ protected function prepare_links( $id ) { $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); $links = array( 'self' => array( 'href' => rest_url( trailingslashit( $base ) . $id ), ), 'about' => array( 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); if ( post_type_supports( $this->post_type, 'revisions' ) ) { $revisions = wp_get_latest_revision_id_and_total_count( $id ); $revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0; $revisions_base = sprintf( '/%s/%d/revisions', $base, $id ); $links['version-history'] = array( 'href' => rest_url( $revisions_base ), 'count' => $revisions_count, ); } return $links; } /** * Get the link relations available for the post and current user. * * @since 5.9.0 * @since 6.2.0 Added 'edit-css' action. * @since 6.6.0 Added $post and $request parameters. * * @param WP_Post $post Post object. * @param WP_REST_Request $request Request object. * @return array List of link relations. */ protected function get_available_actions( $post, $request ) { $rels = array(); $post_type = get_post_type_object( $post->post_type ); if ( current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-publish'; } if ( current_user_can( 'edit_css' ) ) { $rels[] = 'https://api.w.org/action-edit-css'; } return $rels; } /** * Retrieves the query params for the global styles collection. * * @since 5.9.0 * * @return array Collection parameters. */ public function get_collection_params() { return array(); } /** * Retrieves the global styles type' schema, conforming to JSON Schema. * * @since 5.9.0 * * @return array Item schema data. */ public function get_item_schema() { if ( $this->schema ) { return $this->add_additional_fields_schema( $this->schema ); } $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => $this->post_type, 'type' => 'object', 'properties' => array( 'id' => array( 'description' => __( 'ID of global styles config.' ), 'type' => 'string', 'context' => array( 'embed', 'view', 'edit' ), 'readonly' => true, ), 'styles' => array( 'description' => __( 'Global styles.' ), 'type' => array( 'object' ), 'context' => array( 'view', 'edit' ), ), 'settings' => array( 'description' => __( 'Global settings.' ), 'type' => array( 'object' ), 'context' => array( 'view', 'edit' ), ), 'title' => array( 'description' => __( 'Title of the global styles variation.' ), 'type' => array( 'object', 'string' ), 'default' => '', 'context' => array( 'embed', 'view', 'edit' ), 'properties' => array( 'raw' => array( 'description' => __( 'Title for the global styles variation, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), ), 'rendered' => array( 'description' => __( 'HTML title for the post, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), ), ), ), ); $this->schema = $schema; return $this->add_additional_fields_schema( $this->schema ); } /** * Checks if a given request has access to read a single theme global styles config. * * @since 5.9.0 * @since 6.7.0 Allow users with edit post capabilities to view theme global styles. * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_theme_item_permissions_check( $request ) { /* * Verify if the current user has edit_posts capability. * This capability is required to view global styles. */ if ( current_user_can( 'edit_posts' ) ) { return true; } foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { return true; } } /* * Verify if the current user has edit_theme_options capability. */ if ( current_user_can( 'edit_theme_options' ) ) { return true; } return new WP_Error( 'rest_cannot_read_global_styles', __( 'Sorry, you are not allowed to access the global styles on this site.' ), array( 'status' => rest_authorization_required_code(), ) ); } /** * Returns the given theme global styles config. * * @since 5.9.0 * @since 6.6.0 Added custom relative theme file URIs to `_links`. * * @param WP_REST_Request $request The request instance. * @return WP_REST_Response|WP_Error */ public function get_theme_item( $request ) { if ( get_stylesheet() !== $request['stylesheet'] ) { // This endpoint only supports the active theme for now. return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $theme = WP_Theme_JSON_Resolver::get_merged_data( 'theme' ); $fields = $this->get_fields_for_response( $request ); $data = array(); if ( rest_is_field_included( 'settings', $fields ) ) { $data['settings'] = $theme->get_settings(); } if ( rest_is_field_included( 'styles', $fields ) ) { $raw_data = $theme->get_raw_data(); $data['styles'] = isset( $raw_data['styles'] ) ? $raw_data['styles'] : array(); } $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); $response = rest_ensure_response( $data ); if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $links = array( 'self' => array( 'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ), ), ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $theme ); if ( ! empty( $resolved_theme_uris ) ) { $links['https://api.w.org/theme-file'] = $resolved_theme_uris; } $response->add_links( $links ); } return $response; } /** * Checks if a given request has access to read a single theme global styles config. * * @since 6.0.0 * @since 6.7.0 Allow users with edit post capabilities to view theme global styles. * * @param WP_REST_Request $request Full details about the request. * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. */ public function get_theme_items_permissions_check( $request ) { return $this->get_theme_item_permissions_check( $request ); } /** * Returns the given theme global styles variations. * * @since 6.0.0 * @since 6.2.0 Returns parent theme variations, if they exist. * @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 ) { if ( get_stylesheet() !== $request['stylesheet'] ) { // This endpoint only supports the active theme for now. return new WP_Error( 'rest_theme_not_found', __( 'Theme not found.' ), array( 'status' => 404 ) ); } $response = array(); // Register theme-defined variations e.g. from block style variation partials under `/styles`. $partials = WP_Theme_JSON_Resolver::get_style_variations( 'block' ); wp_register_block_style_variations_from_theme_json_partials( $partials ); $variations = WP_Theme_JSON_Resolver::get_style_variations(); foreach ( $variations as $variation ) { $variation_theme_json = new WP_Theme_JSON( $variation ); $resolved_theme_uris = WP_Theme_JSON_Resolver::get_resolved_theme_uris( $variation_theme_json ); $data = rest_ensure_response( $variation ); if ( ! empty( $resolved_theme_uris ) ) { $data->add_links( array( 'https://api.w.org/theme-file' => $resolved_theme_uris, ) ); } $response[] = $this->prepare_response_for_collection( $data ); } return rest_ensure_response( $response ); } /** * Validate style.css as valid CSS. * * Currently just checks for invalid markup. * * @since 6.2.0 * @since 6.4.0 Changed method visibility to protected. * * @param string $css CSS to validate. * @return true|WP_Error True if the input was validated, otherwise WP_Error. */ protected function validate_custom_css( $css ) { if ( preg_match( '#</?\w+#', $css ) ) { return new WP_Error( 'rest_custom_css_illegal_markup', __( 'Markup is not allowed in CSS.' ), array( 'status' => 400 ) ); } return true; } } <?php /** * REST API: WP_REST_Response class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement a REST response object. * * @since 4.4.0 * * @see WP_HTTP_Response */ class WP_REST_Response extends WP_HTTP_Response { /** * Links related to the response. * * @since 4.4.0 * @var array */ protected $links = array(); /** * The route that was to create the response. * * @since 4.4.0 * @var string */ protected $matched_route = ''; /** * The handler that was used to create the response. * * @since 4.4.0 * @var null|array */ protected $matched_handler = null; /** * Adds a link to the response. * * @internal The $rel parameter is first, as this looks nicer when sending multiple. * * @since 4.4.0 * * @link https://tools.ietf.org/html/rfc5988 * @link https://www.iana.org/assignments/link-relations/link-relations.xml * * @param string $rel Link relation. Either an IANA registered type, * or an absolute URL. * @param string $href Target URI for the link. * @param array $attributes Optional. Link parameters to send along with the URL. Default empty array. */ public function add_link( $rel, $href, $attributes = array() ) { if ( empty( $this->links[ $rel ] ) ) { $this->links[ $rel ] = array(); } if ( isset( $attributes['href'] ) ) { // Remove the href attribute, as it's used for the main URL. unset( $attributes['href'] ); } $this->links[ $rel ][] = array( 'href' => $href, 'attributes' => $attributes, ); } /** * Removes a link from the response. * * @since 4.4.0 * * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. * @param string $href Optional. Only remove links for the relation matching the given href. * Default null. */ public function remove_link( $rel, $href = null ) { if ( ! isset( $this->links[ $rel ] ) ) { return; } if ( $href ) { $this->links[ $rel ] = wp_list_filter( $this->links[ $rel ], array( 'href' => $href ), 'NOT' ); } else { $this->links[ $rel ] = array(); } if ( ! $this->links[ $rel ] ) { unset( $this->links[ $rel ] ); } } /** * Adds multiple links to the response. * * Link data should be an associative array with link relation as the key. * The value can either be an associative array of link attributes * (including `href` with the URL for the response), or a list of these * associative arrays. * * @since 4.4.0 * * @param array $links Map of link relation to list of links. */ public function add_links( $links ) { foreach ( $links as $rel => $set ) { // If it's a single link, wrap with an array for consistent handling. if ( isset( $set['href'] ) ) { $set = array( $set ); } foreach ( $set as $attributes ) { $this->add_link( $rel, $attributes['href'], $attributes ); } } } /** * Retrieves links for the response. * * @since 4.4.0 * * @return array List of links. */ public function get_links() { return $this->links; } /** * Sets a single link header. * * @internal The $rel parameter is first, as this looks nicer when sending multiple. * * @since 4.4.0 * * @link https://tools.ietf.org/html/rfc5988 * @link https://www.iana.org/assignments/link-relations/link-relations.xml * * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. * @param string $link Target IRI for the link. * @param array $other Optional. Other parameters to send, as an associative array. * Default empty array. */ public function link_header( $rel, $link, $other = array() ) { $header = '<' . $link . '>; rel="' . $rel . '"'; foreach ( $other as $key => $value ) { if ( 'title' === $key ) { $value = '"' . $value . '"'; } $header .= '; ' . $key . '=' . $value; } $this->header( 'Link', $header, false ); } /** * Retrieves the route that was used. * * @since 4.4.0 * * @return string The matched route. */ public function get_matched_route() { return $this->matched_route; } /** * Sets the route (regex for path) that caused the response. * * @since 4.4.0 * * @param string $route Route name. */ public function set_matched_route( $route ) { $this->matched_route = $route; } /** * Retrieves the handler that was used to generate the response. * * @since 4.4.0 * * @return null|array The handler that was used to create the response. */ public function get_matched_handler() { return $this->matched_handler; } /** * Sets the handler that was responsible for generating the response. * * @since 4.4.0 * * @param array $handler The matched handler. */ public function set_matched_handler( $handler ) { $this->matched_handler = $handler; } /** * Checks if the response is an error, i.e. >= 400 response code. * * @since 4.4.0 * * @return bool Whether the response is an error. */ public function is_error() { return $this->get_status() >= 400; } /** * Retrieves a WP_Error object from the response. * * @since 4.4.0 * * @return WP_Error|null WP_Error or null on not an errored response. */ public function as_error() { if ( ! $this->is_error() ) { return null; } $error = new WP_Error(); if ( is_array( $this->get_data() ) ) { $data = $this->get_data(); $error->add( $data['code'], $data['message'], $data['data'] ); if ( ! empty( $data['additional_errors'] ) ) { foreach ( $data['additional_errors'] as $err ) { $error->add( $err['code'], $err['message'], $err['data'] ); } } } else { $error->add( $this->get_status(), '', array( 'status' => $this->get_status() ) ); } return $error; } /** * Retrieves the CURIEs (compact URIs) used for relations. * * @since 4.5.0 * * @return array Compact URIs. */ public function get_curies() { $curies = array( array( 'name' => 'wp', 'href' => 'https://api.w.org/{rel}', 'templated' => true, ), ); /** * Filters extra CURIEs available on REST API responses. * * CURIEs allow a shortened version of URI relations. This allows a more * usable form for custom relations than using the full URI. These work * similarly to how XML namespaces work. * * Registered CURIES need to specify a name and URI template. This will * automatically transform URI relations into their shortened version. * The shortened relation follows the format `{name}:{rel}`. `{rel}` in * the URI template will be replaced with the `{rel}` part of the * shortened relation. * * For example, a CURIE with name `example` and URI template * `http://w.org/{rel}` would transform a `http://w.org/term` relation * into `example:term`. * * Well-behaved clients should expand and normalize these back to their * full URI relation, however some naive clients may not resolve these * correctly, so adding new CURIEs may break backward compatibility. * * @since 4.5.0 * * @param array $additional Additional CURIEs to register with the REST API. */ $additional = apply_filters( 'rest_response_link_curies', array() ); return array_merge( $curies, $additional ); } } <?php /** * REST API: WP_REST_Server class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement the WordPress REST API server. * * @since 4.4.0 */ #[AllowDynamicProperties] class WP_REST_Server { /** * Alias for GET transport method. * * @since 4.4.0 * @var string */ const READABLE = 'GET'; /** * Alias for POST transport method. * * @since 4.4.0 * @var string */ const CREATABLE = 'POST'; /** * Alias for POST, PUT, PATCH transport methods together. * * @since 4.4.0 * @var string */ const EDITABLE = 'POST, PUT, PATCH'; /** * Alias for DELETE transport method. * * @since 4.4.0 * @var string */ const DELETABLE = 'DELETE'; /** * Alias for GET, POST, PUT, PATCH & DELETE transport methods together. * * @since 4.4.0 * @var string */ const ALLMETHODS = 'GET, POST, PUT, PATCH, DELETE'; /** * Namespaces registered to the server. * * @since 4.4.0 * @var array */ protected $namespaces = array(); /** * Endpoints registered to the server. * * @since 4.4.0 * @var array */ protected $endpoints = array(); /** * Options defined for the routes. * * @since 4.4.0 * @var array */ protected $route_options = array(); /** * Caches embedded requests. * * @since 5.4.0 * @var array */ protected $embed_cache = array(); /** * Stores request objects that are currently being handled. * * @since 6.5.0 * @var array */ protected $dispatching_requests = array(); /** * Instantiates the REST server. * * @since 4.4.0 */ public function __construct() { $this->endpoints = array( // Meta endpoints. '/' => array( 'callback' => array( $this, 'get_index' ), 'methods' => 'GET', 'args' => array( 'context' => array( 'default' => 'view', ), ), ), '/batch/v1' => array( 'callback' => array( $this, 'serve_batch_request_v1' ), 'methods' => 'POST', 'args' => array( 'validation' => array( 'type' => 'string', 'enum' => array( 'require-all-validate', 'normal' ), 'default' => 'normal', ), 'requests' => array( 'required' => true, 'type' => 'array', 'maxItems' => $this->get_max_batch_size(), 'items' => array( 'type' => 'object', 'properties' => array( 'method' => array( 'type' => 'string', 'enum' => array( 'POST', 'PUT', 'PATCH', 'DELETE' ), 'default' => 'POST', ), 'path' => array( 'type' => 'string', 'required' => true, ), 'body' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => true, ), 'headers' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => array( 'type' => array( 'string', 'array' ), 'items' => array( 'type' => 'string', ), ), ), ), ), ), ), ), ); } /** * Checks the authentication headers if supplied. * * @since 4.4.0 * * @return WP_Error|null|true WP_Error indicates unsuccessful login, null indicates successful * or no authentication provided */ public function check_authentication() { /** * Filters REST API authentication errors. * * This is used to pass a WP_Error from an authentication method back to * the API. * * Authentication methods should check first if they're being used, as * multiple authentication methods can be enabled on a site (cookies, * HTTP basic auth, OAuth). If the authentication method hooked in is * not actually being attempted, null should be returned to indicate * another authentication method should check instead. Similarly, * callbacks should ensure the value is `null` before checking for * errors. * * A WP_Error instance can be returned if an error occurs, and this should * match the format used by API methods internally (that is, the `status` * data should be used). A callback can return `true` to indicate that * the authentication method was used, and it succeeded. * * @since 4.4.0 * * @param WP_Error|null|true $errors WP_Error if authentication error, null if authentication * method wasn't used, true if authentication succeeded. */ return apply_filters( 'rest_authentication_errors', null ); } /** * Converts an error to a response object. * * This iterates over all error codes and messages to change it into a flat * array. This enables simpler client behavior, as it is represented as a * list in JSON rather than an object/map. * * @since 4.4.0 * @since 5.7.0 Converted to a wrapper of {@see rest_convert_error_to_response()}. * * @param WP_Error $error WP_Error instance. * @return WP_REST_Response List of associative arrays with code and message keys. */ protected function error_to_response( $error ) { return rest_convert_error_to_response( $error ); } /** * Retrieves an appropriate error representation in JSON. * * Note: This should only be used in WP_REST_Server::serve_request(), as it * cannot handle WP_Error internally. All callbacks and other internal methods * should instead return a WP_Error with the data set to an array that includes * a 'status' key, with the value being the HTTP status to send. * * @since 4.4.0 * * @param string $code WP_Error-style code. * @param string $message Human-readable message. * @param int $status Optional. HTTP status code to send. Default null. * @return string JSON representation of the error */ protected function json_error( $code, $message, $status = null ) { if ( $status ) { $this->set_status( $status ); } $error = compact( 'code', 'message' ); return wp_json_encode( $error ); } /** * Gets the encoding options passed to {@see wp_json_encode}. * * @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 ) { $options = 0; if ( $request->has_param( '_pretty' ) ) { $options |= JSON_PRETTY_PRINT; } /** * Filters the JSON encoding options used to send the REST API response. * * @since 6.1.0 * * @param int $options JSON encoding options {@see json_encode()}. * @param WP_REST_Request $request Current request object. */ return apply_filters( 'rest_json_encode_options', $options, $request ); } /** * Handles serving a REST API request. * * Matches the current server URI to a route and runs the first matching * callback then outputs a JSON representation of the returned value. * * @since 4.4.0 * * @see WP_REST_Server::dispatch() * * @global WP_User $current_user The currently authenticated user. * * @param string $path Optional. The request route. If not set, `$_SERVER['PATH_INFO']` will be used. * Default null. * @return null|false Null if not served and a HEAD request, false otherwise. */ public function serve_request( $path = null ) { /* @var WP_User|null $current_user */ global $current_user; if ( $current_user instanceof WP_User && ! $current_user->exists() ) { /* * If there is no current user authenticated via other means, clear * the cached lack of user, so that an authenticate check can set it * properly. * * This is done because for authentications such as Application * Passwords, we don't want it to be accepted unless the current HTTP * request is a REST API request, which can't always be identified early * enough in evaluation. */ $current_user = null; } /** * Filters whether JSONP is enabled for the REST API. * * @since 4.4.0 * * @param bool $jsonp_enabled Whether JSONP is enabled. Default true. */ $jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true ); $jsonp_callback = false; if ( isset( $_GET['_jsonp'] ) ) { $jsonp_callback = $_GET['_jsonp']; } $content_type = ( $jsonp_callback && $jsonp_enabled ) ? 'application/javascript' : 'application/json'; $this->send_header( 'Content-Type', $content_type . '; charset=' . get_option( 'blog_charset' ) ); $this->send_header( 'X-Robots-Tag', 'noindex' ); $api_root = get_rest_url(); if ( ! empty( $api_root ) ) { $this->send_header( 'Link', '<' . sanitize_url( $api_root ) . '>; rel="https://api.w.org/"' ); } /* * Mitigate possible JSONP Flash attacks. * * https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ */ $this->send_header( 'X-Content-Type-Options', 'nosniff' ); /** * Filters whether the REST API is enabled. * * @since 4.4.0 * @deprecated 4.7.0 Use the {@see 'rest_authentication_errors'} filter to * restrict access to the REST API. * * @param bool $rest_enabled Whether the REST API is enabled. Default true. */ apply_filters_deprecated( 'rest_enabled', array( true ), '4.7.0', 'rest_authentication_errors', sprintf( /* translators: %s: rest_authentication_errors */ __( 'The REST API can no longer be completely disabled, the %s filter can be used to restrict access to the API, instead.' ), 'rest_authentication_errors' ) ); if ( $jsonp_callback ) { if ( ! $jsonp_enabled ) { echo $this->json_error( 'rest_callback_disabled', __( 'JSONP support is disabled on this site.' ), 400 ); return false; } if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) { echo $this->json_error( 'rest_callback_invalid', __( 'Invalid JSONP callback function.' ), 400 ); return false; } } if ( empty( $path ) ) { if ( isset( $_SERVER['PATH_INFO'] ) ) { $path = $_SERVER['PATH_INFO']; } else { $path = '/'; } } $request = new WP_REST_Request( $_SERVER['REQUEST_METHOD'], $path ); $request->set_query_params( wp_unslash( $_GET ) ); $request->set_body_params( wp_unslash( $_POST ) ); $request->set_file_params( $_FILES ); $request->set_headers( $this->get_headers( wp_unslash( $_SERVER ) ) ); $request->set_body( self::get_raw_data() ); /* * HTTP method override for clients that can't use PUT/PATCH/DELETE. First, we check * $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE * header. */ $method_overridden = false; if ( isset( $_GET['_method'] ) ) { $request->set_method( $_GET['_method'] ); } elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) { $request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ); $method_overridden = true; } $expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' ); /** * Filters the list of response headers that are exposed to REST API CORS requests. * * @since 5.5.0 * @since 6.3.0 The `$request` parameter was added. * * @param string[] $expose_headers The list of response headers to expose. * @param WP_REST_Request $request The request in context. */ $expose_headers = apply_filters( 'rest_exposed_cors_headers', $expose_headers, $request ); $this->send_header( 'Access-Control-Expose-Headers', implode( ', ', $expose_headers ) ); $allow_headers = array( 'Authorization', 'X-WP-Nonce', 'Content-Disposition', 'Content-MD5', 'Content-Type', ); /** * Filters the list of request headers that are allowed for REST API CORS requests. * * The allowed headers are passed to the browser to specify which * headers can be passed to the REST API. By default, we allow the * Content-* headers needed to upload files to the media endpoints. * As well as the Authorization and Nonce headers for allowing authentication. * * @since 5.5.0 * @since 6.3.0 The `$request` parameter was added. * * @param string[] $allow_headers The list of request headers to allow. * @param WP_REST_Request $request The request in context. */ $allow_headers = apply_filters( 'rest_allowed_cors_headers', $allow_headers, $request ); $this->send_header( 'Access-Control-Allow-Headers', implode( ', ', $allow_headers ) ); $result = $this->check_authentication(); if ( ! is_wp_error( $result ) ) { $result = $this->dispatch( $request ); } // Normalize to either WP_Error or WP_REST_Response... $result = rest_ensure_response( $result ); // ...then convert WP_Error across. if ( is_wp_error( $result ) ) { $result = $this->error_to_response( $result ); } /** * Filters the REST API response. * * Allows modification of the response before returning. * * @since 4.4.0 * @since 4.5.0 Applied to embedded responses. * * @param WP_HTTP_Response $result Result to send to the client. Usually a `WP_REST_Response`. * @param WP_REST_Server $server Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); // Wrap the response in an envelope if asked for. if ( isset( $_GET['_envelope'] ) ) { $embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false; $result = $this->envelope_response( $result, $embed ); } // Send extra data from response objects. $headers = $result->get_headers(); $this->send_headers( $headers ); $code = $result->get_status(); $this->set_status( $code ); /** * Filters whether to send no-cache headers on a REST API request. * * @since 4.4.0 * @since 6.3.2 Moved the block to catch the filter added on rest_cookie_check_errors() from wp-includes/rest-api.php. * * @param bool $rest_send_nocache_headers Whether to send no-cache headers. */ $send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() ); /* * Send no-cache headers if $send_no_cache_headers is true, * OR if the HTTP_X_HTTP_METHOD_OVERRIDE is used but resulted a 4xx response code. */ if ( $send_no_cache_headers || ( true === $method_overridden && str_starts_with( $code, '4' ) ) ) { foreach ( wp_get_nocache_headers() as $header => $header_value ) { if ( empty( $header_value ) ) { $this->remove_header( $header ); } else { $this->send_header( $header, $header_value ); } } } /** * Filters whether the REST API request has already been served. * * Allow sending the request manually - by returning true, the API result * will not be sent to the client. * * @since 4.4.0 * * @param bool $served Whether the request has already been served. * Default false. * @param WP_HTTP_Response $result Result to send to the client. Usually a `WP_REST_Response`. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. */ $served = apply_filters( 'rest_pre_serve_request', false, $result, $request, $this ); if ( ! $served ) { if ( 'HEAD' === $request->get_method() ) { return null; } // Embed links inside the request. $embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false; $result = $this->response_to_data( $result, $embed ); /** * Filters the REST API response. * * Allows modification of the response data after inserting * embedded data (if any) and before echoing the response data. * * @since 4.8.1 * * @param array $result Response data to send to the client. * @param WP_REST_Server $server Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_pre_echo_response', $result, $this, $request ); // The 204 response shouldn't have a body. if ( 204 === $code || null === $result ) { return null; } $result = wp_json_encode( $result, $this->get_json_encode_options( $request ) ); $json_error_message = $this->get_json_last_error(); if ( $json_error_message ) { $this->set_status( 500 ); $json_error_obj = new WP_Error( 'rest_encode_error', $json_error_message, array( 'status' => 500 ) ); $result = $this->error_to_response( $json_error_obj ); $result = wp_json_encode( $result->data, $this->get_json_encode_options( $request ) ); } if ( $jsonp_callback ) { // Prepend '/**/' to mitigate possible JSONP Flash attacks. // https://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ echo '/**/' . $jsonp_callback . '(' . $result . ')'; } else { echo $result; } } return null; } /** * Converts a response to data to send. * * @since 4.4.0 * @since 5.4.0 The `$embed` parameter can now contain a list of link relations to include. * * @param WP_REST_Response $response Response object. * @param bool|string[] $embed Whether to embed all links, a filtered list of link relations, or no links. * @return array { * Data with sub-requests embedded. * * @type array $_links Links. * @type array $_embedded Embedded objects. * } */ public function response_to_data( $response, $embed ) { $data = $response->get_data(); $links = self::get_compact_response_links( $response ); if ( ! empty( $links ) ) { // Convert links to part of the data. $data['_links'] = $links; } if ( $embed ) { $this->embed_cache = array(); // Determine if this is a numeric array. if ( wp_is_numeric_array( $data ) ) { foreach ( $data as $key => $item ) { $data[ $key ] = $this->embed_links( $item, $embed ); } } else { $data = $this->embed_links( $data, $embed ); } $this->embed_cache = array(); } return $data; } /** * Retrieves links from a response. * * Extracts the links from a response into a structured hash, suitable for * direct output. * * @since 4.4.0 * * @param WP_REST_Response $response Response to extract links from. * @return array Map of link relation to list of link hashes. */ public static function get_response_links( $response ) { $links = $response->get_links(); if ( empty( $links ) ) { return array(); } // Convert links to part of the data. $data = array(); foreach ( $links as $rel => $items ) { $data[ $rel ] = array(); foreach ( $items as $item ) { $attributes = $item['attributes']; $attributes['href'] = $item['href']; if ( 'self' !== $rel ) { $data[ $rel ][] = $attributes; continue; } $target_hints = self::get_target_hints_for_link( $attributes ); if ( $target_hints ) { $attributes['targetHints'] = $target_hints; } $data[ $rel ][] = $attributes; } } return $data; } /** * Gets the target links for a REST API Link. * * @since 6.7.0 * * @param array $link * * @return array|null */ protected static function get_target_hints_for_link( $link ) { // Prefer targetHints that were specifically designated by the developer. if ( isset( $link['targetHints']['allow'] ) ) { return null; } $request = WP_REST_Request::from_url( $link['href'] ); if ( ! $request ) { return null; } $server = rest_get_server(); $match = $server->match_request_to_handler( $request ); if ( is_wp_error( $match ) ) { return null; } if ( is_wp_error( $request->has_valid_params() ) ) { return null; } if ( is_wp_error( $request->sanitize_params() ) ) { return null; } $target_hints = array(); $response = new WP_REST_Response(); $response->set_matched_route( $match[0] ); $response->set_matched_handler( $match[1] ); $headers = rest_send_allow_header( $response, $server, $request )->get_headers(); foreach ( $headers as $name => $value ) { $name = WP_REST_Request::canonicalize_header_name( $name ); $target_hints[ $name ] = array_map( 'trim', explode( ',', $value ) ); } return $target_hints; } /** * Retrieves the CURIEs (compact URIs) used for relations. * * Extracts the links from a response into a structured hash, suitable for * direct output. * * @since 4.5.0 * * @param WP_REST_Response $response Response to extract links from. * @return array Map of link relation to list of link hashes. */ public static function get_compact_response_links( $response ) { $links = self::get_response_links( $response ); if ( empty( $links ) ) { return array(); } $curies = $response->get_curies(); $used_curies = array(); foreach ( $links as $rel => $items ) { // Convert $rel URIs to their compact versions if they exist. foreach ( $curies as $curie ) { $href_prefix = substr( $curie['href'], 0, strpos( $curie['href'], '{rel}' ) ); if ( ! str_starts_with( $rel, $href_prefix ) ) { continue; } // Relation now changes from '$uri' to '$curie:$relation'. $rel_regex = str_replace( '\{rel\}', '(.+)', preg_quote( $curie['href'], '!' ) ); preg_match( '!' . $rel_regex . '!', $rel, $matches ); if ( $matches ) { $new_rel = $curie['name'] . ':' . $matches[1]; $used_curies[ $curie['name'] ] = $curie; $links[ $new_rel ] = $items; unset( $links[ $rel ] ); break; } } } // Push the curies onto the start of the links array. if ( $used_curies ) { $links['curies'] = array_values( $used_curies ); } return $links; } /** * Embeds the links from the data into the request. * * @since 4.4.0 * @since 5.4.0 The `$embed` parameter can now contain a list of link relations to include. * * @param array $data Data from the request. * @param bool|string[] $embed Whether to embed all links or a filtered list of link relations. * @return array { * Data with sub-requests embedded. * * @type array $_links Links. * @type array $_embedded Embedded objects. * } */ protected function embed_links( $data, $embed = true ) { if ( empty( $data['_links'] ) ) { return $data; } $embedded = array(); foreach ( $data['_links'] as $rel => $links ) { /* * If a list of relations was specified, and the link relation * is not in the list of allowed relations, don't process the link. */ if ( is_array( $embed ) && ! in_array( $rel, $embed, true ) ) { continue; } $embeds = array(); foreach ( $links as $item ) { // Determine if the link is embeddable. if ( empty( $item['embeddable'] ) ) { // Ensure we keep the same order. $embeds[] = array(); continue; } if ( ! array_key_exists( $item['href'], $this->embed_cache ) ) { // Run through our internal routing and serve. $request = WP_REST_Request::from_url( $item['href'] ); if ( ! $request ) { $embeds[] = array(); continue; } // Embedded resources get passed context=embed. if ( empty( $request['context'] ) ) { $request['context'] = 'embed'; } if ( empty( $request['per_page'] ) ) { $matched = $this->match_request_to_handler( $request ); if ( ! is_wp_error( $matched ) && isset( $matched[1]['args']['per_page']['maximum'] ) ) { $request['per_page'] = (int) $matched[1]['args']['per_page']['maximum']; } } $response = $this->dispatch( $request ); /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ $response = apply_filters( 'rest_post_dispatch', rest_ensure_response( $response ), $this, $request ); $this->embed_cache[ $item['href'] ] = $this->response_to_data( $response, false ); } $embeds[] = $this->embed_cache[ $item['href'] ]; } // Determine if any real links were found. $has_links = count( array_filter( $embeds ) ); if ( $has_links ) { $embedded[ $rel ] = $embeds; } } if ( ! empty( $embedded ) ) { $data['_embedded'] = $embedded; } return $data; } /** * Wraps the response in an envelope. * * The enveloping technique is used to work around browser/client * compatibility issues. Essentially, it converts the full HTTP response to * data instead. * * @since 4.4.0 * @since 6.0.0 The `$embed` parameter can now contain a list of link relations to include. * * @param WP_REST_Response $response Response object. * @param bool|string[] $embed Whether to embed all links, a filtered list of link relations, or no links. * @return WP_REST_Response New response with wrapped data */ public function envelope_response( $response, $embed ) { $envelope = array( 'body' => $this->response_to_data( $response, $embed ), 'status' => $response->get_status(), 'headers' => $response->get_headers(), ); /** * Filters the enveloped form of a REST API response. * * @since 4.4.0 * * @param array $envelope { * Envelope data. * * @type array $body Response data. * @type int $status The 3-digit HTTP status code. * @type array $headers Map of header name to header value. * } * @param WP_REST_Response $response Original response data. */ $envelope = apply_filters( 'rest_envelope_response', $envelope, $response ); // Ensure it's still a response and return. return rest_ensure_response( $envelope ); } /** * Registers a route to the server. * * @since 4.4.0 * * @param string $route_namespace Namespace. * @param string $route The REST route. * @param array $route_args Route arguments. * @param bool $override Optional. Whether the route should be overridden if it already exists. * Default false. */ public function register_route( $route_namespace, $route, $route_args, $override = false ) { if ( ! isset( $this->namespaces[ $route_namespace ] ) ) { $this->namespaces[ $route_namespace ] = array(); $this->register_route( $route_namespace, '/' . $route_namespace, array( array( 'methods' => self::READABLE, 'callback' => array( $this, 'get_namespace_index' ), 'args' => array( 'namespace' => array( 'default' => $route_namespace, ), 'context' => array( 'default' => 'view', ), ), ), ) ); } // Associative to avoid double-registration. $this->namespaces[ $route_namespace ][ $route ] = true; $route_args['namespace'] = $route_namespace; if ( $override || empty( $this->endpoints[ $route ] ) ) { $this->endpoints[ $route ] = $route_args; } else { $this->endpoints[ $route ] = array_merge( $this->endpoints[ $route ], $route_args ); } } /** * Retrieves the route map. * * The route map is an associative array with path regexes as the keys. The * value is an indexed array with the callback function/method as the first * item, and a bitmask of HTTP methods as the second item (see the class * constants). * * Each route can be mapped to more than one callback by using an array of * the indexed arrays. This allows mapping e.g. GET requests to one callback * and POST requests to another. * * Note that the path regexes (array keys) must have @ escaped, as this is * used as the delimiter with preg_match() * * @since 4.4.0 * @since 5.4.0 Added `$route_namespace` parameter. * * @param string $route_namespace Optionally, only return routes in the given namespace. * @return array `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ), ...)`. */ public function get_routes( $route_namespace = '' ) { $endpoints = $this->endpoints; if ( $route_namespace ) { $endpoints = wp_list_filter( $endpoints, array( 'namespace' => $route_namespace ) ); } /** * Filters the array of available REST API endpoints. * * @since 4.4.0 * * @param array $endpoints The available endpoints. An array of matching regex patterns, each mapped * to an array of callbacks for the endpoint. These take the format * `'/path/regex' => array( $callback, $bitmask )` or * `'/path/regex' => array( array( $callback, $bitmask ). */ $endpoints = apply_filters( 'rest_endpoints', $endpoints ); // Normalize the endpoints. $defaults = array( 'methods' => '', 'accept_json' => false, 'accept_raw' => false, 'show_in_index' => true, 'args' => array(), ); foreach ( $endpoints as $route => &$handlers ) { if ( isset( $handlers['callback'] ) ) { // Single endpoint, add one deeper. $handlers = array( $handlers ); } if ( ! isset( $this->route_options[ $route ] ) ) { $this->route_options[ $route ] = array(); } foreach ( $handlers as $key => &$handler ) { if ( ! is_numeric( $key ) ) { // Route option, move it to the options. $this->route_options[ $route ][ $key ] = $handler; unset( $handlers[ $key ] ); continue; } $handler = wp_parse_args( $handler, $defaults ); // Allow comma-separated HTTP methods. if ( is_string( $handler['methods'] ) ) { $methods = explode( ',', $handler['methods'] ); } elseif ( is_array( $handler['methods'] ) ) { $methods = $handler['methods']; } else { $methods = array(); } $handler['methods'] = array(); foreach ( $methods as $method ) { $method = strtoupper( trim( $method ) ); $handler['methods'][ $method ] = true; } } } return $endpoints; } /** * Retrieves namespaces registered on the server. * * @since 4.4.0 * * @return string[] List of registered namespaces. */ public function get_namespaces() { return array_keys( $this->namespaces ); } /** * Retrieves specified options for a route. * * @since 4.4.0 * * @param string $route Route pattern to fetch options for. * @return array|null Data as an associative array if found, or null if not found. */ public function get_route_options( $route ) { if ( ! isset( $this->route_options[ $route ] ) ) { return null; } return $this->route_options[ $route ]; } /** * Matches the request to a callback and call it. * * @since 4.4.0 * * @param WP_REST_Request $request Request to attempt dispatching. * @return WP_REST_Response Response returned by the callback. */ public function dispatch( $request ) { $this->dispatching_requests[] = $request; /** * Filters the pre-calculated result of a REST API dispatch request. * * Allow hijacking the request before dispatching by returning a non-empty. The returned value * will be used to serve the request instead. * * @since 4.4.0 * * @param mixed $result Response to replace the requested version with. Can be anything * a normal endpoint can return, or null to not hijack the request. * @param WP_REST_Server $server Server instance. * @param WP_REST_Request $request Request used to generate the response. */ $result = apply_filters( 'rest_pre_dispatch', null, $this, $request ); if ( ! empty( $result ) ) { // Normalize to either WP_Error or WP_REST_Response... $result = rest_ensure_response( $result ); // ...then convert WP_Error across. if ( is_wp_error( $result ) ) { $result = $this->error_to_response( $result ); } array_pop( $this->dispatching_requests ); return $result; } $error = null; $matched = $this->match_request_to_handler( $request ); if ( is_wp_error( $matched ) ) { $response = $this->error_to_response( $matched ); array_pop( $this->dispatching_requests ); return $response; } list( $route, $handler ) = $matched; if ( ! is_callable( $handler['callback'] ) ) { $error = new WP_Error( 'rest_invalid_handler', __( 'The handler for the route is invalid.' ), array( 'status' => 500 ) ); } if ( ! is_wp_error( $error ) ) { $check_required = $request->has_valid_params(); if ( is_wp_error( $check_required ) ) { $error = $check_required; } else { $check_sanitized = $request->sanitize_params(); if ( is_wp_error( $check_sanitized ) ) { $error = $check_sanitized; } } } $response = $this->respond_to_request( $request, $route, $handler, $error ); array_pop( $this->dispatching_requests ); return $response; } /** * Returns whether the REST server is currently dispatching / responding to a request. * * This may be a standalone REST API request, or an internal request dispatched from within a regular page load. * * @since 6.5.0 * * @return bool Whether the REST server is currently handling a request. */ public function is_dispatching() { return (bool) $this->dispatching_requests; } /** * Matches a request object to its handler. * * @access private * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @return array|WP_Error The route and request handler on success or a WP_Error instance if no handler was found. */ protected function match_request_to_handler( $request ) { $method = $request->get_method(); $path = $request->get_route(); $with_namespace = array(); foreach ( $this->get_namespaces() as $namespace ) { if ( str_starts_with( trailingslashit( ltrim( $path, '/' ) ), $namespace ) ) { $with_namespace[] = $this->get_routes( $namespace ); } } if ( $with_namespace ) { $routes = array_merge( ...$with_namespace ); } else { $routes = $this->get_routes(); } foreach ( $routes as $route => $handlers ) { $match = preg_match( '@^' . $route . '$@i', $path, $matches ); if ( ! $match ) { continue; } $args = array(); foreach ( $matches as $param => $value ) { if ( ! is_int( $param ) ) { $args[ $param ] = $value; } } foreach ( $handlers as $handler ) { $callback = $handler['callback']; // Fallback to GET method if no HEAD method is registered. $checked_method = $method; if ( 'HEAD' === $method && empty( $handler['methods']['HEAD'] ) ) { $checked_method = 'GET'; } if ( empty( $handler['methods'][ $checked_method ] ) ) { continue; } if ( ! is_callable( $callback ) ) { return array( $route, $handler ); } $request->set_url_params( $args ); $request->set_attributes( $handler ); $defaults = array(); foreach ( $handler['args'] as $arg => $options ) { if ( isset( $options['default'] ) ) { $defaults[ $arg ] = $options['default']; } } $request->set_default_params( $defaults ); return array( $route, $handler ); } } return new WP_Error( 'rest_no_route', __( 'No route was found matching the URL and request method.' ), array( 'status' => 404 ) ); } /** * Dispatches the request to the callback handler. * * @access private * @since 5.6.0 * * @param WP_REST_Request $request The request object. * @param string $route The matched route regex. * @param array $handler The matched route handler. * @param WP_Error|null $response The current error object if any. * @return WP_REST_Response */ protected function respond_to_request( $request, $route, $handler, $response ) { /** * Filters the response before executing any REST API callbacks. * * Allows plugins to perform additional validation after a * request is initialized and matched to a registered route, * but before it is executed. * * Note that this filter will not be called for requests that * fail to authenticate or match to a registered route. * * @since 4.7.0 * * @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client. * Usually a WP_REST_Response or WP_Error. * @param array $handler Route handler used for the request. * @param WP_REST_Request $request Request used to generate the response. */ $response = apply_filters( 'rest_request_before_callbacks', $response, $handler, $request ); // Check permission specified on the route. if ( ! is_wp_error( $response ) && ! empty( $handler['permission_callback'] ) ) { $permission = call_user_func( $handler['permission_callback'], $request ); if ( is_wp_error( $permission ) ) { $response = $permission; } elseif ( false === $permission || null === $permission ) { $response = new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to do that.' ), array( 'status' => rest_authorization_required_code() ) ); } } if ( ! is_wp_error( $response ) ) { /** * Filters the REST API dispatch request result. * * Allow plugins to override dispatching the request. * * @since 4.4.0 * @since 4.5.0 Added `$route` and `$handler` parameters. * * @param mixed $dispatch_result Dispatch result, will be used if not empty. * @param WP_REST_Request $request Request used to generate the response. * @param string $route Route matched for the request. * @param array $handler Route handler used for the request. */ $dispatch_result = apply_filters( 'rest_dispatch_request', null, $request, $route, $handler ); // Allow plugins to halt the request via this filter. if ( null !== $dispatch_result ) { $response = $dispatch_result; } else { $response = call_user_func( $handler['callback'], $request ); } } /** * Filters the response immediately after executing any REST API * callbacks. * * Allows plugins to perform any needed cleanup, for example, * to undo changes made during the {@see 'rest_request_before_callbacks'} * filter. * * Note that this filter will not be called for requests that * fail to authenticate or match to a registered route. * * Note that an endpoint's `permission_callback` can still be * called after this filter - see `rest_send_allow_header()`. * * @since 4.7.0 * * @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client. * Usually a WP_REST_Response or WP_Error. * @param array $handler Route handler used for the request. * @param WP_REST_Request $request Request used to generate the response. */ $response = apply_filters( 'rest_request_after_callbacks', $response, $handler, $request ); if ( is_wp_error( $response ) ) { $response = $this->error_to_response( $response ); } else { $response = rest_ensure_response( $response ); } $response->set_matched_route( $route ); $response->set_matched_handler( $handler ); return $response; } /** * Returns if an error occurred during most recent JSON encode/decode. * * Strings to be translated will be in format like * "Encoding error: Maximum stack depth exceeded". * * @since 4.4.0 * * @return false|string Boolean false or string error message. */ protected function get_json_last_error() { $last_error_code = json_last_error(); if ( JSON_ERROR_NONE === $last_error_code || empty( $last_error_code ) ) { return false; } return json_last_error_msg(); } /** * Retrieves the site index. * * This endpoint describes the capabilities of the site. * * @since 4.4.0 * * @param array $request { * Request. * * @type string $context Context. * } * @return WP_REST_Response The API root index data. */ public function get_index( $request ) { // General site data. $available = array( 'name' => get_option( 'blogname' ), 'description' => get_option( 'blogdescription' ), 'url' => get_option( 'siteurl' ), 'home' => home_url(), 'gmt_offset' => get_option( 'gmt_offset' ), 'timezone_string' => get_option( 'timezone_string' ), 'page_for_posts' => (int) get_option( 'page_for_posts' ), 'page_on_front' => (int) get_option( 'page_on_front' ), 'show_on_front' => get_option( 'show_on_front' ), 'namespaces' => array_keys( $this->namespaces ), 'authentication' => array(), 'routes' => $this->get_data_for_routes( $this->get_routes(), $request['context'] ), ); $response = new WP_REST_Response( $available ); $fields = isset( $request['_fields'] ) ? $request['_fields'] : ''; $fields = wp_parse_list( $fields ); if ( empty( $fields ) ) { $fields[] = '_links'; } if ( $request->has_param( '_embed' ) ) { $fields[] = '_embedded'; } if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { $response->add_link( 'help', 'https://developer.wordpress.org/rest-api/' ); $this->add_active_theme_link_to_index( $response ); $this->add_site_logo_to_index( $response ); $this->add_site_icon_to_index( $response ); } else { if ( rest_is_field_included( 'site_logo', $fields ) ) { $this->add_site_logo_to_index( $response ); } if ( rest_is_field_included( 'site_icon', $fields ) || rest_is_field_included( 'site_icon_url', $fields ) ) { $this->add_site_icon_to_index( $response ); } } /** * Filters the REST API root index data. * * This contains the data describing the API. This includes information * about supported authentication schemes, supported namespaces, routes * available on the API, and a small amount of data about the site. * * @since 4.4.0 * @since 6.0.0 Added `$request` parameter. * * @param WP_REST_Response $response Response data. * @param WP_REST_Request $request Request data. */ return apply_filters( 'rest_index', $response, $request ); } /** * Adds a link to the active theme for users who have proper permissions. * * @since 5.7.0 * * @param WP_REST_Response $response REST API response. */ protected function add_active_theme_link_to_index( WP_REST_Response $response ) { $should_add = current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ); if ( ! $should_add && current_user_can( 'edit_posts' ) ) { $should_add = true; } if ( ! $should_add ) { foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( current_user_can( $post_type->cap->edit_posts ) ) { $should_add = true; break; } } } if ( $should_add ) { $theme = wp_get_theme(); $response->add_link( 'https://api.w.org/active-theme', rest_url( 'wp/v2/themes/' . $theme->get_stylesheet() ) ); } } /** * Exposes the site logo through the WordPress REST API. * * This is used for fetching this information when user has no rights * to update settings. * * @since 5.8.0 * * @param WP_REST_Response $response REST API response. */ protected function add_site_logo_to_index( WP_REST_Response $response ) { $site_logo_id = get_theme_mod( 'custom_logo', 0 ); $this->add_image_to_index( $response, $site_logo_id, 'site_logo' ); } /** * Exposes the site icon through the WordPress REST API. * * This is used for fetching this information when user has no rights * to update settings. * * @since 5.9.0 * * @param WP_REST_Response $response REST API response. */ protected function add_site_icon_to_index( WP_REST_Response $response ) { $site_icon_id = get_option( 'site_icon', 0 ); $this->add_image_to_index( $response, $site_icon_id, 'site_icon' ); $response->data['site_icon_url'] = get_site_icon_url(); } /** * Exposes an image through the WordPress REST API. * This is used for fetching this information when user has no rights * to update settings. * * @since 5.9.0 * * @param WP_REST_Response $response REST API response. * @param int $image_id Image attachment ID. * @param string $type Type of Image. */ protected function add_image_to_index( WP_REST_Response $response, $image_id, $type ) { $response->data[ $type ] = (int) $image_id; if ( $image_id ) { $response->add_link( 'https://api.w.org/featuredmedia', rest_url( rest_get_route_for_post( $image_id ) ), array( 'embeddable' => true, 'type' => $type, ) ); } } /** * Retrieves the index for a namespace. * * @since 4.4.0 * * @param WP_REST_Request $request REST request instance. * @return WP_REST_Response|WP_Error WP_REST_Response instance if the index was found, * WP_Error if the namespace isn't set. */ public function get_namespace_index( $request ) { $namespace = $request['namespace']; if ( ! isset( $this->namespaces[ $namespace ] ) ) { return new WP_Error( 'rest_invalid_namespace', __( 'The specified namespace could not be found.' ), array( 'status' => 404 ) ); } $routes = $this->namespaces[ $namespace ]; $endpoints = array_intersect_key( $this->get_routes(), $routes ); $data = array( 'namespace' => $namespace, 'routes' => $this->get_data_for_routes( $endpoints, $request['context'] ), ); $response = rest_ensure_response( $data ); // Link to the root index. $response->add_link( 'up', rest_url( '/' ) ); /** * Filters the REST API namespace index data. * * This typically is just the route data for the namespace, but you can * add any data you'd like here. * * @since 4.4.0 * * @param WP_REST_Response $response Response data. * @param WP_REST_Request $request Request data. The namespace is passed as the 'namespace' parameter. */ return apply_filters( 'rest_namespace_index', $response, $request ); } /** * Retrieves the publicly-visible data for routes. * * @since 4.4.0 * * @param array $routes Routes to get data for. * @param string $context Optional. Context for data. Accepts 'view' or 'help'. Default 'view'. * @return array[] Route data to expose in indexes, keyed by route. */ public function get_data_for_routes( $routes, $context = 'view' ) { $available = array(); // Find the available routes. foreach ( $routes as $route => $callbacks ) { $data = $this->get_data_for_route( $route, $callbacks, $context ); if ( empty( $data ) ) { continue; } /** * Filters the publicly-visible data for a single REST API route. * * @since 4.4.0 * * @param array $data Publicly-visible data for the route. */ $available[ $route ] = apply_filters( 'rest_endpoints_description', $data ); } /** * Filters the publicly-visible data for REST API routes. * * This data is exposed on indexes and can be used by clients or * developers to investigate the site and find out how to use it. It * acts as a form of self-documentation. * * @since 4.4.0 * * @param array[] $available Route data to expose in indexes, keyed by route. * @param array $routes Internal route data as an associative array. */ return apply_filters( 'rest_route_data', $available, $routes ); } /** * Retrieves publicly-visible data for the route. * * @since 4.4.0 * * @param string $route Route to get data for. * @param array $callbacks Callbacks to convert to data. * @param string $context Optional. Context for the data. Accepts 'view' or 'help'. Default 'view'. * @return array|null Data for the route, or null if no publicly-visible data. */ public function get_data_for_route( $route, $callbacks, $context = 'view' ) { $data = array( 'namespace' => '', 'methods' => array(), 'endpoints' => array(), ); $allow_batch = false; if ( isset( $this->route_options[ $route ] ) ) { $options = $this->route_options[ $route ]; if ( isset( $options['namespace'] ) ) { $data['namespace'] = $options['namespace']; } $allow_batch = isset( $options['allow_batch'] ) ? $options['allow_batch'] : false; if ( isset( $options['schema'] ) && 'help' === $context ) { $data['schema'] = call_user_func( $options['schema'] ); } } $allowed_schema_keywords = array_flip( rest_get_allowed_schema_keywords() ); $route = preg_replace( '#\(\?P<(\w+?)>.*?\)#', '{$1}', $route ); foreach ( $callbacks as $callback ) { // Skip to the next route if any callback is hidden. if ( empty( $callback['show_in_index'] ) ) { continue; } $data['methods'] = array_merge( $data['methods'], array_keys( $callback['methods'] ) ); $endpoint_data = array( 'methods' => array_keys( $callback['methods'] ), ); $callback_batch = isset( $callback['allow_batch'] ) ? $callback['allow_batch'] : $allow_batch; if ( $callback_batch ) { $endpoint_data['allow_batch'] = $callback_batch; } if ( isset( $callback['args'] ) ) { $endpoint_data['args'] = array(); foreach ( $callback['args'] as $key => $opts ) { if ( is_string( $opts ) ) { $opts = array( $opts => 0 ); } elseif ( ! is_array( $opts ) ) { $opts = array(); } $arg_data = array_intersect_key( $opts, $allowed_schema_keywords ); $arg_data['required'] = ! empty( $opts['required'] ); $endpoint_data['args'][ $key ] = $arg_data; } } $data['endpoints'][] = $endpoint_data; // For non-variable routes, generate links. if ( ! str_contains( $route, '{' ) ) { $data['_links'] = array( 'self' => array( array( 'href' => rest_url( $route ), ), ), ); } } if ( empty( $data['methods'] ) ) { // No methods supported, hide the route. return null; } return $data; } /** * Gets the maximum number of requests that can be included in a batch. * * @since 5.6.0 * * @return int The maximum requests. */ protected function get_max_batch_size() { /** * Filters the maximum number of REST API requests that can be included in a batch. * * @since 5.6.0 * * @param int $max_size The maximum size. */ return apply_filters( 'rest_get_max_batch_size', 25 ); } /** * Serves the batch/v1 request. * * @since 5.6.0 * * @param WP_REST_Request $batch_request The batch request object. * @return WP_REST_Response The generated response object. */ public function serve_batch_request_v1( WP_REST_Request $batch_request ) { $requests = array(); foreach ( $batch_request['requests'] as $args ) { $parsed_url = wp_parse_url( $args['path'] ); if ( false === $parsed_url ) { $requests[] = new WP_Error( 'parse_path_failed', __( 'Could not parse the path.' ), array( 'status' => 400 ) ); continue; } $single_request = new WP_REST_Request( isset( $args['method'] ) ? $args['method'] : 'POST', $parsed_url['path'] ); if ( ! empty( $parsed_url['query'] ) ) { $query_args = array(); wp_parse_str( $parsed_url['query'], $query_args ); $single_request->set_query_params( $query_args ); } if ( ! empty( $args['body'] ) ) { $single_request->set_body_params( $args['body'] ); } if ( ! empty( $args['headers'] ) ) { $single_request->set_headers( $args['headers'] ); } $requests[] = $single_request; } $matches = array(); $validation = array(); $has_error = false; foreach ( $requests as $single_request ) { $match = $this->match_request_to_handler( $single_request ); $matches[] = $match; $error = null; if ( is_wp_error( $match ) ) { $error = $match; } if ( ! $error ) { list( $route, $handler ) = $match; if ( isset( $handler['allow_batch'] ) ) { $allow_batch = $handler['allow_batch']; } else { $route_options = $this->get_route_options( $route ); $allow_batch = isset( $route_options['allow_batch'] ) ? $route_options['allow_batch'] : false; } if ( ! is_array( $allow_batch ) || empty( $allow_batch['v1'] ) ) { $error = new WP_Error( 'rest_batch_not_allowed', __( 'The requested route does not support batch requests.' ), array( 'status' => 400 ) ); } } if ( ! $error ) { $check_required = $single_request->has_valid_params(); if ( is_wp_error( $check_required ) ) { $error = $check_required; } } if ( ! $error ) { $check_sanitized = $single_request->sanitize_params(); if ( is_wp_error( $check_sanitized ) ) { $error = $check_sanitized; } } if ( $error ) { $has_error = true; $validation[] = $error; } else { $validation[] = true; } } $responses = array(); if ( $has_error && 'require-all-validate' === $batch_request['validation'] ) { foreach ( $validation as $valid ) { if ( is_wp_error( $valid ) ) { $responses[] = $this->envelope_response( $this->error_to_response( $valid ), false )->get_data(); } else { $responses[] = null; } } return new WP_REST_Response( array( 'failed' => 'validation', 'responses' => $responses, ), WP_Http::MULTI_STATUS ); } foreach ( $requests as $i => $single_request ) { $clean_request = clone $single_request; $clean_request->set_url_params( array() ); $clean_request->set_attributes( array() ); $clean_request->set_default_params( array() ); /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ $result = apply_filters( 'rest_pre_dispatch', null, $this, $clean_request ); if ( empty( $result ) ) { $match = $matches[ $i ]; $error = null; if ( is_wp_error( $validation[ $i ] ) ) { $error = $validation[ $i ]; } if ( is_wp_error( $match ) ) { $result = $this->error_to_response( $match ); } else { list( $route, $handler ) = $match; if ( ! $error && ! is_callable( $handler['callback'] ) ) { $error = new WP_Error( 'rest_invalid_handler', __( 'The handler for the route is invalid' ), array( 'status' => 500 ) ); } $result = $this->respond_to_request( $single_request, $route, $handler, $error ); } } /** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */ $result = apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $single_request ); $responses[] = $this->envelope_response( $result, false )->get_data(); } return new WP_REST_Response( array( 'responses' => $responses ), WP_Http::MULTI_STATUS ); } /** * Sends an HTTP status code. * * @since 4.4.0 * * @param int $code HTTP status. */ protected function set_status( $code ) { status_header( $code ); } /** * Sends an HTTP header. * * @since 4.4.0 * * @param string $key Header key. * @param string $value Header value. */ public function send_header( $key, $value ) { /* * Sanitize as per RFC2616 (Section 4.2): * * Any LWS that occurs between field-content MAY be replaced with a * single SP before interpreting the field value or forwarding the * message downstream. */ $value = preg_replace( '/\s+/', ' ', $value ); header( sprintf( '%s: %s', $key, $value ) ); } /** * Sends multiple HTTP headers. * * @since 4.4.0 * * @param array $headers Map of header name to header value. */ public function send_headers( $headers ) { foreach ( $headers as $key => $value ) { $this->send_header( $key, $value ); } } /** * Removes an HTTP header from the current response. * * @since 4.8.0 * * @param string $key Header key. */ public function remove_header( $key ) { header_remove( $key ); } /** * Retrieves the raw request entity (body). * * @since 4.4.0 * * @global string $HTTP_RAW_POST_DATA Raw post data. * * @return string Raw request data. */ public static function get_raw_data() { // phpcs:disable PHPCompatibility.Variables.RemovedPredefinedGlobalVariables.http_raw_post_dataDeprecatedRemoved global $HTTP_RAW_POST_DATA; // $HTTP_RAW_POST_DATA was deprecated in PHP 5.6 and removed in PHP 7.0. if ( ! isset( $HTTP_RAW_POST_DATA ) ) { $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } return $HTTP_RAW_POST_DATA; // phpcs:enable } /** * Extracts headers from a PHP-style $_SERVER array. * * @since 4.4.0 * * @param array $server Associative array similar to `$_SERVER`. * @return array Headers extracted from the input. */ public function get_headers( $server ) { $headers = array(); // CONTENT_* headers are not prefixed with HTTP_. $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true, ); foreach ( $server as $key => $value ) { if ( str_starts_with( $key, 'HTTP_' ) ) { $headers[ substr( $key, 5 ) ] = $value; } elseif ( 'REDIRECT_HTTP_AUTHORIZATION' === $key && empty( $server['HTTP_AUTHORIZATION'] ) ) { /* * In some server configurations, the authorization header is passed in this alternate location. * Since it would not be passed in in both places we do not check for both headers and resolve. */ $headers['AUTHORIZATION'] = $value; } elseif ( isset( $additional[ $key ] ) ) { $headers[ $key ] = $value; } } return $headers; } } <?php /** * REST API: WP_REST_Request class * * @package WordPress * @subpackage REST_API * @since 4.4.0 */ /** * Core class used to implement a REST request object. * * Contains data from the request, to be passed to the callback. * * Note: This implements ArrayAccess, and acts as an array of parameters when * used in that manner. It does not use ArrayObject (as we cannot rely on SPL), * so be aware it may have non-array behavior in some cases. * * Note: When using features provided by ArrayAccess, be aware that WordPress deliberately * does not distinguish between arguments of the same name for different request methods. * For instance, in a request with `GET id=1` and `POST id=2`, `$request['id']` will equal * 2 (`POST`) not 1 (`GET`). For more precision between request methods, use * WP_REST_Request::get_body_params(), WP_REST_Request::get_url_params(), etc. * * @since 4.4.0 * * @link https://www.php.net/manual/en/class.arrayaccess.php */ #[AllowDynamicProperties] class WP_REST_Request implements ArrayAccess { /** * HTTP method. * * @since 4.4.0 * @var string */ protected $method = ''; /** * Parameters passed to the request. * * These typically come from the `$_GET`, `$_POST` and `$_FILES` * superglobals when being created from the global scope. * * @since 4.4.0 * @var array Contains GET, POST and FILES keys mapping to arrays of data. */ protected $params; /** * HTTP headers for the request. * * @since 4.4.0 * @var array Map of key to value. Key is always lowercase, as per HTTP specification. */ protected $headers = array(); /** * Body data. * * @since 4.4.0 * @var string Binary data from the request. */ protected $body = null; /** * Route matched for the request. * * @since 4.4.0 * @var string */ protected $route; /** * Attributes (options) for the route that was matched. * * This is the options array used when the route was registered, typically * containing the callback as well as the valid methods for the route. * * @since 4.4.0 * @var array Attributes for the request. */ protected $attributes = array(); /** * Used to determine if the JSON data has been parsed yet. * * Allows lazy-parsing of JSON data where possible. * * @since 4.4.0 * @var bool */ protected $parsed_json = false; /** * Used to determine if the body data has been parsed yet. * * @since 4.4.0 * @var bool */ protected $parsed_body = false; /** * Constructor. * * @since 4.4.0 * * @param string $method Optional. Request method. Default empty. * @param string $route Optional. Request route. Default empty. * @param array $attributes Optional. Request attributes. Default empty array. */ public function __construct( $method = '', $route = '', $attributes = array() ) { $this->params = array( 'URL' => array(), 'GET' => array(), 'POST' => array(), 'FILES' => array(), // See parse_json_params. 'JSON' => null, 'defaults' => array(), ); $this->set_method( $method ); $this->set_route( $route ); $this->set_attributes( $attributes ); } /** * Retrieves the HTTP method for the request. * * @since 4.4.0 * * @return string HTTP method. */ public function get_method() { return $this->method; } /** * Sets HTTP method for the request. * * @since 4.4.0 * * @param string $method HTTP method. */ public function set_method( $method ) { $this->method = strtoupper( $method ); } /** * Retrieves all headers from the request. * * @since 4.4.0 * * @return array Map of key to value. Key is always lowercase, as per HTTP specification. */ public function get_headers() { return $this->headers; } /** * Determines if the request is the given method. * * @since 6.8.0 * * @param string $method HTTP method. * @return bool Whether the request is of the given method. */ public function is_method( $method ) { return $this->get_method() === strtoupper( $method ); } /** * Canonicalizes the header name. * * Ensures that header names are always treated the same regardless of * source. Header names are always case-insensitive. * * Note that we treat `-` (dashes) and `_` (underscores) as the same * character, as per header parsing rules in both Apache and nginx. * * @link https://stackoverflow.com/q/18185366 * @link https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#missing-disappearing-http-headers * @link https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers * * @since 4.4.0 * * @param string $key Header name. * @return string Canonicalized name. */ public static function canonicalize_header_name( $key ) { $key = strtolower( $key ); $key = str_replace( '-', '_', $key ); return $key; } /** * Retrieves the given header from the request. * * If the header has multiple values, they will be concatenated with a comma * as per the HTTP specification. Be aware that some non-compliant headers * (notably cookie headers) cannot be joined this way. * * @since 4.4.0 * * @param string $key Header name, will be canonicalized to lowercase. * @return string|null String value if set, null otherwise. */ public function get_header( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return implode( ',', $this->headers[ $key ] ); } /** * Retrieves header values from the request. * * @since 4.4.0 * * @param string $key Header name, will be canonicalized to lowercase. * @return array|null List of string values if set, null otherwise. */ public function get_header_as_array( $key ) { $key = $this->canonicalize_header_name( $key ); if ( ! isset( $this->headers[ $key ] ) ) { return null; } return $this->headers[ $key ]; } /** * Sets the header on request. * * @since 4.4.0 * * @param string $key Header name. * @param string $value Header value, or list of values. */ public function set_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; $this->headers[ $key ] = $value; } /** * Appends a header value for the given header. * * @since 4.4.0 * * @param string $key Header name. * @param string $value Header value, or list of values. */ public function add_header( $key, $value ) { $key = $this->canonicalize_header_name( $key ); $value = (array) $value; if ( ! isset( $this->headers[ $key ] ) ) { $this->headers[ $key ] = array(); } $this->headers[ $key ] = array_merge( $this->headers[ $key ], $value ); } /** * Removes all values for a header. * * @since 4.4.0 * * @param string $key Header name. */ public function remove_header( $key ) { $key = $this->canonicalize_header_name( $key ); unset( $this->headers[ $key ] ); } /** * Sets headers on the request. * * @since 4.4.0 * * @param array $headers Map of header name to value. * @param bool $override If true, replace the request's headers. Otherwise, merge with existing. */ public function set_headers( $headers, $override = true ) { if ( true === $override ) { $this->headers = array(); } foreach ( $headers as $key => $value ) { $this->set_header( $key, $value ); } } /** * Retrieves the Content-Type of the request. * * @since 4.4.0 * * @return array|null Map containing 'value' and 'parameters' keys * or null when no valid Content-Type header was * available. */ public function get_content_type() { $value = $this->get_header( 'Content-Type' ); if ( empty( $value ) ) { return null; } $parameters = ''; if ( strpos( $value, ';' ) ) { list( $value, $parameters ) = explode( ';', $value, 2 ); } $value = strtolower( $value ); if ( ! str_contains( $value, '/' ) ) { return null; } // Parse type and subtype out. list( $type, $subtype ) = explode( '/', $value, 2 ); $data = compact( 'value', 'type', 'subtype', 'parameters' ); $data = array_map( 'trim', $data ); return $data; } /** * Checks if the request has specified a JSON Content-Type. * * @since 5.6.0 * * @return bool True if the Content-Type header is JSON. */ public function is_json_content_type() { $content_type = $this->get_content_type(); return isset( $content_type['value'] ) && wp_is_json_media_type( $content_type['value'] ); } /** * Retrieves the parameter priority order. * * Used when checking parameters in WP_REST_Request::get_param(). * * @since 4.4.0 * * @return string[] Array of types to check, in order of priority. */ protected function get_parameter_order() { $order = array(); if ( $this->is_json_content_type() ) { $order[] = 'JSON'; } $this->parse_json_params(); // Ensure we parse the body data. $body = $this->get_body(); if ( 'POST' !== $this->method && ! empty( $body ) ) { $this->parse_body_params(); } $accepts_body_data = array( 'POST', 'PUT', 'PATCH', 'DELETE' ); if ( in_array( $this->method, $accepts_body_data, true ) ) { $order[] = 'POST'; } $order[] = 'GET'; $order[] = 'URL'; $order[] = 'defaults'; /** * Filters the parameter priority order for a REST API request. * * The order affects which parameters are checked when using WP_REST_Request::get_param() * and family. This acts similarly to PHP's `request_order` setting. * * @since 4.4.0 * * @param string[] $order Array of types to check, in order of priority. * @param WP_REST_Request $request The request object. */ return apply_filters( 'rest_request_parameter_order', $order, $this ); } /** * Retrieves a parameter from the request. * * @since 4.4.0 * * @param string $key Parameter name. * @return mixed|null Value if set, null otherwise. */ public function get_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { // Determine if we have the parameter for this type. if ( isset( $this->params[ $type ][ $key ] ) ) { return $this->params[ $type ][ $key ]; } } return null; } /** * Checks if a parameter exists in the request. * * This allows distinguishing between an omitted parameter, * and a parameter specifically set to null. * * @since 5.3.0 * * @param string $key Parameter name. * @return bool True if a param exists for the given key. */ public function has_param( $key ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { return true; } } return false; } /** * Sets a parameter on the request. * * If the given parameter key exists in any parameter type an update will take place, * otherwise a new param will be created in the first parameter type (respecting * get_parameter_order()). * * @since 4.4.0 * * @param string $key Parameter name. * @param mixed $value Parameter value. */ public function set_param( $key, $value ) { $order = $this->get_parameter_order(); $found_key = false; foreach ( $order as $type ) { if ( 'defaults' !== $type && is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) { $this->params[ $type ][ $key ] = $value; $found_key = true; } } if ( ! $found_key ) { $this->params[ $order[0] ][ $key ] = $value; } } /** * Retrieves merged parameters from the request. * * The equivalent of get_param(), but returns all parameters for the request. * Handles merging all the available values into a single array. * * @since 4.4.0 * * @return array Map of key to value. */ public function get_params() { $order = $this->get_parameter_order(); $order = array_reverse( $order, true ); $params = array(); foreach ( $order as $type ) { /* * array_merge() / the "+" operator will mess up * numeric keys, so instead do a manual foreach. */ foreach ( (array) $this->params[ $type ] as $key => $value ) { $params[ $key ] = $value; } } // Exclude rest_route if pretty permalinks are not enabled. if ( ! get_option( 'permalink_structure' ) ) { unset( $params['rest_route'] ); } return $params; } /** * Retrieves parameters from the route itself. * * These are parsed from the URL using the regex. * * @since 4.4.0 * * @return array Parameter map of key to value. */ public function get_url_params() { return $this->params['URL']; } /** * Sets parameters from the route. * * Typically, this is set after parsing the URL. * * @since 4.4.0 * * @param array $params Parameter map of key to value. */ public function set_url_params( $params ) { $this->params['URL'] = $params; } /** * Retrieves parameters from the query string. * * These are the parameters you'd typically find in `$_GET`. * * @since 4.4.0 * * @return array Parameter map of key to value */ public function get_query_params() { return $this->params['GET']; } /** * Sets parameters from the query string. * * Typically, this is set from `$_GET`. * * @since 4.4.0 * * @param array $params Parameter map of key to value. */ public function set_query_params( $params ) { $this->params['GET'] = $params; } /** * Retrieves parameters from the body. * * These are the parameters you'd typically find in `$_POST`. * * @since 4.4.0 * * @return array Parameter map of key to value. */ public function get_body_params() { return $this->params['POST']; } /** * Sets parameters from the body. * * Typically, this is set from `$_POST`. * * @since 4.4.0 * * @param array $params Parameter map of key to value. */ public function set_body_params( $params ) { $this->params['POST'] = $params; } /** * Retrieves multipart file parameters from the body. * * These are the parameters you'd typically find in `$_FILES`. * * @since 4.4.0 * * @return array Parameter map of key to value */ public function get_file_params() { return $this->params['FILES']; } /** * Sets multipart file parameters from the body. * * Typically, this is set from `$_FILES`. * * @since 4.4.0 * * @param array $params Parameter map of key to value. */ public function set_file_params( $params ) { $this->params['FILES'] = $params; } /** * Retrieves the default parameters. * * These are the parameters set in the route registration. * * @since 4.4.0 * * @return array Parameter map of key to value */ public function get_default_params() { return $this->params['defaults']; } /** * Sets default parameters. * * These are the parameters set in the route registration. * * @since 4.4.0 * * @param array $params Parameter map of key to value. */ public function set_default_params( $params ) { $this->params['defaults'] = $params; } /** * Retrieves the request body content. * * @since 4.4.0 * * @return string Binary data from the request body. */ public function get_body() { return $this->body; } /** * Sets body content. * * @since 4.4.0 * * @param string $data Binary data from the request body. */ public function set_body( $data ) { $this->body = $data; // Enable lazy parsing. $this->parsed_json = false; $this->parsed_body = false; $this->params['JSON'] = null; } /** * Retrieves the parameters from a JSON-formatted body. * * @since 4.4.0 * * @return array Parameter map of key to value. */ public function get_json_params() { // Ensure the parameters have been parsed out. $this->parse_json_params(); return $this->params['JSON']; } /** * Parses the JSON parameters. * * Avoids parsing the JSON data until we need to access it. * * @since 4.4.0 * @since 4.7.0 Returns error instance if value cannot be decoded. * @return true|WP_Error True if the JSON data was passed or no JSON data was provided, WP_Error if invalid JSON was passed. */ protected function parse_json_params() { if ( $this->parsed_json ) { return true; } $this->parsed_json = true; // Check that we actually got JSON. if ( ! $this->is_json_content_type() ) { return true; } $body = $this->get_body(); if ( empty( $body ) ) { return true; } $params = json_decode( $body, true ); /* * Check for a parsing error. */ if ( null === $params && JSON_ERROR_NONE !== json_last_error() ) { // Ensure subsequent calls receive error instance. $this->parsed_json = false; $error_data = array( 'status' => WP_Http::BAD_REQUEST, 'json_error_code' => json_last_error(), 'json_error_message' => json_last_error_msg(), ); return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data ); } $this->params['JSON'] = $params; return true; } /** * Parses the request body parameters. * * Parses out URL-encoded bodies for request methods that aren't supported * natively by PHP. * * @since 4.4.0 */ protected function parse_body_params() { if ( $this->parsed_body ) { return; } $this->parsed_body = true; /* * Check that we got URL-encoded. Treat a missing Content-Type as * URL-encoded for maximum compatibility. */ $content_type = $this->get_content_type(); if ( ! empty( $content_type ) && 'application/x-www-form-urlencoded' !== $content_type['value'] ) { return; } parse_str( $this->get_body(), $params ); /* * Add to the POST parameters stored internally. If a user has already * set these manually (via `set_body_params`), don't override them. */ $this->params['POST'] = array_merge( $params, $this->params['POST'] ); } /** * Retrieves the route that matched the request. * * @since 4.4.0 * * @return string Route matching regex. */ public function get_route() { return $this->route; } /** * Sets the route that matched the request. * * @since 4.4.0 * * @param string $route Route matching regex. */ public function set_route( $route ) { $this->route = $route; } /** * Retrieves the attributes for the request. * * These are the options for the route that was matched. * * @since 4.4.0 * * @return array Attributes for the request. */ public function get_attributes() { return $this->attributes; } /** * Sets the attributes for the request. * * @since 4.4.0 * * @param array $attributes Attributes for the request. */ public function set_attributes( $attributes ) { $this->attributes = $attributes; } /** * Sanitizes (where possible) the params on the request. * * This is primarily based off the sanitize_callback param on each registered * argument. * * @since 4.4.0 * * @return true|WP_Error True if parameters were sanitized, WP_Error if an error occurred during sanitization. */ public function sanitize_params() { $attributes = $this->get_attributes(); // No arguments set, skip sanitizing. if ( empty( $attributes['args'] ) ) { return true; } $order = $this->get_parameter_order(); $invalid_params = array(); $invalid_details = array(); foreach ( $order as $type ) { if ( empty( $this->params[ $type ] ) ) { continue; } foreach ( $this->params[ $type ] as $key => $value ) { if ( ! isset( $attributes['args'][ $key ] ) ) { continue; } $param_args = $attributes['args'][ $key ]; // If the arg has a type but no sanitize_callback attribute, default to rest_parse_request_arg. if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) { $param_args['sanitize_callback'] = 'rest_parse_request_arg'; } // If there's still no sanitize_callback, nothing to do here. if ( empty( $param_args['sanitize_callback'] ) ) { continue; } /** @var mixed|WP_Error $sanitized_value */ $sanitized_value = call_user_func( $param_args['sanitize_callback'], $value, $this, $key ); if ( is_wp_error( $sanitized_value ) ) { $invalid_params[ $key ] = implode( ' ', $sanitized_value->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $sanitized_value )->get_data(); } else { $this->params[ $type ][ $key ] = $sanitized_value; } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: List of invalid parameters. */ sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } return true; } /** * Checks whether this request is valid according to its attributes. * * @since 4.4.0 * * @return true|WP_Error True if there are no parameters to validate or if all pass validation, * WP_Error if required parameters are missing. */ public function has_valid_params() { // If JSON data was passed, check for errors. $json_error = $this->parse_json_params(); if ( is_wp_error( $json_error ) ) { return $json_error; } $attributes = $this->get_attributes(); $required = array(); $args = empty( $attributes['args'] ) ? array() : $attributes['args']; foreach ( $args as $key => $arg ) { $param = $this->get_param( $key ); if ( isset( $arg['required'] ) && true === $arg['required'] && null === $param ) { $required[] = $key; } } if ( ! empty( $required ) ) { return new WP_Error( 'rest_missing_callback_param', /* translators: %s: List of required parameters. */ sprintf( __( 'Missing parameter(s): %s' ), implode( ', ', $required ) ), array( 'status' => 400, 'params' => $required, ) ); } /* * Check the validation callbacks for each registered arg. * * This is done after required checking as required checking is cheaper. */ $invalid_params = array(); $invalid_details = array(); foreach ( $args as $key => $arg ) { $param = $this->get_param( $key ); if ( null !== $param && ! empty( $arg['validate_callback'] ) ) { /** @var bool|\WP_Error $valid_check */ $valid_check = call_user_func( $arg['validate_callback'], $param, $this, $key ); if ( false === $valid_check ) { $invalid_params[ $key ] = __( 'Invalid parameter.' ); } if ( is_wp_error( $valid_check ) ) { $invalid_params[ $key ] = implode( ' ', $valid_check->get_error_messages() ); $invalid_details[ $key ] = rest_convert_error_to_response( $valid_check )->get_data(); } } } if ( $invalid_params ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: List of invalid parameters. */ sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ), array( 'status' => 400, 'params' => $invalid_params, 'details' => $invalid_details, ) ); } if ( isset( $attributes['validate_callback'] ) ) { $valid_check = call_user_func( $attributes['validate_callback'], $this ); if ( is_wp_error( $valid_check ) ) { return $valid_check; } if ( false === $valid_check ) { // A WP_Error instance is preferred, but false is supported for parity with the per-arg validate_callback. return new WP_Error( 'rest_invalid_params', __( 'Invalid parameters.' ), array( 'status' => 400 ) ); } } return true; } /** * Checks if a parameter is set. * * @since 4.4.0 * * @param string $offset Parameter name. * @return bool Whether the parameter is set. */ #[ReturnTypeWillChange] public function offsetExists( $offset ) { $order = $this->get_parameter_order(); foreach ( $order as $type ) { if ( isset( $this->params[ $type ][ $offset ] ) ) { return true; } } return false; } /** * Retrieves a parameter from the request. * * @since 4.4.0 * * @param string $offset Parameter name. * @return mixed|null Value if set, null otherwise. */ #[ReturnTypeWillChange] public function offsetGet( $offset ) { return $this->get_param( $offset ); } /** * Sets a parameter on the request. * * @since 4.4.0 * * @param string $offset Parameter name. * @param mixed $value Parameter value. */ #[ReturnTypeWillChange] public function offsetSet( $offset, $value ) { $this->set_param( $offset, $value ); } /** * Removes a parameter from the request. * * @since 4.4.0 * * @param string $offset Parameter name. */ #[ReturnTypeWillChange] public function offsetUnset( $offset ) { $order = $this->get_parameter_order(); // Remove the offset from every group. foreach ( $order as $type ) { unset( $this->params[ $type ][ $offset ] ); } } /** * Retrieves a WP_REST_Request object from a full URL. * * @since 4.5.0 * * @param string $url URL with protocol, domain, path and query args. * @return WP_REST_Request|false WP_REST_Request object on success, false on failure. */ public static function from_url( $url ) { $bits = parse_url( $url ); $query_params = array(); if ( ! empty( $bits['query'] ) ) { wp_parse_str( $bits['query'], $query_params ); } $api_root = rest_url(); if ( get_option( 'permalink_structure' ) && str_starts_with( $url, $api_root ) ) { // Pretty permalinks on, and URL is under the API root. $api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) ); $route = parse_url( $api_url_part, PHP_URL_PATH ); } elseif ( ! empty( $query_params['rest_route'] ) ) { // ?rest_route=... set directly. $route = $query_params['rest_route']; unset( $query_params['rest_route'] ); } $request = false; if ( ! empty( $route ) ) { $request = new WP_REST_Request( 'GET', $route ); $request->set_query_params( $query_params ); } /** * Filters the REST API request generated from a URL. * * @since 4.5.0 * * @param WP_REST_Request|false $request Generated request object, or false if URL * could not be parsed. * @param string $url URL the request was generated from. */ return apply_filters( 'rest_request_from_url', $request, $url ); } } <?php /** * Block Metadata Registry * * @package WordPress * @subpackage Blocks * @since 6.7.0 */ /** * Class used for managing block metadata collections. * * The WP_Block_Metadata_Registry allows plugins to register metadata for large * collections of blocks (e.g., 50-100+) using a single PHP file. This approach * reduces the need to read and decode multiple `block.json` files, enhancing * performance through opcode caching. * * @since 6.7.0 */ class WP_Block_Metadata_Registry { /** * Container for storing block metadata collections. * * Each entry maps a base path to its corresponding metadata and callback. * * @since 6.7.0 * @var array<string, array<string, mixed>> */ private static $collections = array(); /** * Caches the last matched collection path for performance optimization. * * @since 6.7.0 * @var string|null */ private static $last_matched_collection = null; /** * Stores the default allowed collection root paths. * * @since 6.7.2 * @var string[]|null */ private static $default_collection_roots = null; /** * Registers a block metadata collection. * * This method allows registering a collection of block metadata from a single * manifest file, improving performance for large sets of blocks. * * The manifest file should be a PHP file that returns an associative array, where * the keys are the block identifiers (without their namespace) and the values are * the corresponding block metadata arrays. The block identifiers must match the * parent directory name for the respective `block.json` file. * * Example manifest file structure: * ``` * return array( * 'example-block' => array( * 'title' => 'Example Block', * 'category' => 'widgets', * 'icon' => 'smiley', * // ... other block metadata * ), * 'another-block' => array( * 'title' => 'Another Block', * 'category' => 'formatting', * 'icon' => 'star-filled', * // ... other block metadata * ), * // ... more block metadata entries * ); * ``` * * @since 6.7.0 * * @param string $path The absolute base path for the collection ( e.g., WP_PLUGIN_DIR . '/my-plugin/blocks/' ). * @param string $manifest The absolute path to the manifest file containing the metadata collection. * @return bool True if the collection was registered successfully, false otherwise. */ public static function register_collection( $path, $manifest ) { $path = rtrim( wp_normalize_path( $path ), '/' ); $collection_roots = self::get_default_collection_roots(); /** * Filters the root directory paths for block metadata collections. * * Any block metadata collection that is registered must not use any of these paths, or any parent directory * path of them. Most commonly, block metadata collections should reside within one of these paths, though in * some scenarios they may also reside in entirely different directories (e.g. in case of symlinked plugins). * * Example: * * It is allowed to register a collection with path `WP_PLUGIN_DIR . '/my-plugin'`. * * It is not allowed to register a collection with path `WP_PLUGIN_DIR`. * * It is not allowed to register a collection with path `dirname( WP_PLUGIN_DIR )`. * * The default list encompasses the `wp-includes` directory, as well as the root directories for plugins, * must-use plugins, and themes. This filter can be used to expand the list, e.g. to custom directories that * contain symlinked plugins, so that these root directories cannot be used themselves for a block metadata * collection either. * * @since 6.7.2 * * @param string[] $collection_roots List of allowed metadata collection root paths. */ $collection_roots = apply_filters( 'wp_allowed_block_metadata_collection_roots', $collection_roots ); $collection_roots = array_unique( array_map( static function ( $allowed_root ) { return rtrim( wp_normalize_path( $allowed_root ), '/' ); }, $collection_roots ) ); // Check if the path is valid: if ( ! self::is_valid_collection_path( $path, $collection_roots ) ) { _doing_it_wrong( __METHOD__, sprintf( /* translators: %s: list of allowed collection roots */ __( 'Block metadata collections cannot be registered as one of the following directories or their parent directories: %s' ), esc_html( implode( wp_get_list_item_separator(), $collection_roots ) ) ), '6.7.2' ); return false; } if ( ! file_exists( $manifest ) ) { _doing_it_wrong( __METHOD__, __( 'The specified manifest file does not exist.' ), '6.7.0' ); return false; } self::$collections[ $path ] = array( 'manifest' => $manifest, 'metadata' => null, ); return true; } /** * Retrieves block metadata for a given block within a specific collection. * * This method uses the registered collections to efficiently lookup * block metadata without reading individual `block.json` files. * * @since 6.7.0 * * @param string $file_or_folder The path to the file or folder containing the block. * @return array|null The block metadata for the block, or null if not found. */ public static function get_metadata( $file_or_folder ) { $file_or_folder = wp_normalize_path( $file_or_folder ); $path = self::find_collection_path( $file_or_folder ); if ( ! $path ) { return null; } $collection = &self::$collections[ $path ]; if ( null === $collection['metadata'] ) { // Load the manifest file if not already loaded $collection['metadata'] = require $collection['manifest']; } // Get the block name from the path. $block_name = self::default_identifier_callback( $file_or_folder ); return isset( $collection['metadata'][ $block_name ] ) ? $collection['metadata'][ $block_name ] : null; } /** * Gets the list of absolute paths to all block metadata files that are part of the given collection. * * For instance, if a block metadata collection is registered with path `WP_PLUGIN_DIR . '/my-plugin/blocks/'`, * and the manifest file includes metadata for two blocks `'block-a'` and `'block-b'`, the result of this method * will be an array containing: * * `WP_PLUGIN_DIR . '/my-plugin/blocks/block-a/block.json'` * * `WP_PLUGIN_DIR . '/my-plugin/blocks/block-b/block.json'` * * @since 6.8.0 * * @param string $path The absolute base path for a previously registered collection. * @return string[] List of block metadata file paths, or an empty array if the given `$path` is invalid. */ public static function get_collection_block_metadata_files( $path ) { $path = rtrim( wp_normalize_path( $path ), '/' ); if ( ! isset( self::$collections[ $path ] ) ) { _doing_it_wrong( __METHOD__, __( 'No registered block metadata collection was found for the provided path.' ), '6.8.0' ); return array(); } $collection = &self::$collections[ $path ]; if ( null === $collection['metadata'] ) { // Load the manifest file if not already loaded. $collection['metadata'] = require $collection['manifest']; } return array_map( // No normalization necessary since `$path` is already normalized and `$block_name` is just a folder name. static function ( $block_name ) use ( $path ) { return "{$path}/{$block_name}/block.json"; }, array_keys( $collection['metadata'] ) ); } /** * Finds the collection path for a given file or folder. * * @since 6.7.0 * * @param string $file_or_folder The normalized path to the file or folder. * @return string|null The normalized collection path if found, or null if not found. */ private static function find_collection_path( $file_or_folder ) { if ( empty( $file_or_folder ) ) { return null; } // Check the last matched collection first, since block registration usually happens in batches per plugin or theme. $path = rtrim( $file_or_folder, '/' ); if ( self::$last_matched_collection && str_starts_with( $path, self::$last_matched_collection ) ) { return self::$last_matched_collection; } $collection_paths = array_keys( self::$collections ); foreach ( $collection_paths as $collection_path ) { if ( str_starts_with( $path, $collection_path ) ) { self::$last_matched_collection = $collection_path; return $collection_path; } } return null; } /** * Checks if metadata exists for a given block name in a specific collection. * * @since 6.7.0 * * @param string $file_or_folder The path to the file or folder containing the block metadata. * @return bool True if metadata exists for the block, false otherwise. */ public static function has_metadata( $file_or_folder ) { return null !== self::get_metadata( $file_or_folder ); } /** * Default identifier function to determine the block identifier from a given path. * * This function extracts the block identifier from the path: * - For 'block.json' files, it uses the parent directory name. * - For directories, it uses the directory name itself. * - For empty paths, it returns an empty string. * * For example: * - Path: '/wp-content/plugins/my-plugin/blocks/example/block.json' * Identifier: 'example' * - Path: '/wp-content/plugins/my-plugin/blocks/another-block' * Identifier: 'another-block' * * This default behavior matches the standard WordPress block structure. * * @since 6.7.0 * * @param string $path The normalized file or folder path to determine the block identifier from. * @return string The block identifier, or an empty string if the path is empty. */ private static function default_identifier_callback( $path ) { // Ensure $path is not empty to prevent unexpected behavior. if ( empty( $path ) ) { return ''; } if ( str_ends_with( $path, 'block.json' ) ) { // Return the parent directory name if it's a block.json file. return basename( dirname( $path ) ); } // Otherwise, assume it's a directory and return its name. return basename( $path ); } /** * Checks whether the given block metadata collection path is valid against the list of collection roots. * * @since 6.7.2 * * @param string $path Normalized block metadata collection path, without trailing slash. * @param string[] $collection_roots List of normalized collection root paths, without trailing slashes. * @return bool True if the path is allowed, false otherwise. */ private static function is_valid_collection_path( $path, $collection_roots ) { foreach ( $collection_roots as $allowed_root ) { // If the path matches any root exactly, it is invalid. if ( $allowed_root === $path ) { return false; } // If the path is a parent path of any of the roots, it is invalid. if ( str_starts_with( $allowed_root, $path ) ) { return false; } } return true; } /** * Gets the default collection root directory paths. * * @since 6.7.2 * * @return string[] List of directory paths within which metadata collections are allowed. */ private static function get_default_collection_roots() { if ( isset( self::$default_collection_roots ) ) { return self::$default_collection_roots; } $collection_roots = array( wp_normalize_path( ABSPATH . WPINC ), wp_normalize_path( WP_CONTENT_DIR ), wp_normalize_path( WPMU_PLUGIN_DIR ), wp_normalize_path( WP_PLUGIN_DIR ), ); $theme_roots = get_theme_roots(); if ( ! is_array( $theme_roots ) ) { $theme_roots = array( $theme_roots ); } foreach ( $theme_roots as $theme_root ) { $collection_roots[] = trailingslashit( wp_normalize_path( WP_CONTENT_DIR ) ) . ltrim( wp_normalize_path( $theme_root ), '/' ); } self::$default_collection_roots = array_unique( $collection_roots ); return self::$default_collection_roots; } } <?php /** * Blocks API: WP_Block_Type_Registry class * * @package WordPress * @subpackage Blocks * @since 5.0.0 */ /** * Core class used for interacting with block types. * * @since 5.0.0 */ #[AllowDynamicProperties] final class WP_Block_Type_Registry { /** * Registered block types, as `$name => $instance` pairs. * * @since 5.0.0 * @var WP_Block_Type[] */ private $registered_block_types = array(); /** * Container for the main instance of the class. * * @since 5.0.0 * @var WP_Block_Type_Registry|null */ private static $instance = null; /** * Registers a block type. * * @since 5.0.0 * * @see WP_Block_Type::__construct() * * @param string|WP_Block_Type $name Block type name including namespace, or alternatively * a complete WP_Block_Type instance. In case a WP_Block_Type * is provided, the $args parameter will be ignored. * @param array $args Optional. Array of block type arguments. Accepts any public property * of `WP_Block_Type`. See WP_Block_Type::__construct() for information * on accepted arguments. Default empty array. * @return WP_Block_Type|false The registered block type on success, or false on failure. */ public function register( $name, $args = array() ) { $block_type = null; if ( $name instanceof WP_Block_Type ) { $block_type = $name; $name = $block_type->name; } if ( ! is_string( $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must be strings.' ), '5.0.0' ); return false; } if ( preg_match( '/[A-Z]+/', $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must not contain uppercase characters.' ), '5.0.0' ); return false; } $name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/'; if ( ! preg_match( $name_matcher, $name ) ) { _doing_it_wrong( __METHOD__, __( 'Block type names must contain a namespace prefix. Example: my-plugin/my-custom-block-type' ), '5.0.0' ); return false; } if ( $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, /* translators: %s: Block name. */ sprintf( __( 'Block type "%s" is already registered.' ), $name ), '5.0.0' ); return false; } if ( ! $block_type ) { $block_type = new WP_Block_Type( $name, $args ); } $this->registered_block_types[ $name ] = $block_type; return $block_type; } /** * Unregisters a block type. * * @since 5.0.0 * * @param string|WP_Block_Type $name Block type name including namespace, or alternatively * a complete WP_Block_Type instance. * @return WP_Block_Type|false The unregistered block type on success, or false on failure. */ public function unregister( $name ) { if ( $name instanceof WP_Block_Type ) { $name = $name->name; } if ( ! $this->is_registered( $name ) ) { _doing_it_wrong( __METHOD__, /* translators: %s: Block name. */ sprintf( __( 'Block type "%s" is not registered.' ), $name ), '5.0.0' ); return false; } $unregistered_block_type = $this->registered_block_types[ $name ]; unset( $this->registered_block_types[ $name ] ); return $unregistered_block_type; } /** * Retrieves a registered block type. * * @since 5.0.0 * * @param string $name Block type name including namespace. * @return WP_Block_Type|null The registered block type, or null if it is not registered. */ public function get_registered( $name ) { if ( ! $this->is_registered( $name ) ) { return null; } return $this->registered_block_types[ $name ]; } /** * Retrieves all registered block types. * * @since 5.0.0 * * @return WP_Block_Type[] Associative array of `$block_type_name => $block_type` pairs. */ public function get_all_registered() { return $this->registered_block_types; } /** * Checks if a block type is registered. * * @since 5.0.0 * * @param string $name Block type name including namespace. * @return bool True if the block type is registered, false otherwise. */ public function is_registered( $name ) { return isset( $this->registered_block_types[ $name ] ); } public function __wakeup() { if ( ! $this->registered_block_types ) { return; } if ( ! is_array( $this->registered_block_types ) ) { throw new UnexpectedValueException(); } foreach ( $this->registered_block_types as $value ) { if ( ! $value instanceof WP_Block_Type ) { throw new UnexpectedValueException(); } } } /** * Utility method to retrieve the main instance of the class. * * The instance will be created if it does not exist yet. * * @since 5.0.0 * * @return WP_Block_Type_Registry The main instance. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } } wOFF f � FFTM D rL"�GDEF ` 3 OS/2 � @ `�i�cmap � A ��@�gasp �� glyf Y� ���l��head \� . 6��hhea ], $��hmtx ]H �@rloca ^P ���vmaxp `` Y �name `� � V/*v�post b � F��?�webf f ��V� �=�� �� �c-x�c`d``�b `b`d`dd�,` � 9 x�c`f?�8�����U�e�4ʹ���)�Ja���~����_ ��bDR��� 6� �x�ݐ�KA�璨�7�� Ł���$��4�$�"���H�hb!];[��E;��F�j���6�y$`ao�yÃ�` �ɀ;X�q��9e��!�A&�A6 �K#�S@S���L5ڠ�h_Y�V��U^�jV��վ�늩�S3u�0-s`�8�6���(��(��@i&��1}�r��U�N[�Km*���SA�n�t�CS6K]��i��9d�~N���s��(���?���_����o���qK8��8�Ξ�tv�mg]�媬ɪ\��rN��#�ĵ���L�����NV?�TX������6y�t �� xڬ� |U�8\����;[��[��t��,��7�u�=l!� K�/F�MnQAPE7D\F�"�a�F�mD&��C�qduF��s I_����N:�̛���t��[U�n����'r�GN�ݜ�I��K�W����]o�{*����������-d�c���X3������Lh�C�g�<�3G���*���_�z�� �iH(LLf+1[�`HCd�P@L9��%�Y�0 Ca>����x0ְ;g��eM+��ݺ�6�H��i�e�Œ7j�i��?�R�������e��f6���Ow��[ʳ���$-������tK^plf���eK�ʕ���ͺU#�X�!^.*5�j.��^m2�R)!:G�;���i��u���(M�B*�ƚ[��4rzm+�ݺ^[� u|"}}���1��ѐ�O$Э�IM{��6�6,�$;���|[��F�U��,�o`�=zw����TKN�4�7��Wȵ\6���^S��di$A��]�%���MÎ%�H�)(��%����l$abf����7o���eDjiill|�q"}�R�z�Uda�������� �-&�d�OнW)��MM��H�XrWk���[������?����7*����[c߰�Mr;�y3Y�n��y��45r� �G�i���b�#D�w��]vJ�&��:�U�R��/�u, ���:;t�h�+~�z�~�#�uu�©�X���n;z�p����%�<�}��N���.�+�5� ��X|T�wr �#��T^Jd?0'Q�O��:�&��;$����h�. 8��p'�?K�85��g��q!"g�]� =n#�iP����X@�_"�=Y�o��_W��<�����z� �D�s�\.��K���w�7N��n�v�ι��~8��r�K����RL�猜�.�<{,D�Y��Ӭ�M.46`5J��߯�}5����m~��9D��~Ar��xX�^�t��j�n�?/�cW����8�z%�Z0g��~AO��5?� ,����@��+�����K�1��:�#K|8��Ĉ�@8�u�1��G<�$�dC��uŽ��X����f#��@��>O�NU��[�Z�v-�n��n����b�b��Gn'��<Zn���[¥g��;UЕ�2qu����_OzuԄf���?�SA�a�� 1���F�Ǯ?��0�ɇ� �$ep�?Xa�0��R7̷l��]X�� �y�! .H-$C�(tV@߄�Oe�xjЛ�I*m\^��<��t٥��$�?l�����ݑ�\��ƍk��C�L([��l9g��)5[yV�z��5��g���#����*����,�F{��=!�ǡ�C��9 ؍&s�,��>�:�wJY�in��cw�-�=����;���'�(�`��'��g���t ��3�\�ivδ-&�gCI0/^2{!ޅײvE�By*�WΔD�D��Q�vVu0�� 5�<j��v��֗臻iOD�S�z.�+VM��j�\�2����&�\��ͤq��Q����� |)�W���j&�*�\sS�}�f9��NO� �3rh�#CN�Mt�����O��G�_%e����0PJ�9G�6�^ڿ���ֹ��A��$k_og����?�6�p2 �X�ſ\I�Me�T6�'�b�m�&