Plugin Directory

Changeset 3366846


Ignore:
Timestamp:
09/24/2025 03:10:59 AM (6 months ago)
Author:
linguise
Message:

Updating to version 2.1.72

Location:
linguise
Files:
4 added
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • linguise/tags/2.1.72/linguise.php

    r3362901 r3366846  
    55 * Plugin URI: https://www.linguise.com/
    66 * Description: Linguise translation plugin
    7  * Version:2.1.71
     7 * Version:2.1.72
    88 * Text Domain: linguise
    99 * Domain Path: /languages
     
    387387// Load all the super-important stuff first
    388388require_once ABSPATH . 'wp-admin/includes/plugin.php';
     389
     390include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'HTMLHelper.php'); // Main HTML Helper, required by fragment handler
     391include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'FragmentBase.php'); // Base class for fragment handlers
    389392include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'FragmentHandler.php');
    390393include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'AttributeHandler.php');
  • linguise/tags/2.1.72/readme.txt

    r3362901 r3366846  
    44Requires at least: 4.0
    55Tested up to: 6.8
    6 Stable tag:2.1.71
     6Stable tag:2.1.72
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    104104
    105105== Changelog ==
     106= 2.1.72 =
     107- Chore: Refactored fragment handler code
     108
    106109= 2.1.71 =
    107110- Fix: Broken hreflang issue on SEMrush plugin
  • linguise/tags/2.1.72/src/AttributeHandler.php

    r3339453 r3366846  
    33namespace Linguise\WordPress;
    44
     5use Linguise\WordPress\FragmentHandler;
     6use Linguise\WordPress\HTMLHelper;
    57use Linguise\Vendor\JsonPath\JsonObject;
    6 use Linguise\WordPress\FragmentHandler;
    78use Linguise\Vendor\Linguise\Script\Core\Debug;
    89
     
    156157    public static function findWPFragments(&$html_data)
    157158    {
    158         $html_dom = self::loadHTML($html_data);
     159        $html_dom = HTMLHelper::loadHTML($html_data);
    159160        if (empty($html_dom)) {
    160161            return [];
     
    179180
    180181                // Unroll the entity
    181                 $key_data = html_entity_decode(self::unprotectEntity($key_data), ENT_QUOTES, 'UTF-8');
     182                $key_data = html_entity_decode(HTMLHelper::unprotectEntity($key_data), ENT_QUOTES, 'UTF-8');
    182183
    183184                // Is the data URL encoded?
     
    236237
    237238        if (!empty($all_fragments)) {
    238             $html_data = self::saveHTML($html_dom);
     239            $html_data = HTMLHelper::saveHTML($html_dom);
    239240        }
    240241
     
    283284        }
    284285
    285         $html_dom = self::loadHTML($html_data);
     286        $html_dom = HTMLHelper::loadHTML($html_data);
    286287        if (empty($html_dom)) {
    287288            return $html_data;
     
    321322
    322323                // Since we have protection enabled around this!
    323                 $match_data = html_entity_decode(self::unprotectEntity($match_data), ENT_QUOTES, 'UTF-8');
     324                $match_data = html_entity_decode(HTMLHelper::unprotectEntity($match_data), ENT_QUOTES, 'UTF-8');
    324325
    325326                $should_encode = isset($matched['encode']) && $matched['encode'];
     
    347348                    }
    348349
    349                     $protected_json = self::protectEntity($replaced_text);
     350                    $protected_json = HTMLHelper::protectEntity($replaced_text);
    350351                } else {
    351352                    // JSON mode, we need to decode the JSON data
     
    357358                    $json_data = new JsonObject($json_decoded);
    358359                    foreach ($fragment_list['fragments'] as $fragment) {
     360                        $dec_key = self::unwrapKey($fragment['key']);
    359361                        try {
    360                             $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     362                            $json_data->set('$.' . $dec_key, $fragment['value']);
    361363                        } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    362                             Debug::log('Failed to set key in attributes: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     364                            Debug::log('Failed to set key in attributes: ' . $dec_key . ' -> ' . $e->getMessage());
    363365                        }
    364366                    }
     
    370372
    371373                    // Protect the entity back
    372                     $protected_json = self::protectEntity(htmlspecialchars($replaced_json, ENT_QUOTES, 'UTF-8', false));
     374                    $protected_json = HTMLHelper::protectEntity(htmlspecialchars($replaced_json, ENT_QUOTES, 'UTF-8', false));
    373375                }
    374376
     
    378380        }
    379381
    380         $html_data = self::saveHTML($html_dom);
     382        $html_data = HTMLHelper::saveHTML($html_dom);
    381383        foreach ($queued_deletions as $deletion) {
    382384            foreach ($deletion as $fragment) {
  • linguise/tags/2.1.72/src/FragmentHandler.php

    r3358294 r3366846  
    33namespace Linguise\WordPress;
    44
     5use Linguise\WordPress\FragmentBase;
     6use Linguise\WordPress\Helper;
     7use Linguise\WordPress\HTMLHelper;
    58use Linguise\Vendor\JsonPath\JsonObject;
    69use Linguise\Vendor\Linguise\Script\Core\Debug;
    710
    811defined('ABSPATH') || die('');
    9 
    10 /**
    11  * Check if the array is an actual object or not.
    12  *
    13  * @param array|object $arr_or_object The array or object to be checked
    14  *
    15  * @return boolean - True if it's an actual object, false if it's an array
    16  */
    17 function is_actual_object($arr_or_object): bool
    18 {
    19     if (is_object($arr_or_object)) {
    20         return true;
    21     }
    22 
    23     if (!is_array($arr_or_object)) {
    24         // preliminary check
    25         return false;
    26     }
    27 
    28     // https://stackoverflow.com/a/72949244 (PHP 7 compatible)
    29     if (function_exists('array_is_list')) {
    30         return array_is_list($arr_or_object) === false; // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound
    31     }
    32 
    33     $keys = array_keys($arr_or_object);
    34     return implode('', $keys) !== implode(range(0, count($keys) - 1));
    35 }
    36 
    37 /**
    38  * Check if the string has space or not.
    39  *
    40  * @param string $str The string to be checked
    41  *
    42  * @return boolean - True if it has space, false if it doesn't
    43  */
    44 function has_space($str)
    45 {
    46     return preg_match('/\s/', $str) > 0;
    47 }
    4812
    4913/**
    5014 * Class FragmentHandler
    5115 */
    52 class FragmentHandler
     16class FragmentHandler extends FragmentBase
    5317{
    5418    /**
     
    6630     */
    6731    protected static $frag_html_match_self_close = '/<(img) class="linguise-fragment" data-fragment-name="([^"]*)" data-fragment-param="([^"]*)" data-fragment-key="([^"]*)" data-fragment-format="(link|html|html-main|text|media-img|media-imgset)" data-fragment-mode="(auto|override|attribute)"(?: data-fragment-extra-id="([^"]*)")?(?: (?:href|src|srcset)="([^"]*)")?\s*\/?>/si';
    68 
    69     /**
    70      * Marker used to protect the HTML entities
    71      *
    72      * @var array
    73      */
    74     protected static $marker_entity = [
    75         'common' => 'linguise-internal-entity',
    76         'named' => 'linguise-internal-entity1',
    77         'numeric' => 'linguise-internal-entity2',
    78     ];
    79 
    80     /**
    81      * Default filters for the fragments
    82      *
    83      * @var array
    84      */
    85     protected static $default_filters = [
    86         [
    87             'key' => 'nonce',
    88             'mode' => 'wildcard',
    89             'kind' => 'deny',
    90         ],
    91         [
    92             'key' => 'i18n_.+',
    93             'mode' => 'regex',
    94             'kind' => 'allow',
    95             'cast' => 'html-main',
    96         ],
    97         [
    98             'key' => 'currency\..*',
    99             'mode' => 'regex_full',
    100             'kind' => 'deny',
    101         ],
    102         [
    103             'key' => 'wc.*?_currency',
    104             'mode' => 'regex',
    105             'kind' => 'deny',
    106         ],
    107         [
    108             'key' => 'dateFormat',
    109             'mode' => 'exact',
    110             'kind' => 'deny',
    111         ],
    112         [
    113             'key' => 'baseLocation.country',
    114             'mode' => 'path',
    115             'kind' => 'deny',
    116         ],
    117         [
    118             'key' => 'baseLocation.state',
    119             'mode' => 'path',
    120             'kind' => 'deny',
    121         ],
    122         [
    123             'key' => 'admin.wccomHelper.storeCountry',
    124             'mode' => 'path',
    125             'kind' => 'deny',
    126         ],
    127         [
    128             'key' => '.*-version',
    129             'mode' => 'regex',
    130             'kind' => 'deny',
    131         ],
    132         [
    133             'key' => 'orderStatuses\..*',
    134             'mode' => 'regex_full',
    135             'kind' => 'allow',
    136         ],
    137         [
    138             'key' => 'wc.*Url',
    139             'mode' => 'regex_full',
    140             'kind' => 'deny',
    141         ],
    142         [
    143             'key' => '^defaultFields\..*\.(autocapitalize|autocomplete)',
    144             'mode' => 'regex_full',
    145             'kind' => 'deny',
    146         ],
    147         [
    148             'key' => 'defaultAddressFormat',
    149             'mode' => 'exact',
    150             'kind' => 'deny',
    151         ],
    152         [
    153             'key' => 'dateFormat',
    154             'mode' => 'exact',
    155             'kind' => 'deny',
    156         ],
    157         [
    158             'key' => '^checkoutData\..*',
    159             'mode' => 'regex_full',
    160             'kind' => 'deny',
    161         ],
    162         [
    163             'key' => 'api_key',
    164             'mode' => 'exact',
    165             'kind' => 'deny',
    166         ],
    167         [
    168             'key' => '^countryData\..*\.format',
    169             'mode' => 'regex_full',
    170             'kind' => 'deny',
    171         ],
    172         [
    173             'key' => '.*?(hash_key|fragment_name|storage_key)',
    174             'mode' => 'regex',
    175             'kind' => 'deny',
    176         ],
    177         [
    178             'key' => 'wc_ajax_url',
    179             'mode' => 'exact',
    180             'kind' => 'deny',
    181         ],
    182         /**
    183          * Plugin : woocommerce-gateway-stripe
    184          */
    185         [
    186             'key' => 'paymentMethodsConfig.*?(card|us_bank_account|alipay|klarna|afterpay_clearpay|link|wechat_pay|cashapp)\.countries',
    187             'mode' => 'regex_full',
    188             'kind' => 'deny',
    189         ],
    190         [
    191             'key' => 'accountCountry',
    192             'mode' => 'exact',
    193             'kind' => 'deny',
    194         ],
    195         [
    196             'key' => 'appearance\..*',
    197             'mode' => 'regex_full',
    198             'kind' => 'deny',
    199         ],
    200         [
    201             'key' => 'blocksAppearance\..*',
    202             'mode' => 'regex_full',
    203             'kind' => 'deny',
    204         ],
    205         [
    206             'key' => 'paymentMethodData.*?stripe\.plugin_url',
    207             'mode' => 'regex_full',
    208             'kind' => 'deny',
    209         ],
    210         [
    211             'key' => 'currency',
    212             'mode' => 'exact',
    213             'kind' => 'deny',
    214         ],
    215     ];
    216 
    217     /**
    218      * Check with the Configuration for the allow list and deny list.
    219      *
    220      * @param string $key      The key to be checked
    221      * @param string $full_key The full JSON path key to be checked
    222      *
    223      * @return boolean|null - True if it's allowed, false if it's not
    224      */
    225     public static function isKeyAllowed($key, $full_key)
    226     {
    227         // the allow/deny list are formatted array like:
    228         // [
    229         //    [
    230         //        'key' => 'woocommerce',
    231         //        'mode' => 'regex' | 'exact | 'path' | 'wildcard',
    232         //        'kind' => 'allow' | 'deny',
    233         //    ]
    234         // ]
    235 
    236         $merged_defaults = self::$default_filters;
    237         if (self::isCurrentTheme('Woodmart')) {
    238             $regex_key_disallowed = [
    239                 'add_to_cart_action.*',
    240                 'age_verify.*',
    241                 'ajax_(?!url)(\w+)',
    242                 'carousel_breakpoints\..*',
    243                 'comment_images_upload_mimes\..*',
    244                 'tooltip_\w+_selector',
    245             ];
    246 
    247             foreach ($regex_key_disallowed as $regex_key) {
    248                 $merged_defaults[] = [
    249                     'key' => $regex_key,
    250                     'mode' => 'regex_full',
    251                     'kind' => 'deny',
    252                 ];
    253             }
    254 
    255             $exact_key_disallowed = [
    256                 'added_popup',
    257                 'base_hover_mobile_click',
    258                 'cart_redirect_after_add',
    259                 'categories_toggle',
    260                 'collapse_footer_widgets',
    261                 'compare_by_category',
    262                 'compare_save_button_state',
    263                 'countdown_timezone',
    264                 'whb_header_clone',
    265                 'vimeo_library_url',
    266                 'theme_dir',
    267                 'wishlist_page_nonce',
    268                 'photoswipe_template',
    269             ];
    270 
    271             foreach ($exact_key_disallowed as $exact_key) {
    272                 $merged_defaults[] = [
    273                     'key' => $exact_key,
    274                     'mode' => 'path',
    275                     'kind' => 'deny',
    276                 ];
    277             }
    278         }
    279 
    280         // Run through filters, provide our current default filters
    281         // User can change it by adding a filter and modify the array.
    282         if (function_exists('apply_filters')) {
    283             $wp_frag_list = apply_filters('linguise_fragment_filters', $merged_defaults);
    284         } else {
    285             $wp_frag_list = $merged_defaults;
    286         }
    287 
    288         foreach ($wp_frag_list as $frag_item) {
    289             $allow = $frag_item['kind'] === 'allow';
    290             $cast_data = isset($frag_item['cast']) ? $frag_item['cast'] : null;
    291             if ($frag_item['mode'] === 'path') {
    292                 // check if full key is the same
    293                 if ($frag_item['key'] === $full_key) {
    294                     // Return cast or bool
    295                     return $cast_data ? $cast_data : $allow;
    296                 }
    297             } elseif ($frag_item['mode'] === 'exact') {
    298                 // check if key is the same
    299                 if ($frag_item['key'] === $key) {
    300                     return $cast_data ? $cast_data : $allow;
    301                 }
    302             } elseif ($frag_item['mode'] === 'regex' || $frag_item['mode'] === 'regex_full') {
    303                 // check if regex matches
    304                 $key_match = $frag_item['mode'] === 'regex_full' ? $full_key : $key;
    305                 $match_re = '/' . $frag_item['key'] . '/';
    306                 if (preg_match($match_re, $key_match)) {
    307                     return $cast_data ? $cast_data : $allow;
    308                 }
    309             } elseif ($frag_item['mode'] === 'wildcard') {
    310                 // check if wildcard matches
    311                 $match_re = '/^.*?' . $frag_item['key'] . '.*?$/';
    312                 if (preg_match($match_re, $key)) {
    313                     return $cast_data ? $cast_data : $allow;
    314                 }
    315             }
    316         }
    317 
    318         return null;
    319     }
    320 
    321     /**
    322      * Check if the string is a translatable string or not.
    323      *
    324      * @param string $value The string to be checked
    325      *
    326      * @return boolean - True if it's a translatable string, false if it's not
    327      */
    328     private static function isTranslatableString($value)
    329     {
    330         $value = trim($value);
    331 
    332         if (empty($value) || !is_string($value)) {
    333             return false;
    334         }
    335 
    336         // Check if it's a JSON, if yes, do not translate
    337         $json_parse = json_decode($value);
    338         if (!is_null($json_parse)) {
    339             return false;
    340         }
    341 
    342         // Has space? Most likely a translateable string
    343         if (has_space($value)) {
    344             return true;
    345         }
    346 
    347         // Check if email
    348         if (!empty(filter_var($value, FILTER_VALIDATE_EMAIL))) {
    349             return false;
    350         }
    351 
    352         // Check if string is UUID
    353         if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/', $value)) {
    354             return false;
    355         }
    356 
    357         // Check if first word is lowercase (bad idea?)
    358         // Or, check if has a number/symbols
    359         if (ctype_lower($value[0]) || preg_match('/[0-9\W]/', $value)) {
    360             return false;
    361         }
    362 
    363         return true;
    364     }
    365 
    366     /**
    367      * Check if the string is a link or not.
    368      *
    369      * @param string $value The string to be checked
    370      *
    371      * @return boolean - True if it's a link, false if it's not
    372      */
    373     private static function isStringLink($value)
    374     {
    375         // Has http:// or https://
    376         // Has %%endpoint%%
    377         // Starts with / and has no space
    378         if (preg_match('/https?:\/\//', $value)) {
    379             // Validate the link
    380             if (filter_var($value, FILTER_VALIDATE_URL)) {
    381                 return true;
    382             }
    383 
    384             return false;
    385         }
    386 
    387         if (substr($value, 0, 1) === '/' && !has_space($value)) {
    388             $as_url = parse_url($value);
    389             if (empty($as_url)) {
    390                 return false;
    391             }
    392 
    393             // Check if it only have "path" and not other keys
    394             $array_keys = array_keys($as_url);
    395             if (count($array_keys) === 1 && $array_keys[0] === 'path') {
    396                 return true;
    397             }
    398 
    399             if (preg_match('/%%.*%%/', $value)) {
    400                 // Assume WC-AJAX
    401                 return true;
    402             }
    403         }
    404 
    405         return false;
    406     }
    407 
    408     /**
    409      * Check if the string is a image link or not.
    410      *
    411      * @param string $value The string to be checked
    412      *
    413      * @return boolean - True if it's a image link, false if it's not
    414      */
    415     private static function isImageLink($value)
    416     {
    417         // There is so much more image extension
    418         $extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'tiff', 'tif', 'ico', 'avif', 'heic', 'heif'];
    419         $regex_matcher = '/\.(?:' . implode('|', $extensions) . ')$/i';
    420         if (preg_match($regex_matcher, $value)) {
    421             // We don't need to validate the link since this is called inside isStringLink
    422             return true;
    423         }
    424         return false;
    425     }
    426 
    427     /**
    428      * Check if the string is a HTML element or not.
    429      *
    430      * @param string $value The string to be checked
    431      *
    432      * @return string|false - True if it's a HTML element, false if it's not
    433      */
    434     private static function isHTMLElement($value)
    435     {
    436         if (empty($value)) {
    437             return false;
    438         }
    439 
    440         // use simplexml, suppress the warning
    441         if (extension_loaded('xml') && function_exists('simplexml_load_string')) {
    442             $doc = @simplexml_load_string($value); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
    443             if ($doc !== false) {
    444                 return 'html';
    445             }
    446         }
    447 
    448         // Use strip_tags method
    449         if (strip_tags($value) !== $value) {
    450             return 'html-main';
    451         }
    452 
    453         return false;
    454     }
    455 
    456     /**
    457      * Check and wrap key with ["$key"] if it use symbols
    458      *
    459      * @param string $key The key to be checked
    460      *
    461      * @return string
    462      */
    463     private static function wrapKey($key)
    464     {
    465         // only include symbols
    466         // alphanumeric is not included
    467         if (preg_match('/[^\w]/', $key)) {
    468             return "['" . $key . "']";
    469         }
    470 
    471         return $key;
    472     }
    47332
    47433    /**
     
    49857        }
    49958
    500         if (is_actual_object($value)) {
     59        if (Helper::isActualObject($value)) {
    50160            $collected_fragments = self::collectFragmentFromJson($value, $strict, $collected_fragments, $use_key);
    50261        } elseif (is_array($value)) {
     
    566125        }
    567126        return $collected_fragments;
    568     }
    569 
    570     /**
    571      * Checks if the given theme name is the current theme or the parent of the current theme.
    572      *
    573      * @param string         $theme_name   The name of the theme to check.
    574      * @param \WP_Theme|null $parent_theme Optional. The parent theme to check. Default is null.
    575      *
    576      * @return boolean True if the given theme name is the current theme or its parent, false otherwise.
    577      */
    578     private static function isCurrentTheme($theme_name, $parent_theme = \null)
    579     {
    580         if (!function_exists('wp_get_theme')) {
    581             return false;
    582         }
    583 
    584         $theme = $parent_theme ?: wp_get_theme();
    585         if (empty($theme)) {
    586             return false;
    587         }
    588 
    589         $is_theme = $theme->name === $theme_name;
    590         if ($is_theme) {
    591             return true;
    592         }
    593 
    594         $parent = $theme->parent();
    595         if ($parent !== false) {
    596             return self::isCurrentTheme($theme_name, $parent);
    597         }
    598         return false;
    599     }
    600 
    601     /**
    602      * Protect the HTML entities in the source code.
    603      *
    604      * Adapted from: https://github.com/ivopetkov/html5-dom-document-php/blob/master/src/HTML5DOMDocument.php
    605      *
    606      * @param string $source The source code to be protected
    607      *
    608      * @return string The protected source code
    609      */
    610     protected static function protectEntity($source)
    611     {
    612         // Replace the entity with our own
    613         $source = preg_replace('/&([a-zA-Z]*);/', self::$marker_entity['named'] . '-$1-end', $source);
    614         $source = preg_replace('/&#([0-9]*);/', self::$marker_entity['numeric'] . '-$1-end', $source);
    615 
    616         return $source;
    617     }
    618 
    619     /**
    620      * Unprotect the HTML entities in the source code.
    621      *
    622      * @param string $html The HTML code to be unprotected
    623      *
    624      * @return string The unprotected HTML code
    625      */
    626     protected static function unprotectEntity($html)
    627     {
    628         if (strpos($html, self::$marker_entity['common']) !== false) {
    629             $html = preg_replace('/' . self::$marker_entity['named'] . '-(.*?)-end/', '&$1;', $html);
    630             $html = preg_replace('/' . self::$marker_entity['numeric'] . '-(.*?)-end/', '&#$1;', $html);
    631         }
    632 
    633         return $html;
    634     }
    635 
    636     /**
    637      * Protect the HTML string before processing with DOMDocument.
    638      *
    639      * It does:
    640      * - Add CDATA around script tags content
    641      * - Preserve html entities
    642      *
    643      * Adapted from: https://github.com/ivopetkov/html5-dom-document-php/blob/master/src/HTML5DOMDocument.php
    644      *
    645      * @param string $source The HTML source code to be protected
    646      *
    647      * @return string The protected HTML source code
    648      */
    649     private static function protectHTML($source)
    650     {
    651         // Add CDATA around script tags content
    652         $matches = null;
    653         preg_match_all('/<script(.*?)>/', $source, $matches);
    654         if (isset($matches[0])) {
    655             $matches[0] = array_unique($matches[0]);
    656             foreach ($matches[0] as $match) {
    657                 if (substr($match, -2, 1) !== '/') { // check if ends with />
    658                     $source = str_replace($match, $match . '<![CDATA[-linguise-dom-internal-cdata', $source); // Add CDATA after the open tag
    659                 }
    660             }
    661         }
    662 
    663         $source = str_replace('</script>', '-linguise-dom-internal-cdata]]></script>', $source); // Add CDATA before the end tag
    664         $source = str_replace('<![CDATA[-linguise-dom-internal-cdata-linguise-dom-internal-cdata]]>', '', $source); // Clean empty script tags
    665         $matches = null;
    666         preg_match_all('/\<!\[CDATA\[-linguise-dom-internal-cdata.*?-linguise-dom-internal-cdata\]\]>/s', $source, $matches);
    667         if (isset($matches[0])) {
    668             $matches[0] = array_unique($matches[0]);
    669             foreach ($matches[0] as $match) {
    670                 if (strpos($match, '</') !== false) { // check if contains </
    671                     $source = str_replace($match, str_replace('</', '<-linguise-dom-internal-cdata-endtagfix/', $match), $source);
    672                 }
    673             }
    674         }
    675 
    676         // Preserve html entities
    677         $source = self::protectEntity($source);
    678 
    679         return $source;
    680     }
    681 
    682     /**
    683      * Load the HTML data into a DOMDocument object.
    684      *
    685      * @param string $html_data The HTML data to be loaded
    686      *
    687      * @return \DOMDocument|null The loaded HTML DOM object
    688      */
    689     protected static function loadHTML($html_data)
    690     {
    691         // Check if DOMDocument is available or xml extension is loaded
    692         if (!class_exists('DOMDocument') && !extension_loaded('xml')) {
    693             return null;
    694         }
    695 
    696         // Load HTML
    697         $html_dom = new \DOMDocument();
    698         @$html_dom->loadHTML(self::protectHTML($html_data), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
    699 
    700         /**
    701         * Avoid mangling the CSS and JS code with encoded HTML entities
    702         *
    703         * See: https://www.php.net/manual/en/domdocument.savehtml.php#119813
    704         *
    705         * While testing, we found this issue with css inner text got weirdly mangled
    706         * following the issue above, I manage to correct this by adding proper content-type equiv
    707         * which is really weird honestly but it manages to fix the issue.
    708         */
    709         $has_utf8 = false;
    710         $meta_attrs = $html_dom->getElementsByTagName('meta');
    711         foreach ($meta_attrs as $meta) {
    712             if ($meta->hasAttribute('http-equiv') && strtolower($meta->getAttribute('http-equiv')) === 'content-type') {
    713                 // force UTF-8s
    714                 $meta->setAttribute('content', 'text/html; charset=UTF-8');
    715                 $has_utf8 = true;
    716                 break;
    717             }
    718         }
    719 
    720         if (!$has_utf8) {
    721             // We didn't found any meta tag with content-type equiv, add our own
    722             $meta = $html_dom->createElement('meta');
    723             $meta->setAttribute('http-equiv', 'Content-Type');
    724             $meta->setAttribute('content', 'text/html; charset=UTF-8');
    725             $head_doc = $html_dom->getElementsByTagName('head');
    726             if ($head_doc->length > 0) {
    727                 // Add to head tag on the child as the first node
    728                 $head = $head_doc->item(0);
    729                 @$head->insertBefore($meta, $head->firstChild); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore any errors for now
    730             }
    731         }
    732 
    733         return $html_dom;
    734     }
    735 
    736     /**
    737      * Save the HTML data into a string.
    738      *
    739      * @param \DOMDocument $dom The DOMDocument object to be saved
    740      *
    741      * @return string The saved HTML data
    742      */
    743     protected static function saveHTML($dom)
    744     {
    745         // Save HTML
    746         $html_data = $dom->saveHTML();
    747         if ($html_data === false) {
    748             return '';
    749         }
    750 
    751         // Unprotect HTML entities
    752         $html_data = self::unprotectEntity($html_data);
    753 
    754         // Unprotect HTML
    755         $code_to_be_removed = [
    756             'linguise-dom-internal-content',
    757             '<![CDATA[-linguise-dom-internal-cdata',
    758             '-linguise-dom-internal-cdata]]>',
    759             '-linguise-dom-internal-cdata-endtagfix'
    760         ];
    761         foreach ($code_to_be_removed as $code) {
    762             $html_data = str_replace($code, '', $html_data);
    763         }
    764 
    765         // Unmangle stuff like &amp;#xE5;
    766         $html_data = preg_replace('/&amp;#x([0-9A-Fa-f]+);/', '&#x$1;', $html_data);
    767 
    768         return $html_data;
    769     }
    770 
    771     /**
    772      * Unclobber the CDATA internal
    773      *
    774      * NOTE: Only use this when processing a script content internal data not the whole HTML data.
    775      *
    776      * This is used to protect the CDATA internal data from being mangled by the DOMDocument.
    777      *
    778      * @param string $html_data The HTML data to be unclobbered
    779      *
    780      * @return string The unclobbered HTML data
    781      */
    782     protected static function unclobberCdataInternal($html_data)
    783     {
    784         // Unclobber the CDATA internal
    785         $html_data = str_replace('<![CDATA[-linguise-dom-internal-cdata', '', $html_data);
    786         $html_data = str_replace('-linguise-dom-internal-cdata]]>', '', $html_data);
    787         $html_data = str_replace('<-linguise-dom-internal-cdata-endtagfix/', '</', $html_data);
    788 
    789         return $html_data;
    790     }
    791 
    792     /**
    793      * Clobber back the CDATA internal
    794      *
    795      * NOTE: Only use this when processing a script content internal data not the whole HTML data.
    796      *
    797      * This is used to protect the CDATA internal data from being mangled by the DOMDocument.
    798      *
    799      * @param string $html_data The HTML data to be clobbered
    800      *
    801      * @return string The clobbered HTML data
    802      */
    803     protected static function clobberCdataInternal($html_data)
    804     {
    805         // Append prefix and suffix
    806         return '<![CDATA[-linguise-dom-internal-cdata' . $html_data . '-linguise-dom-internal-cdata]]>';
    807     }
    808 
    809     /**
    810      * Get override JSON fragment matching
    811      *
    812      * The way the override works is by matching the script content with the regex, the schema of each item is:
    813      * - name: The name of the plugin, e.g. 'mailoptin', must be unique
    814      * - match: The regex to match the script content
    815      * - replacement: The replacement string, use $$JSON_DATA$$ as the placeholder for the JSON data
    816      * - position: The position of the JSON data, default to 1 (optional)
    817      * - encode: If the JSON data is URL encoded or not, default to false (optional)
    818      * - id: The id of the script, if it's not the same, then it will be skipped (optional)
    819      * - mode: The mode of the script, default to 'script' (available are: `script` and `app_json`)
    820      *
    821      * @param string $html_data The HTML data input
    822      *
    823      * @return array The array of JSON to match with fragment
    824      */
    825     private static function getJSONOverrideMatcher($html_data)
    826     {
    827         $current_list = [];
    828 
    829         if (is_plugin_active('mailoptin/mailoptin.php')) {
    830             $current_list[] = [
    831                 'name' => 'mailoptin',
    832                 'match' => '<script type="text\/javascript">var (.*)_lightbox = (.*);<\/script>',
    833                 'replacement' => '<script text="text/javascript">var $1_lightbox = $$JSON_DATA$$;</script>',
    834                 'position' => 2,
    835             ];
    836         }
    837 
    838         if (is_plugin_active('ninja-forms/ninja-forms.php')) {
    839             $current_list[] = [
    840                 'name' => 'ninjaforms_fields',
    841                 'match' => 'form.fields=(.*?);nfForms',
    842                 'replacement' => 'form.fields=$1;nfForms',
    843             ];
    844             $current_list[] = [
    845                 'name' => 'ninjaforms_i18n',
    846                 'match' => 'nfi18n = (.*?);',
    847                 'replacement' => 'nfi18n = $$JSON_DATA$$;',
    848             ];
    849             $current_list[] = [
    850                 'name' => 'ninjaforms_settings',
    851                 'match' => 'form.settings=(.*?);form',
    852                 'replacement' => 'form.settings=$$JSON_DATA$$;form',
    853             ];
    854         }
    855 
    856         if (is_plugin_active('wpforms-lite/wpforms.php')) {
    857             $current_list[] = [
    858                 'name' => 'wpforms-lite',
    859                 'match' => 'wpforms_settings = (.*?)(\n)(\/\* ]]> \*\/)',
    860                 'replacement' => 'wpforms_settings = $$JSON_DATA$$$2$3',
    861             ];
    862         }
    863 
    864         if (is_plugin_active('popup-maker/popup-maker.php')) {
    865             $current_list[] = [
    866                 'name' => 'popup-maker',
    867                 'match' => 'var pumAdminBarText = (.*?);',
    868                 'replacement' => 'var pumAdminBarText = $$JSON_DATA$$;',
    869             ];
    870         }
    871 
    872         if (is_plugin_active('mailpoet/mailpoet.php')) {
    873             $current_list[] = [
    874                 'name' => 'mailpoet',
    875                 'match' => 'var MailPoetForm = (.*?);',
    876                 'replacement' => 'var MailPoetForm = $$JSON_DATA$$;',
    877             ];
    878         }
    879 
    880         if (self::isCurrentTheme('Woodmart')) {
    881             $current_list[] = [
    882                 'name' => 'woodmart-theme',
    883                 'match' => 'var woodmart_settings = (.*?);',
    884                 'replacement' => 'var woodmart_settings = $$JSON_DATA$$;',
    885             ];
    886         }
    887 
    888         $current_list[] = [
    889             'name' => 'wc-settings-encoded',
    890             'match' => 'var wcSettings = wcSettings \|\| JSON\.parse\( decodeURIComponent\( \'(.*?)\' \) \);',
    891             'replacement' => 'var wcSettings = wcSettings || JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) );',
    892             'encode' => true,
    893         ];
    894 
    895         if (defined('CFCORE_VER')) {
    896             $current_list[] = [
    897                 'name' => 'calderaforms',
    898                 'match' => 'CF_VALIDATOR_STRINGS = (.*?);',
    899                 'replacement' => 'CF_VALIDATOR_STRINGS = $$JSON_DATA$$;',
    900             ];
    901         }
    902 
    903         $current_list[] = [
    904             'name' => 'surecart-store-data',
    905             'key' => 'sc-store-data',
    906             'mode' => 'app_json',
    907         ];
    908 
    909         // Merge with apply_filters
    910         if (function_exists('apply_filters')) {
    911             $current_list = apply_filters('linguise_fragment_override', $current_list, $html_data);
    912         }
    913 
    914         return $current_list;
    915127    }
    916128
     
    1061273
    1062274        foreach ($override_list as $override_item) {
    1063             $script_content = self::unclobberCdataInternal($script_content);
     275            $script_content = HTMLHelper::unclobberCdataInternal($script_content);
    1064276            if (isset($override_item['mode']) && $override_item['mode'] === 'app_json') {
    1065277                // If mode is app_json and key is the same
     
    1130342    public static function findWPFragments(&$html_data)
    1131343    {
    1132         $html_dom = self::loadHTML($html_data);
     344        $html_dom = HTMLHelper::loadHTML($html_data);
    1133345        if (empty($html_dom)) {
    1134346            return [];
     
    1154366            $frag_id = $attr_match[1];
    1155367
    1156             $script_content = self::unclobberCdataInternal($script->textContent);
     368            $script_content = HTMLHelper::unclobberCdataInternal($script->textContent);
    1157369
    1158370            $match_res = preg_match('/var ' . str_replace('-', '_', $frag_id) . '_params = (.*);/', $script_content, $json_matches);
     
    1202414
    1203415    /**
    1204      * Unpack/decode the key name from the JSON data.
    1205      *
    1206      * This is needed because the key name would be encoded sometimes.
    1207      *
    1208      * @param string $key The key to be decoded
    1209      *
    1210      * @return string
    1211      */
    1212     protected static function decodeKeyName($key)
    1213     {
    1214         $key = html_entity_decode($key, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    1215         // Would sometimes fails??
    1216         $key = str_replace('&apos;', "'", $key);
    1217         $key = str_replace('&quot;', '"', $key);
    1218         return $key;
    1219     }
    1220 
    1221     /**
    1222416     * Apply the translated fragments for the override.
    1223417     *
     
    1260454            $json_data = new JsonObject(json_decode('{' . $match_data . '}', true));
    1261455            foreach ($fragment_info['fragments'] as $fragment) {
     456                $decoded_key = self::unwrapKey($fragment['key']);
    1262457                try {
    1263                     $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     458                    $json_data->set('$.' . $decoded_key, $fragment['value']);
    1264459                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1265                     Debug::log('Failed to set key in override: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     460                    Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
    1266461                }
    1267462            }
     
    1289484            $json_data = new JsonObject(json_decode($before_match, true));
    1290485            foreach ($fragment_info['fragments'] as $fragment) {
     486                $decoded_key = self::unwrapKey($fragment['key']);
    1291487                try {
    1292                     $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     488                    $json_data->set('$.' . $decoded_key, $fragment['value']);
    1293489                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1294                     Debug::log('Failed to set key in override: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     490                    Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
    1295491                }
    1296492            }
     
    1335531        foreach ($fragments as $fragment) {
    1336532            // remove the html fragment from the translated page
     533            $decoded_key = self::unwrapKey($fragment['key']);
    1337534            try {
    1338                 $json_path->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     535                $json_path->set('$.' . $decoded_key, $fragment['value']);
    1339536            } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1340                 Debug::log('Failed to set key in auto: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     537                Debug::log('Failed to set key in auto: ' . $decoded_key . ' -> ' . $e->getMessage());
    1341538            }
    1342539        }
  • linguise/tags/2.1.72/src/Helper.php

    r3344947 r3366846  
    44
    55defined('ABSPATH') || die('');
    6 
    76
    87/**
     
    342341        return 'rgba(' . $color_p['r'] . ', ' . $color_p['g'] . ', ' . $color_p['b'] . ', ' . $alpha . ')';
    343342    }
     343
     344    /**
     345     * Check if the array is an actual object or not.
     346     *
     347     * @param array|object $arrOrObject The array or object to be checked
     348     *
     349     * @return boolean - True if it's an actual object, false if it's an array
     350     */
     351    public static function isActualObject($arrOrObject)
     352    {
     353        if (is_object($arrOrObject)) {
     354            return true;
     355        }
     356
     357        if (!is_array($arrOrObject)) {
     358            // preliminary check
     359            return false;
     360        }
     361
     362        // https://stackoverflow.com/a/72949244 (PHP 7 compatible)
     363        if (function_exists('array_is_list')) {
     364            return array_is_list($arrOrObject) === false; // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound
     365        }
     366
     367        $keys = array_keys($arrOrObject);
     368        return implode('', $keys) !== implode(range(0, count($keys) - 1));
     369    }
     370
     371    /**
     372     * Check if the string has space or not.
     373     *
     374     * @param string $str The string to be checked
     375     *
     376     * @return boolean - True if it has space, false if it doesn't
     377     */
     378    public static function hasSpace($str)
     379    {
     380        return preg_match('/\s/', $str) > 0;
     381    }
    344382}
  • linguise/tags/2.1.72/src/constants.php

    r3362901 r3366846  
    11<?php
    22if (!defined('LINGUISE_SCRIPT_TRANSLATION_VERSION')) {
    3     define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.1.71');
     3    define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.1.72');
    44}
    55
    66if (!defined('LINGUISE_VERSION')) {
    7     define('LINGUISE_VERSION', '2.1.71');
     7    define('LINGUISE_VERSION', '2.1.72');
    88}
  • linguise/tags/2.1.72/vendor/composer/installed.json

    r3357604 r3366846  
    5757        {
    5858            "name": "linguise/script-php",
    59             "version": "v1.3.34",
    60             "version_normalized": "1.3.34.0",
     59            "version": "v1.3.35",
     60            "version_normalized": "1.3.35.0",
    6161            "source": {
    6262                "type": "git",
    6363                "url": "git@bitbucket.org:linguise/script-php.git",
    64                 "reference": "6b3fc442043092f8b4ab344cb4013972d515f2e8"
     64                "reference": "c3ec7ac41f08b8678c985e5ff2e8a2658ac4594d"
    6565            },
    6666            "require": {
     
    7171            },
    7272            "require-dev": {
    73                 "phpunit/phpunit": "^9"
    74             },
    75             "time": "2025-09-08T05:45:17+00:00",
     73                "phpunit/php-code-coverage": "9.2.32",
     74                "phpunit/phpunit": "^9",
     75                "vlucas/phpdotenv": "^5.6"
     76            },
     77            "time": "2025-09-18T08:53:06+00:00",
    7678            "type": "library",
    7779            "installation-source": "source",
  • linguise/tags/2.1.72/vendor/composer/installed.php

    r3362901 r3366846  
    44        'pretty_version' => 'dev-master',
    55        'version' => 'dev-master',
    6         'reference' => 'c501b5b2201bfed3d5375935d80af464ce9ed5cc',
     6        'reference' => '3d43db286724933049dae05905587dd8108a9002',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    2121        ),
    2222        'linguise/script-php' => array(
    23             'pretty_version' => 'v1.3.34',
    24             'version' => '1.3.34.0',
    25             'reference' => '6b3fc442043092f8b4ab344cb4013972d515f2e8',
     23            'pretty_version' => 'v1.3.35',
     24            'version' => '1.3.35.0',
     25            'reference' => 'c3ec7ac41f08b8678c985e5ff2e8a2658ac4594d',
    2626            'type' => 'library',
    2727            'install_path' => __DIR__ . '/../linguise/script-php',
     
    3232            'pretty_version' => 'dev-master',
    3333            'version' => 'dev-master',
    34             'reference' => 'c501b5b2201bfed3d5375935d80af464ce9ed5cc',
     34            'reference' => '3d43db286724933049dae05905587dd8108a9002',
    3535            'type' => 'library',
    3636            'install_path' => __DIR__ . '/../../',
  • linguise/tags/2.1.72/vendor/linguise/script-php/.version

    r3357604 r3366846  
    1 1.3.34
     11.3.35
  • linguise/tags/2.1.72/vendor/linguise/script-php/composer.json

    r2718675 r3366846  
    2828  },
    2929  "require-dev": {
    30     "phpunit/phpunit": "^9"
     30    "phpunit/php-code-coverage": "9.2.32",
     31    "phpunit/phpunit": "^9",
     32    "vlucas/phpdotenv": "^5.6"
    3133  }
    3234}
  • linguise/tags/2.1.72/vendor/linguise/script-php/composer.lock

    r2679984 r3366846  
    55        "This file is @generated automatically"
    66    ],
    7     "content-hash": "662cefddda37d75487a93c211e51de4e",
     7    "content-hash": "93d2aed00792824a33c47a2d587cfa8a",
    88    "packages": [],
    99    "packages-dev": [
    1010        {
    1111            "name": "doctrine/instantiator",
    12             "version": "1.4.0",
     12            "version": "1.5.0",
    1313            "source": {
    1414                "type": "git",
    1515                "url": "https://github.com/doctrine/instantiator.git",
    16                 "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
    17             },
    18             "dist": {
    19                 "type": "zip",
    20                 "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
    21                 "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
     16                "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
     17            },
     18            "dist": {
     19                "type": "zip",
     20                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
     21                "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
    2222                "shasum": ""
    2323            },
     
    2626            },
    2727            "require-dev": {
    28                 "doctrine/coding-standard": "^8.0",
     28                "doctrine/coding-standard": "^9 || ^11",
    2929                "ext-pdo": "*",
    3030                "ext-phar": "*",
    31                 "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
    32                 "phpstan/phpstan": "^0.12",
    33                 "phpstan/phpstan-phpunit": "^0.12",
    34                 "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
     31                "phpbench/phpbench": "^0.16 || ^1",
     32                "phpstan/phpstan": "^1.4",
     33                "phpstan/phpstan-phpunit": "^1",
     34                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
     35                "vimeo/psalm": "^4.30 || ^5.4"
    3536            },
    3637            "type": "library",
     
    5960            "support": {
    6061                "issues": "https://github.com/doctrine/instantiator/issues",
    61                 "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
     62                "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
    6263            },
    6364            "funding": [
     
    7576                }
    7677            ],
    77             "time": "2020-11-10T18:47:58+00:00"
     78            "time": "2022-12-30T00:15:36+00:00"
     79        },
     80        {
     81            "name": "graham-campbell/result-type",
     82            "version": "v1.1.3",
     83            "source": {
     84                "type": "git",
     85                "url": "https://github.com/GrahamCampbell/Result-Type.git",
     86                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
     87            },
     88            "dist": {
     89                "type": "zip",
     90                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
     91                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
     92                "shasum": ""
     93            },
     94            "require": {
     95                "php": "^7.2.5 || ^8.0",
     96                "phpoption/phpoption": "^1.9.3"
     97            },
     98            "require-dev": {
     99                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
     100            },
     101            "type": "library",
     102            "autoload": {
     103                "psr-4": {
     104                    "GrahamCampbell\\ResultType\\": "src/"
     105                }
     106            },
     107            "notification-url": "https://packagist.org/downloads/",
     108            "license": [
     109                "MIT"
     110            ],
     111            "authors": [
     112                {
     113                    "name": "Graham Campbell",
     114                    "email": "hello@gjcampbell.co.uk",
     115                    "homepage": "https://github.com/GrahamCampbell"
     116                }
     117            ],
     118            "description": "An Implementation Of The Result Type",
     119            "keywords": [
     120                "Graham Campbell",
     121                "GrahamCampbell",
     122                "Result Type",
     123                "Result-Type",
     124                "result"
     125            ],
     126            "support": {
     127                "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
     128                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
     129            },
     130            "funding": [
     131                {
     132                    "url": "https://github.com/GrahamCampbell",
     133                    "type": "github"
     134                },
     135                {
     136                    "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
     137                    "type": "tidelift"
     138                }
     139            ],
     140            "time": "2024-07-20T21:45:45+00:00"
    78141        },
    79142        {
    80143            "name": "myclabs/deep-copy",
    81             "version": "1.10.2",
     144            "version": "1.13.4",
    82145            "source": {
    83146                "type": "git",
    84147                "url": "https://github.com/myclabs/DeepCopy.git",
    85                 "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
    86             },
    87             "dist": {
    88                 "type": "zip",
    89                 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
    90                 "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
     148                "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
     149            },
     150            "dist": {
     151                "type": "zip",
     152                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
     153                "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
    91154                "shasum": ""
    92155            },
     
    94157                "php": "^7.1 || ^8.0"
    95158            },
    96             "replace": {
    97                 "myclabs/deep-copy": "self.version"
    98             },
    99             "require-dev": {
    100                 "doctrine/collections": "^1.0",
    101                 "doctrine/common": "^2.6",
    102                 "phpunit/phpunit": "^7.1"
     159            "conflict": {
     160                "doctrine/collections": "<1.6.8",
     161                "doctrine/common": "<2.13.3 || >=3 <3.2.2"
     162            },
     163            "require-dev": {
     164                "doctrine/collections": "^1.6.8",
     165                "doctrine/common": "^2.13.3 || ^3.2.2",
     166                "phpspec/prophecy": "^1.10",
     167                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
    103168            },
    104169            "type": "library",
     
    125190            "support": {
    126191                "issues": "https://github.com/myclabs/DeepCopy/issues",
    127                 "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
     192                "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
    128193            },
    129194            "funding": [
     
    133198                }
    134199            ],
    135             "time": "2020-11-13T09:40:50+00:00"
     200            "time": "2025-08-01T08:46:24+00:00"
    136201        },
    137202        {
    138203            "name": "nikic/php-parser",
    139             "version": "v4.13.2",
     204            "version": "v5.6.1",
    140205            "source": {
    141206                "type": "git",
    142207                "url": "https://github.com/nikic/PHP-Parser.git",
    143                 "reference": "210577fe3cf7badcc5814d99455df46564f3c077"
    144             },
    145             "dist": {
    146                 "type": "zip",
    147                 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077",
    148                 "reference": "210577fe3cf7badcc5814d99455df46564f3c077",
    149                 "shasum": ""
    150             },
    151             "require": {
     208                "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2"
     209            },
     210            "dist": {
     211                "type": "zip",
     212                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
     213                "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
     214                "shasum": ""
     215            },
     216            "require": {
     217                "ext-ctype": "*",
     218                "ext-json": "*",
    152219                "ext-tokenizer": "*",
    153                 "php": ">=7.0"
     220                "php": ">=7.4"
    154221            },
    155222            "require-dev": {
    156223                "ircmaxell/php-yacc": "^0.0.7",
    157                 "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
     224                "phpunit/phpunit": "^9.0"
    158225            },
    159226            "bin": [
     
    163230            "extra": {
    164231                "branch-alias": {
    165                     "dev-master": "4.9-dev"
     232                    "dev-master": "5.x-dev"
    166233                }
    167234            },
     
    187254            "support": {
    188255                "issues": "https://github.com/nikic/PHP-Parser/issues",
    189                 "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2"
    190             },
    191             "time": "2021-11-30T19:35:32+00:00"
     256                "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1"
     257            },
     258            "time": "2025-08-13T20:13:15+00:00"
    192259        },
    193260        {
    194261            "name": "phar-io/manifest",
    195             "version": "2.0.3",
     262            "version": "2.0.4",
    196263            "source": {
    197264                "type": "git",
    198265                "url": "https://github.com/phar-io/manifest.git",
    199                 "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
    200             },
    201             "dist": {
    202                 "type": "zip",
    203                 "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
    204                 "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
     266                "reference": "54750ef60c58e43759730615a392c31c80e23176"
     267            },
     268            "dist": {
     269                "type": "zip",
     270                "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
     271                "reference": "54750ef60c58e43759730615a392c31c80e23176",
    205272                "shasum": ""
    206273            },
    207274            "require": {
    208275                "ext-dom": "*",
     276                "ext-libxml": "*",
    209277                "ext-phar": "*",
    210278                "ext-xmlwriter": "*",
     
    247315            "support": {
    248316                "issues": "https://github.com/phar-io/manifest/issues",
    249                 "source": "https://github.com/phar-io/manifest/tree/2.0.3"
    250             },
    251             "time": "2021-07-20T11:28:43+00:00"
     317                "source": "https://github.com/phar-io/manifest/tree/2.0.4"
     318            },
     319            "funding": [
     320                {
     321                    "url": "https://github.com/theseer",
     322                    "type": "github"
     323                }
     324            ],
     325            "time": "2024-03-03T12:33:53+00:00"
    252326        },
    253327        {
    254328            "name": "phar-io/version",
    255             "version": "3.1.1",
     329            "version": "3.2.1",
    256330            "source": {
    257331                "type": "git",
    258332                "url": "https://github.com/phar-io/version.git",
    259                 "reference": "15a90844ad40f127afd244c0cad228de2a80052a"
    260             },
    261             "dist": {
    262                 "type": "zip",
    263                 "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a",
    264                 "reference": "15a90844ad40f127afd244c0cad228de2a80052a",
     333                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
     334            },
     335            "dist": {
     336                "type": "zip",
     337                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
     338                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
    265339                "shasum": ""
    266340            },
     
    298372            "support": {
    299373                "issues": "https://github.com/phar-io/version/issues",
    300                 "source": "https://github.com/phar-io/version/tree/3.1.1"
    301             },
    302             "time": "2022-02-07T21:56:48+00:00"
    303         },
    304         {
    305             "name": "phpdocumentor/reflection-common",
    306             "version": "2.2.0",
    307             "source": {
    308                 "type": "git",
    309                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
    310                 "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
    311             },
    312             "dist": {
    313                 "type": "zip",
    314                 "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
    315                 "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
    316                 "shasum": ""
    317             },
    318             "require": {
    319                 "php": "^7.2 || ^8.0"
    320             },
    321             "type": "library",
    322             "extra": {
    323                 "branch-alias": {
    324                     "dev-2.x": "2.x-dev"
     374                "source": "https://github.com/phar-io/version/tree/3.2.1"
     375            },
     376            "time": "2022-02-21T01:04:05+00:00"
     377        },
     378        {
     379            "name": "phpoption/phpoption",
     380            "version": "1.9.4",
     381            "source": {
     382                "type": "git",
     383                "url": "https://github.com/schmittjoh/php-option.git",
     384                "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d"
     385            },
     386            "dist": {
     387                "type": "zip",
     388                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
     389                "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
     390                "shasum": ""
     391            },
     392            "require": {
     393                "php": "^7.2.5 || ^8.0"
     394            },
     395            "require-dev": {
     396                "bamarni/composer-bin-plugin": "^1.8.2",
     397                "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34"
     398            },
     399            "type": "library",
     400            "extra": {
     401                "bamarni-bin": {
     402                    "bin-links": true,
     403                    "forward-command": false
     404                },
     405                "branch-alias": {
     406                    "dev-master": "1.9-dev"
    325407                }
    326408            },
    327409            "autoload": {
    328410                "psr-4": {
    329                     "phpDocumentor\\Reflection\\": "src/"
    330                 }
    331             },
    332             "notification-url": "https://packagist.org/downloads/",
    333             "license": [
    334                 "MIT"
    335             ],
    336             "authors": [
    337                 {
    338                     "name": "Jaap van Otterdijk",
    339                     "email": "opensource@ijaap.nl"
    340                 }
    341             ],
    342             "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
    343             "homepage": "http://www.phpdoc.org",
     411                    "PhpOption\\": "src/PhpOption/"
     412                }
     413            },
     414            "notification-url": "https://packagist.org/downloads/",
     415            "license": [
     416                "Apache-2.0"
     417            ],
     418            "authors": [
     419                {
     420                    "name": "Johannes M. Schmitt",
     421                    "email": "schmittjoh@gmail.com",
     422                    "homepage": "https://github.com/schmittjoh"
     423                },
     424                {
     425                    "name": "Graham Campbell",
     426                    "email": "hello@gjcampbell.co.uk",
     427                    "homepage": "https://github.com/GrahamCampbell"
     428                }
     429            ],
     430            "description": "Option Type for PHP",
    344431            "keywords": [
    345                 "FQSEN",
    346                 "phpDocumentor",
    347                 "phpdoc",
    348                 "reflection",
    349                 "static analysis"
    350             ],
    351             "support": {
    352                 "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
    353                 "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
    354             },
    355             "time": "2020-06-27T09:03:43+00:00"
    356         },
    357         {
    358             "name": "phpdocumentor/reflection-docblock",
    359             "version": "5.3.0",
    360             "source": {
    361                 "type": "git",
    362                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
    363                 "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
    364             },
    365             "dist": {
    366                 "type": "zip",
    367                 "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
    368                 "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
    369                 "shasum": ""
    370             },
    371             "require": {
    372                 "ext-filter": "*",
    373                 "php": "^7.2 || ^8.0",
    374                 "phpdocumentor/reflection-common": "^2.2",
    375                 "phpdocumentor/type-resolver": "^1.3",
    376                 "webmozart/assert": "^1.9.1"
    377             },
    378             "require-dev": {
    379                 "mockery/mockery": "~1.3.2",
    380                 "psalm/phar": "^4.8"
    381             },
    382             "type": "library",
    383             "extra": {
    384                 "branch-alias": {
    385                     "dev-master": "5.x-dev"
    386                 }
    387             },
    388             "autoload": {
    389                 "psr-4": {
    390                     "phpDocumentor\\Reflection\\": "src"
    391                 }
    392             },
    393             "notification-url": "https://packagist.org/downloads/",
    394             "license": [
    395                 "MIT"
    396             ],
    397             "authors": [
    398                 {
    399                     "name": "Mike van Riel",
    400                     "email": "me@mikevanriel.com"
    401                 },
    402                 {
    403                     "name": "Jaap van Otterdijk",
    404                     "email": "account@ijaap.nl"
    405                 }
    406             ],
    407             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
    408             "support": {
    409                 "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
    410                 "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
    411             },
    412             "time": "2021-10-19T17:43:47+00:00"
    413         },
    414         {
    415             "name": "phpdocumentor/type-resolver",
    416             "version": "1.6.0",
    417             "source": {
    418                 "type": "git",
    419                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
    420                 "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
    421             },
    422             "dist": {
    423                 "type": "zip",
    424                 "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
    425                 "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
    426                 "shasum": ""
    427             },
    428             "require": {
    429                 "php": "^7.2 || ^8.0",
    430                 "phpdocumentor/reflection-common": "^2.0"
    431             },
    432             "require-dev": {
    433                 "ext-tokenizer": "*",
    434                 "psalm/phar": "^4.8"
    435             },
    436             "type": "library",
    437             "extra": {
    438                 "branch-alias": {
    439                     "dev-1.x": "1.x-dev"
    440                 }
    441             },
    442             "autoload": {
    443                 "psr-4": {
    444                     "phpDocumentor\\Reflection\\": "src"
    445                 }
    446             },
    447             "notification-url": "https://packagist.org/downloads/",
    448             "license": [
    449                 "MIT"
    450             ],
    451             "authors": [
    452                 {
    453                     "name": "Mike van Riel",
    454                     "email": "me@mikevanriel.com"
    455                 }
    456             ],
    457             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
    458             "support": {
    459                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
    460                 "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0"
    461             },
    462             "time": "2022-01-04T19:58:01+00:00"
    463         },
    464         {
    465             "name": "phpspec/prophecy",
    466             "version": "v1.15.0",
    467             "source": {
    468                 "type": "git",
    469                 "url": "https://github.com/phpspec/prophecy.git",
    470                 "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
    471             },
    472             "dist": {
    473                 "type": "zip",
    474                 "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
    475                 "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
    476                 "shasum": ""
    477             },
    478             "require": {
    479                 "doctrine/instantiator": "^1.2",
    480                 "php": "^7.2 || ~8.0, <8.2",
    481                 "phpdocumentor/reflection-docblock": "^5.2",
    482                 "sebastian/comparator": "^3.0 || ^4.0",
    483                 "sebastian/recursion-context": "^3.0 || ^4.0"
    484             },
    485             "require-dev": {
    486                 "phpspec/phpspec": "^6.0 || ^7.0",
    487                 "phpunit/phpunit": "^8.0 || ^9.0"
    488             },
    489             "type": "library",
    490             "extra": {
    491                 "branch-alias": {
    492                     "dev-master": "1.x-dev"
    493                 }
    494             },
    495             "autoload": {
    496                 "psr-4": {
    497                     "Prophecy\\": "src/Prophecy"
    498                 }
    499             },
    500             "notification-url": "https://packagist.org/downloads/",
    501             "license": [
    502                 "MIT"
    503             ],
    504             "authors": [
    505                 {
    506                     "name": "Konstantin Kudryashov",
    507                     "email": "ever.zet@gmail.com",
    508                     "homepage": "http://everzet.com"
    509                 },
    510                 {
    511                     "name": "Marcello Duarte",
    512                     "email": "marcello.duarte@gmail.com"
    513                 }
    514             ],
    515             "description": "Highly opinionated mocking framework for PHP 5.3+",
    516             "homepage": "https://github.com/phpspec/prophecy",
    517             "keywords": [
    518                 "Double",
    519                 "Dummy",
    520                 "fake",
    521                 "mock",
    522                 "spy",
    523                 "stub"
    524             ],
    525             "support": {
    526                 "issues": "https://github.com/phpspec/prophecy/issues",
    527                 "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
    528             },
    529             "time": "2021-12-08T12:19:24+00:00"
     432                "language",
     433                "option",
     434                "php",
     435                "type"
     436            ],
     437            "support": {
     438                "issues": "https://github.com/schmittjoh/php-option/issues",
     439                "source": "https://github.com/schmittjoh/php-option/tree/1.9.4"
     440            },
     441            "funding": [
     442                {
     443                    "url": "https://github.com/GrahamCampbell",
     444                    "type": "github"
     445                },
     446                {
     447                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
     448                    "type": "tidelift"
     449                }
     450            ],
     451            "time": "2025-08-21T11:53:16+00:00"
    530452        },
    531453        {
    532454            "name": "phpunit/php-code-coverage",
    533             "version": "9.2.10",
     455            "version": "9.2.32",
    534456            "source": {
    535457                "type": "git",
    536458                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
    537                 "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687"
    538             },
    539             "dist": {
    540                 "type": "zip",
    541                 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687",
    542                 "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687",
     459                "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5"
     460            },
     461            "dist": {
     462                "type": "zip",
     463                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5",
     464                "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5",
    543465                "shasum": ""
    544466            },
     
    547469                "ext-libxml": "*",
    548470                "ext-xmlwriter": "*",
    549                 "nikic/php-parser": "^4.13.0",
     471                "nikic/php-parser": "^4.19.1 || ^5.1.0",
    550472                "php": ">=7.3",
    551                 "phpunit/php-file-iterator": "^3.0.3",
    552                 "phpunit/php-text-template": "^2.0.2",
    553                 "sebastian/code-unit-reverse-lookup": "^2.0.2",
    554                 "sebastian/complexity": "^2.0",
    555                 "sebastian/environment": "^5.1.2",
    556                 "sebastian/lines-of-code": "^1.0.3",
    557                 "sebastian/version": "^3.0.1",
    558                 "theseer/tokenizer": "^1.2.0"
    559             },
    560             "require-dev": {
    561                 "phpunit/phpunit": "^9.3"
     473                "phpunit/php-file-iterator": "^3.0.6",
     474                "phpunit/php-text-template": "^2.0.4",
     475                "sebastian/code-unit-reverse-lookup": "^2.0.3",
     476                "sebastian/complexity": "^2.0.3",
     477                "sebastian/environment": "^5.1.5",
     478                "sebastian/lines-of-code": "^1.0.4",
     479                "sebastian/version": "^3.0.2",
     480                "theseer/tokenizer": "^1.2.3"
     481            },
     482            "require-dev": {
     483                "phpunit/phpunit": "^9.6"
    562484            },
    563485            "suggest": {
    564                 "ext-pcov": "*",
    565                 "ext-xdebug": "*"
    566             },
    567             "type": "library",
    568             "extra": {
    569                 "branch-alias": {
    570                     "dev-master": "9.2-dev"
     486                "ext-pcov": "PHP extension that provides line coverage",
     487                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
     488            },
     489            "type": "library",
     490            "extra": {
     491                "branch-alias": {
     492                    "dev-main": "9.2.x-dev"
    571493                }
    572494            },
     
    596518            "support": {
    597519                "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
    598                 "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10"
     520                "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
     521                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32"
    599522            },
    600523            "funding": [
     
    604527                }
    605528            ],
    606             "time": "2021-12-05T09:12:13+00:00"
     529            "time": "2024-08-22T04:23:01+00:00"
    607530        },
    608531        {
     
    849772        {
    850773            "name": "phpunit/phpunit",
    851             "version": "9.5.13",
     774            "version": "9.6.25",
    852775            "source": {
    853776                "type": "git",
    854777                "url": "https://github.com/sebastianbergmann/phpunit.git",
    855                 "reference": "597cb647654ede35e43b137926dfdfef0fb11743"
    856             },
    857             "dist": {
    858                 "type": "zip",
    859                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743",
    860                 "reference": "597cb647654ede35e43b137926dfdfef0fb11743",
    861                 "shasum": ""
    862             },
    863             "require": {
    864                 "doctrine/instantiator": "^1.3.1",
     778                "reference": "049c011e01be805202d8eebedef49f769a8ec7b7"
     779            },
     780            "dist": {
     781                "type": "zip",
     782                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/049c011e01be805202d8eebedef49f769a8ec7b7",
     783                "reference": "049c011e01be805202d8eebedef49f769a8ec7b7",
     784                "shasum": ""
     785            },
     786            "require": {
     787                "doctrine/instantiator": "^1.5.0 || ^2",
    865788                "ext-dom": "*",
    866789                "ext-json": "*",
     
    869792                "ext-xml": "*",
    870793                "ext-xmlwriter": "*",
    871                 "myclabs/deep-copy": "^1.10.1",
    872                 "phar-io/manifest": "^2.0.3",
    873                 "phar-io/version": "^3.0.2",
     794                "myclabs/deep-copy": "^1.13.4",
     795                "phar-io/manifest": "^2.0.4",
     796                "phar-io/version": "^3.2.1",
    874797                "php": ">=7.3",
    875                 "phpspec/prophecy": "^1.12.1",
    876                 "phpunit/php-code-coverage": "^9.2.7",
    877                 "phpunit/php-file-iterator": "^3.0.5",
     798                "phpunit/php-code-coverage": "^9.2.32",
     799                "phpunit/php-file-iterator": "^3.0.6",
    878800                "phpunit/php-invoker": "^3.1.1",
    879                 "phpunit/php-text-template": "^2.0.3",
    880                 "phpunit/php-timer": "^5.0.2",
    881                 "sebastian/cli-parser": "^1.0.1",
    882                 "sebastian/code-unit": "^1.0.6",
    883                 "sebastian/comparator": "^4.0.5",
    884                 "sebastian/diff": "^4.0.3",
    885                 "sebastian/environment": "^5.1.3",
    886                 "sebastian/exporter": "^4.0.3",
    887                 "sebastian/global-state": "^5.0.1",
    888                 "sebastian/object-enumerator": "^4.0.3",
    889                 "sebastian/resource-operations": "^3.0.3",
    890                 "sebastian/type": "^2.3.4",
     801                "phpunit/php-text-template": "^2.0.4",
     802                "phpunit/php-timer": "^5.0.3",
     803                "sebastian/cli-parser": "^1.0.2",
     804                "sebastian/code-unit": "^1.0.8",
     805                "sebastian/comparator": "^4.0.9",
     806                "sebastian/diff": "^4.0.6",
     807                "sebastian/environment": "^5.1.5",
     808                "sebastian/exporter": "^4.0.6",
     809                "sebastian/global-state": "^5.0.8",
     810                "sebastian/object-enumerator": "^4.0.4",
     811                "sebastian/resource-operations": "^3.0.4",
     812                "sebastian/type": "^3.2.1",
    891813                "sebastian/version": "^3.0.2"
    892814            },
    893             "require-dev": {
    894                 "ext-pdo": "*",
    895                 "phpspec/prophecy-phpunit": "^2.0.1"
    896             },
    897815            "suggest": {
    898                 "ext-soap": "*",
    899                 "ext-xdebug": "*"
     816                "ext-soap": "To be able to generate mocks based on WSDL files",
     817                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
    900818            },
    901819            "bin": [
     
    905823            "extra": {
    906824                "branch-alias": {
    907                     "dev-master": "9.5-dev"
     825                    "dev-master": "9.6-dev"
    908826                }
    909827            },
     
    936854            "support": {
    937855                "issues": "https://github.com/sebastianbergmann/phpunit/issues",
    938                 "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13"
     856                "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
     857                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.25"
    939858            },
    940859            "funding": [
     
    946865                    "url": "https://github.com/sebastianbergmann",
    947866                    "type": "github"
    948                 }
    949             ],
    950             "time": "2022-01-24T07:33:35+00:00"
     867                },
     868                {
     869                    "url": "https://liberapay.com/sebastianbergmann",
     870                    "type": "liberapay"
     871                },
     872                {
     873                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     874                    "type": "thanks_dev"
     875                },
     876                {
     877                    "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
     878                    "type": "tidelift"
     879                }
     880            ],
     881            "time": "2025-08-20T14:38:31+00:00"
    951882        },
    952883        {
    953884            "name": "sebastian/cli-parser",
    954             "version": "1.0.1",
     885            "version": "1.0.2",
    955886            "source": {
    956887                "type": "git",
    957888                "url": "https://github.com/sebastianbergmann/cli-parser.git",
    958                 "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
    959             },
    960             "dist": {
    961                 "type": "zip",
    962                 "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
    963                 "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
     889                "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
     890            },
     891            "dist": {
     892                "type": "zip",
     893                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
     894                "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
    964895                "shasum": ""
    965896            },
     
    996927            "support": {
    997928                "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
    998                 "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
     929                "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
    999930            },
    1000931            "funding": [
     
    1004935                }
    1005936            ],
    1006             "time": "2020-09-28T06:08:49+00:00"
     937            "time": "2024-03-02T06:27:43+00:00"
    1007938        },
    1008939        {
     
    11191050        {
    11201051            "name": "sebastian/comparator",
    1121             "version": "4.0.6",
     1052            "version": "4.0.9",
    11221053            "source": {
    11231054                "type": "git",
    11241055                "url": "https://github.com/sebastianbergmann/comparator.git",
    1125                 "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
    1126             },
    1127             "dist": {
    1128                 "type": "zip",
    1129                 "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
    1130                 "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
     1056                "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
     1057            },
     1058            "dist": {
     1059                "type": "zip",
     1060                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
     1061                "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
    11311062                "shasum": ""
    11321063            },
     
    11811112            "support": {
    11821113                "issues": "https://github.com/sebastianbergmann/comparator/issues",
    1183                 "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
     1114                "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
    11841115            },
    11851116            "funding": [
     
    11871118                    "url": "https://github.com/sebastianbergmann",
    11881119                    "type": "github"
    1189                 }
    1190             ],
    1191             "time": "2020-10-26T15:49:45+00:00"
     1120                },
     1121                {
     1122                    "url": "https://liberapay.com/sebastianbergmann",
     1123                    "type": "liberapay"
     1124                },
     1125                {
     1126                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1127                    "type": "thanks_dev"
     1128                },
     1129                {
     1130                    "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
     1131                    "type": "tidelift"
     1132                }
     1133            ],
     1134            "time": "2025-08-10T06:51:50+00:00"
    11921135        },
    11931136        {
    11941137            "name": "sebastian/complexity",
    1195             "version": "2.0.2",
     1138            "version": "2.0.3",
    11961139            "source": {
    11971140                "type": "git",
    11981141                "url": "https://github.com/sebastianbergmann/complexity.git",
    1199                 "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
    1200             },
    1201             "dist": {
    1202                 "type": "zip",
    1203                 "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
    1204                 "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
    1205                 "shasum": ""
    1206             },
    1207             "require": {
    1208                 "nikic/php-parser": "^4.7",
     1142                "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
     1143            },
     1144            "dist": {
     1145                "type": "zip",
     1146                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
     1147                "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
     1148                "shasum": ""
     1149            },
     1150            "require": {
     1151                "nikic/php-parser": "^4.18 || ^5.0",
    12091152                "php": ">=7.3"
    12101153            },
     
    12381181            "support": {
    12391182                "issues": "https://github.com/sebastianbergmann/complexity/issues",
    1240                 "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
     1183                "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
    12411184            },
    12421185            "funding": [
     
    12461189                }
    12471190            ],
    1248             "time": "2020-10-26T15:52:27+00:00"
     1191            "time": "2023-12-22T06:19:30+00:00"
    12491192        },
    12501193        {
    12511194            "name": "sebastian/diff",
    1252             "version": "4.0.4",
     1195            "version": "4.0.6",
    12531196            "source": {
    12541197                "type": "git",
    12551198                "url": "https://github.com/sebastianbergmann/diff.git",
    1256                 "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
    1257             },
    1258             "dist": {
    1259                 "type": "zip",
    1260                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
    1261                 "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
     1199                "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
     1200            },
     1201            "dist": {
     1202                "type": "zip",
     1203                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
     1204                "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
    12621205                "shasum": ""
    12631206            },
     
    13041247            "support": {
    13051248                "issues": "https://github.com/sebastianbergmann/diff/issues",
    1306                 "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
     1249                "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
    13071250            },
    13081251            "funding": [
     
    13121255                }
    13131256            ],
    1314             "time": "2020-10-26T13:10:38+00:00"
     1257            "time": "2024-03-02T06:30:58+00:00"
    13151258        },
    13161259        {
    13171260            "name": "sebastian/environment",
    1318             "version": "5.1.3",
     1261            "version": "5.1.5",
    13191262            "source": {
    13201263                "type": "git",
    13211264                "url": "https://github.com/sebastianbergmann/environment.git",
    1322                 "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
    1323             },
    1324             "dist": {
    1325                 "type": "zip",
    1326                 "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
    1327                 "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
     1265                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
     1266            },
     1267            "dist": {
     1268                "type": "zip",
     1269                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
     1270                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
    13281271                "shasum": ""
    13291272            },
     
    13671310            "support": {
    13681311                "issues": "https://github.com/sebastianbergmann/environment/issues",
    1369                 "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3"
     1312                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
    13701313            },
    13711314            "funding": [
     
    13751318                }
    13761319            ],
    1377             "time": "2020-09-28T05:52:38+00:00"
     1320            "time": "2023-02-03T06:03:51+00:00"
    13781321        },
    13791322        {
    13801323            "name": "sebastian/exporter",
    1381             "version": "4.0.4",
     1324            "version": "4.0.6",
    13821325            "source": {
    13831326                "type": "git",
    13841327                "url": "https://github.com/sebastianbergmann/exporter.git",
    1385                 "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
    1386             },
    1387             "dist": {
    1388                 "type": "zip",
    1389                 "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
    1390                 "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
     1328                "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
     1329            },
     1330            "dist": {
     1331                "type": "zip",
     1332                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
     1333                "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
    13911334                "shasum": ""
    13921335            },
     
    14441387            "support": {
    14451388                "issues": "https://github.com/sebastianbergmann/exporter/issues",
    1446                 "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
     1389                "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
    14471390            },
    14481391            "funding": [
     
    14521395                }
    14531396            ],
    1454             "time": "2021-11-11T14:18:36+00:00"
     1397            "time": "2024-03-02T06:33:00+00:00"
    14551398        },
    14561399        {
    14571400            "name": "sebastian/global-state",
    1458             "version": "5.0.4",
     1401            "version": "5.0.8",
    14591402            "source": {
    14601403                "type": "git",
    14611404                "url": "https://github.com/sebastianbergmann/global-state.git",
    1462                 "reference": "19c519631c5a511b7ed0ad64a6713fdb3fd25fe4"
    1463             },
    1464             "dist": {
    1465                 "type": "zip",
    1466                 "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/19c519631c5a511b7ed0ad64a6713fdb3fd25fe4",
    1467                 "reference": "19c519631c5a511b7ed0ad64a6713fdb3fd25fe4",
     1405                "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
     1406            },
     1407            "dist": {
     1408                "type": "zip",
     1409                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
     1410                "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
    14681411                "shasum": ""
    14691412            },
     
    15081451            "support": {
    15091452                "issues": "https://github.com/sebastianbergmann/global-state/issues",
    1510                 "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.4"
     1453                "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
    15111454            },
    15121455            "funding": [
     
    15141457                    "url": "https://github.com/sebastianbergmann",
    15151458                    "type": "github"
    1516                 }
    1517             ],
    1518             "time": "2022-02-10T07:01:19+00:00"
     1459                },
     1460                {
     1461                    "url": "https://liberapay.com/sebastianbergmann",
     1462                    "type": "liberapay"
     1463                },
     1464                {
     1465                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1466                    "type": "thanks_dev"
     1467                },
     1468                {
     1469                    "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
     1470                    "type": "tidelift"
     1471                }
     1472            ],
     1473            "time": "2025-08-10T07:10:35+00:00"
    15191474        },
    15201475        {
    15211476            "name": "sebastian/lines-of-code",
    1522             "version": "1.0.3",
     1477            "version": "1.0.4",
    15231478            "source": {
    15241479                "type": "git",
    15251480                "url": "https://github.com/sebastianbergmann/lines-of-code.git",
    1526                 "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
    1527             },
    1528             "dist": {
    1529                 "type": "zip",
    1530                 "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
    1531                 "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
    1532                 "shasum": ""
    1533             },
    1534             "require": {
    1535                 "nikic/php-parser": "^4.6",
     1481                "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
     1482            },
     1483            "dist": {
     1484                "type": "zip",
     1485                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
     1486                "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
     1487                "shasum": ""
     1488            },
     1489            "require": {
     1490                "nikic/php-parser": "^4.18 || ^5.0",
    15361491                "php": ">=7.3"
    15371492            },
     
    15651520            "support": {
    15661521                "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
    1567                 "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
     1522                "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
    15681523            },
    15691524            "funding": [
     
    15731528                }
    15741529            ],
    1575             "time": "2020-11-28T06:42:11+00:00"
     1530            "time": "2023-12-22T06:20:34+00:00"
    15761531        },
    15771532        {
     
    16891644        {
    16901645            "name": "sebastian/recursion-context",
    1691             "version": "4.0.4",
     1646            "version": "4.0.6",
    16921647            "source": {
    16931648                "type": "git",
    16941649                "url": "https://github.com/sebastianbergmann/recursion-context.git",
    1695                 "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
    1696             },
    1697             "dist": {
    1698                 "type": "zip",
    1699                 "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
    1700                 "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
     1650                "reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
     1651            },
     1652            "dist": {
     1653                "type": "zip",
     1654                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
     1655                "reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
    17011656                "shasum": ""
    17021657            },
     
    17371692            ],
    17381693            "description": "Provides functionality to recursively process PHP variables",
    1739             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
     1694            "homepage": "https://github.com/sebastianbergmann/recursion-context",
    17401695            "support": {
    17411696                "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
    1742                 "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
     1697                "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
    17431698            },
    17441699            "funding": [
     
    17461701                    "url": "https://github.com/sebastianbergmann",
    17471702                    "type": "github"
    1748                 }
    1749             ],
    1750             "time": "2020-10-26T13:17:30+00:00"
     1703                },
     1704                {
     1705                    "url": "https://liberapay.com/sebastianbergmann",
     1706                    "type": "liberapay"
     1707                },
     1708                {
     1709                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1710                    "type": "thanks_dev"
     1711                },
     1712                {
     1713                    "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
     1714                    "type": "tidelift"
     1715                }
     1716            ],
     1717            "time": "2025-08-10T06:57:39+00:00"
    17511718        },
    17521719        {
    17531720            "name": "sebastian/resource-operations",
    1754             "version": "3.0.3",
     1721            "version": "3.0.4",
    17551722            "source": {
    17561723                "type": "git",
    17571724                "url": "https://github.com/sebastianbergmann/resource-operations.git",
    1758                 "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
    1759             },
    1760             "dist": {
    1761                 "type": "zip",
    1762                 "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
    1763                 "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
     1725                "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
     1726            },
     1727            "dist": {
     1728                "type": "zip",
     1729                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
     1730                "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
    17641731                "shasum": ""
    17651732            },
     
    17731740            "extra": {
    17741741                "branch-alias": {
    1775                     "dev-master": "3.0-dev"
     1742                    "dev-main": "3.0-dev"
    17761743                }
    17771744            },
     
    17941761            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
    17951762            "support": {
    1796                 "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
    1797                 "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
     1763                "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
    17981764            },
    17991765            "funding": [
     
    18031769                }
    18041770            ],
    1805             "time": "2020-09-28T06:45:17+00:00"
     1771            "time": "2024-03-14T16:00:52+00:00"
    18061772        },
    18071773        {
    18081774            "name": "sebastian/type",
    1809             "version": "2.3.4",
     1775            "version": "3.2.1",
    18101776            "source": {
    18111777                "type": "git",
    18121778                "url": "https://github.com/sebastianbergmann/type.git",
    1813                 "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
    1814             },
    1815             "dist": {
    1816                 "type": "zip",
    1817                 "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
    1818                 "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
     1779                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
     1780            },
     1781            "dist": {
     1782                "type": "zip",
     1783                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
     1784                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
    18191785                "shasum": ""
    18201786            },
     
    18231789            },
    18241790            "require-dev": {
    1825                 "phpunit/phpunit": "^9.3"
    1826             },
    1827             "type": "library",
    1828             "extra": {
    1829                 "branch-alias": {
    1830                     "dev-master": "2.3-dev"
     1791                "phpunit/phpunit": "^9.5"
     1792            },
     1793            "type": "library",
     1794            "extra": {
     1795                "branch-alias": {
     1796                    "dev-master": "3.2-dev"
    18311797                }
    18321798            },
     
    18511817            "support": {
    18521818                "issues": "https://github.com/sebastianbergmann/type/issues",
    1853                 "source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
     1819                "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
    18541820            },
    18551821            "funding": [
     
    18591825                }
    18601826            ],
    1861             "time": "2021-06-15T12:49:02+00:00"
     1827            "time": "2023-02-03T06:13:03+00:00"
    18621828        },
    18631829        {
     
    19161882        {
    19171883            "name": "symfony/polyfill-ctype",
    1918             "version": "v1.24.0",
     1884            "version": "v1.33.0",
    19191885            "source": {
    19201886                "type": "git",
    19211887                "url": "https://github.com/symfony/polyfill-ctype.git",
    1922                 "reference": "30885182c981ab175d4d034db0f6f469898070ab"
    1923             },
    1924             "dist": {
    1925                 "type": "zip",
    1926                 "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
    1927                 "reference": "30885182c981ab175d4d034db0f6f469898070ab",
    1928                 "shasum": ""
    1929             },
    1930             "require": {
    1931                 "php": ">=7.1"
     1888                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
     1889            },
     1890            "dist": {
     1891                "type": "zip",
     1892                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
     1893                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
     1894                "shasum": ""
     1895            },
     1896            "require": {
     1897                "php": ">=7.2"
    19321898            },
    19331899            "provide": {
     
    19391905            "type": "library",
    19401906            "extra": {
    1941                 "branch-alias": {
    1942                     "dev-main": "1.23-dev"
    1943                 },
    19441907                "thanks": {
    1945                     "name": "symfony/polyfill",
    1946                     "url": "https://github.com/symfony/polyfill"
    1947                 }
    1948             },
    1949             "autoload": {
     1908                    "url": "https://github.com/symfony/polyfill",
     1909                    "name": "symfony/polyfill"
     1910                }
     1911            },
     1912            "autoload": {
     1913                "files": [
     1914                    "bootstrap.php"
     1915                ],
    19501916                "psr-4": {
    19511917                    "Symfony\\Polyfill\\Ctype\\": ""
    1952                 },
    1953                 "files": [
    1954                     "bootstrap.php"
    1955                 ]
     1918                }
    19561919            },
    19571920            "notification-url": "https://packagist.org/downloads/",
     
    19781941            ],
    19791942            "support": {
    1980                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
     1943                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
    19811944            },
    19821945            "funding": [
     
    19901953                },
    19911954                {
     1955                    "url": "https://github.com/nicolas-grekas",
     1956                    "type": "github"
     1957                },
     1958                {
    19921959                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
    19931960                    "type": "tidelift"
    19941961                }
    19951962            ],
    1996             "time": "2021-10-20T20:35:02+00:00"
     1963            "time": "2024-09-09T11:45:10+00:00"
     1964        },
     1965        {
     1966            "name": "symfony/polyfill-mbstring",
     1967            "version": "v1.33.0",
     1968            "source": {
     1969                "type": "git",
     1970                "url": "https://github.com/symfony/polyfill-mbstring.git",
     1971                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
     1972            },
     1973            "dist": {
     1974                "type": "zip",
     1975                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
     1976                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
     1977                "shasum": ""
     1978            },
     1979            "require": {
     1980                "ext-iconv": "*",
     1981                "php": ">=7.2"
     1982            },
     1983            "provide": {
     1984                "ext-mbstring": "*"
     1985            },
     1986            "suggest": {
     1987                "ext-mbstring": "For best performance"
     1988            },
     1989            "type": "library",
     1990            "extra": {
     1991                "thanks": {
     1992                    "url": "https://github.com/symfony/polyfill",
     1993                    "name": "symfony/polyfill"
     1994                }
     1995            },
     1996            "autoload": {
     1997                "files": [
     1998                    "bootstrap.php"
     1999                ],
     2000                "psr-4": {
     2001                    "Symfony\\Polyfill\\Mbstring\\": ""
     2002                }
     2003            },
     2004            "notification-url": "https://packagist.org/downloads/",
     2005            "license": [
     2006                "MIT"
     2007            ],
     2008            "authors": [
     2009                {
     2010                    "name": "Nicolas Grekas",
     2011                    "email": "p@tchwork.com"
     2012                },
     2013                {
     2014                    "name": "Symfony Community",
     2015                    "homepage": "https://symfony.com/contributors"
     2016                }
     2017            ],
     2018            "description": "Symfony polyfill for the Mbstring extension",
     2019            "homepage": "https://symfony.com",
     2020            "keywords": [
     2021                "compatibility",
     2022                "mbstring",
     2023                "polyfill",
     2024                "portable",
     2025                "shim"
     2026            ],
     2027            "support": {
     2028                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
     2029            },
     2030            "funding": [
     2031                {
     2032                    "url": "https://symfony.com/sponsor",
     2033                    "type": "custom"
     2034                },
     2035                {
     2036                    "url": "https://github.com/fabpot",
     2037                    "type": "github"
     2038                },
     2039                {
     2040                    "url": "https://github.com/nicolas-grekas",
     2041                    "type": "github"
     2042                },
     2043                {
     2044                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
     2045                    "type": "tidelift"
     2046                }
     2047            ],
     2048            "time": "2024-12-23T08:48:59+00:00"
     2049        },
     2050        {
     2051            "name": "symfony/polyfill-php80",
     2052            "version": "v1.33.0",
     2053            "source": {
     2054                "type": "git",
     2055                "url": "https://github.com/symfony/polyfill-php80.git",
     2056                "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
     2057            },
     2058            "dist": {
     2059                "type": "zip",
     2060                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
     2061                "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
     2062                "shasum": ""
     2063            },
     2064            "require": {
     2065                "php": ">=7.2"
     2066            },
     2067            "type": "library",
     2068            "extra": {
     2069                "thanks": {
     2070                    "url": "https://github.com/symfony/polyfill",
     2071                    "name": "symfony/polyfill"
     2072                }
     2073            },
     2074            "autoload": {
     2075                "files": [
     2076                    "bootstrap.php"
     2077                ],
     2078                "psr-4": {
     2079                    "Symfony\\Polyfill\\Php80\\": ""
     2080                },
     2081                "classmap": [
     2082                    "Resources/stubs"
     2083                ]
     2084            },
     2085            "notification-url": "https://packagist.org/downloads/",
     2086            "license": [
     2087                "MIT"
     2088            ],
     2089            "authors": [
     2090                {
     2091                    "name": "Ion Bazan",
     2092                    "email": "ion.bazan@gmail.com"
     2093                },
     2094                {
     2095                    "name": "Nicolas Grekas",
     2096                    "email": "p@tchwork.com"
     2097                },
     2098                {
     2099                    "name": "Symfony Community",
     2100                    "homepage": "https://symfony.com/contributors"
     2101                }
     2102            ],
     2103            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
     2104            "homepage": "https://symfony.com",
     2105            "keywords": [
     2106                "compatibility",
     2107                "polyfill",
     2108                "portable",
     2109                "shim"
     2110            ],
     2111            "support": {
     2112                "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
     2113            },
     2114            "funding": [
     2115                {
     2116                    "url": "https://symfony.com/sponsor",
     2117                    "type": "custom"
     2118                },
     2119                {
     2120                    "url": "https://github.com/fabpot",
     2121                    "type": "github"
     2122                },
     2123                {
     2124                    "url": "https://github.com/nicolas-grekas",
     2125                    "type": "github"
     2126                },
     2127                {
     2128                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
     2129                    "type": "tidelift"
     2130                }
     2131            ],
     2132            "time": "2025-01-02T08:10:11+00:00"
    19972133        },
    19982134        {
    19992135            "name": "theseer/tokenizer",
    2000             "version": "1.2.1",
     2136            "version": "1.2.3",
    20012137            "source": {
    20022138                "type": "git",
    20032139                "url": "https://github.com/theseer/tokenizer.git",
    2004                 "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
    2005             },
    2006             "dist": {
    2007                 "type": "zip",
    2008                 "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
    2009                 "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
     2140                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
     2141            },
     2142            "dist": {
     2143                "type": "zip",
     2144                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
     2145                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
    20102146                "shasum": ""
    20112147            },
     
    20362172            "support": {
    20372173                "issues": "https://github.com/theseer/tokenizer/issues",
    2038                 "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
     2174                "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
    20392175            },
    20402176            "funding": [
     
    20442180                }
    20452181            ],
    2046             "time": "2021-07-28T10:34:58+00:00"
    2047         },
    2048         {
    2049             "name": "webmozart/assert",
    2050             "version": "1.10.0",
    2051             "source": {
    2052                 "type": "git",
    2053                 "url": "https://github.com/webmozarts/assert.git",
    2054                 "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
    2055             },
    2056             "dist": {
    2057                 "type": "zip",
    2058                 "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
    2059                 "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
    2060                 "shasum": ""
    2061             },
    2062             "require": {
    2063                 "php": "^7.2 || ^8.0",
    2064                 "symfony/polyfill-ctype": "^1.8"
    2065             },
    2066             "conflict": {
    2067                 "phpstan/phpstan": "<0.12.20",
    2068                 "vimeo/psalm": "<4.6.1 || 4.6.2"
    2069             },
    2070             "require-dev": {
    2071                 "phpunit/phpunit": "^8.5.13"
    2072             },
    2073             "type": "library",
    2074             "extra": {
    2075                 "branch-alias": {
    2076                     "dev-master": "1.10-dev"
     2182            "time": "2024-03-03T12:36:25+00:00"
     2183        },
     2184        {
     2185            "name": "vlucas/phpdotenv",
     2186            "version": "v5.6.2",
     2187            "source": {
     2188                "type": "git",
     2189                "url": "https://github.com/vlucas/phpdotenv.git",
     2190                "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af"
     2191            },
     2192            "dist": {
     2193                "type": "zip",
     2194                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
     2195                "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
     2196                "shasum": ""
     2197            },
     2198            "require": {
     2199                "ext-pcre": "*",
     2200                "graham-campbell/result-type": "^1.1.3",
     2201                "php": "^7.2.5 || ^8.0",
     2202                "phpoption/phpoption": "^1.9.3",
     2203                "symfony/polyfill-ctype": "^1.24",
     2204                "symfony/polyfill-mbstring": "^1.24",
     2205                "symfony/polyfill-php80": "^1.24"
     2206            },
     2207            "require-dev": {
     2208                "bamarni/composer-bin-plugin": "^1.8.2",
     2209                "ext-filter": "*",
     2210                "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
     2211            },
     2212            "suggest": {
     2213                "ext-filter": "Required to use the boolean validator."
     2214            },
     2215            "type": "library",
     2216            "extra": {
     2217                "bamarni-bin": {
     2218                    "bin-links": true,
     2219                    "forward-command": false
     2220                },
     2221                "branch-alias": {
     2222                    "dev-master": "5.6-dev"
    20772223                }
    20782224            },
    20792225            "autoload": {
    20802226                "psr-4": {
    2081                     "Webmozart\\Assert\\": "src/"
    2082                 }
    2083             },
    2084             "notification-url": "https://packagist.org/downloads/",
    2085             "license": [
    2086                 "MIT"
    2087             ],
    2088             "authors": [
    2089                 {
    2090                     "name": "Bernhard Schussek",
    2091                     "email": "bschussek@gmail.com"
    2092                 }
    2093             ],
    2094             "description": "Assertions to validate method input/output with nice error messages.",
     2227                    "Dotenv\\": "src/"
     2228                }
     2229            },
     2230            "notification-url": "https://packagist.org/downloads/",
     2231            "license": [
     2232                "BSD-3-Clause"
     2233            ],
     2234            "authors": [
     2235                {
     2236                    "name": "Graham Campbell",
     2237                    "email": "hello@gjcampbell.co.uk",
     2238                    "homepage": "https://github.com/GrahamCampbell"
     2239                },
     2240                {
     2241                    "name": "Vance Lucas",
     2242                    "email": "vance@vancelucas.com",
     2243                    "homepage": "https://github.com/vlucas"
     2244                }
     2245            ],
     2246            "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
    20952247            "keywords": [
    2096                 "assert",
    2097                 "check",
    2098                 "validate"
    2099             ],
    2100             "support": {
    2101                 "issues": "https://github.com/webmozarts/assert/issues",
    2102                 "source": "https://github.com/webmozarts/assert/tree/1.10.0"
    2103             },
    2104             "time": "2021-03-09T10:59:23+00:00"
     2248                "dotenv",
     2249                "env",
     2250                "environment"
     2251            ],
     2252            "support": {
     2253                "issues": "https://github.com/vlucas/phpdotenv/issues",
     2254                "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2"
     2255            },
     2256            "funding": [
     2257                {
     2258                    "url": "https://github.com/GrahamCampbell",
     2259                    "type": "github"
     2260                },
     2261                {
     2262                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
     2263                    "type": "tidelift"
     2264                }
     2265            ],
     2266            "time": "2025-04-30T23:37:27+00:00"
    21052267        }
    21062268    ],
    21072269    "aliases": [],
    21082270    "minimum-stability": "stable",
    2109     "stability-flags": [],
     2271    "stability-flags": {},
    21102272    "prefer-stable": false,
    21112273    "prefer-lowest": false,
     
    21162278        "ext-zip": "*"
    21172279    },
    2118     "platform-dev": [],
    2119     "plugin-api-version": "2.0.0"
     2280    "platform-dev": {},
     2281    "plugin-api-version": "2.6.0"
    21202282}
  • linguise/trunk/linguise.php

    r3362901 r3366846  
    55 * Plugin URI: https://www.linguise.com/
    66 * Description: Linguise translation plugin
    7  * Version:2.1.71
     7 * Version:2.1.72
    88 * Text Domain: linguise
    99 * Domain Path: /languages
     
    387387// Load all the super-important stuff first
    388388require_once ABSPATH . 'wp-admin/includes/plugin.php';
     389
     390include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'HTMLHelper.php'); // Main HTML Helper, required by fragment handler
     391include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'FragmentBase.php'); // Base class for fragment handlers
    389392include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'FragmentHandler.php');
    390393include_once(__DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'AttributeHandler.php');
  • linguise/trunk/readme.txt

    r3362901 r3366846  
    44Requires at least: 4.0
    55Tested up to: 6.8
    6 Stable tag:2.1.71
     6Stable tag:2.1.72
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    104104
    105105== Changelog ==
     106= 2.1.72 =
     107- Chore: Refactored fragment handler code
     108
    106109= 2.1.71 =
    107110- Fix: Broken hreflang issue on SEMrush plugin
  • linguise/trunk/src/AttributeHandler.php

    r3339453 r3366846  
    33namespace Linguise\WordPress;
    44
     5use Linguise\WordPress\FragmentHandler;
     6use Linguise\WordPress\HTMLHelper;
    57use Linguise\Vendor\JsonPath\JsonObject;
    6 use Linguise\WordPress\FragmentHandler;
    78use Linguise\Vendor\Linguise\Script\Core\Debug;
    89
     
    156157    public static function findWPFragments(&$html_data)
    157158    {
    158         $html_dom = self::loadHTML($html_data);
     159        $html_dom = HTMLHelper::loadHTML($html_data);
    159160        if (empty($html_dom)) {
    160161            return [];
     
    179180
    180181                // Unroll the entity
    181                 $key_data = html_entity_decode(self::unprotectEntity($key_data), ENT_QUOTES, 'UTF-8');
     182                $key_data = html_entity_decode(HTMLHelper::unprotectEntity($key_data), ENT_QUOTES, 'UTF-8');
    182183
    183184                // Is the data URL encoded?
     
    236237
    237238        if (!empty($all_fragments)) {
    238             $html_data = self::saveHTML($html_dom);
     239            $html_data = HTMLHelper::saveHTML($html_dom);
    239240        }
    240241
     
    283284        }
    284285
    285         $html_dom = self::loadHTML($html_data);
     286        $html_dom = HTMLHelper::loadHTML($html_data);
    286287        if (empty($html_dom)) {
    287288            return $html_data;
     
    321322
    322323                // Since we have protection enabled around this!
    323                 $match_data = html_entity_decode(self::unprotectEntity($match_data), ENT_QUOTES, 'UTF-8');
     324                $match_data = html_entity_decode(HTMLHelper::unprotectEntity($match_data), ENT_QUOTES, 'UTF-8');
    324325
    325326                $should_encode = isset($matched['encode']) && $matched['encode'];
     
    347348                    }
    348349
    349                     $protected_json = self::protectEntity($replaced_text);
     350                    $protected_json = HTMLHelper::protectEntity($replaced_text);
    350351                } else {
    351352                    // JSON mode, we need to decode the JSON data
     
    357358                    $json_data = new JsonObject($json_decoded);
    358359                    foreach ($fragment_list['fragments'] as $fragment) {
     360                        $dec_key = self::unwrapKey($fragment['key']);
    359361                        try {
    360                             $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     362                            $json_data->set('$.' . $dec_key, $fragment['value']);
    361363                        } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    362                             Debug::log('Failed to set key in attributes: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     364                            Debug::log('Failed to set key in attributes: ' . $dec_key . ' -> ' . $e->getMessage());
    363365                        }
    364366                    }
     
    370372
    371373                    // Protect the entity back
    372                     $protected_json = self::protectEntity(htmlspecialchars($replaced_json, ENT_QUOTES, 'UTF-8', false));
     374                    $protected_json = HTMLHelper::protectEntity(htmlspecialchars($replaced_json, ENT_QUOTES, 'UTF-8', false));
    373375                }
    374376
     
    378380        }
    379381
    380         $html_data = self::saveHTML($html_dom);
     382        $html_data = HTMLHelper::saveHTML($html_dom);
    381383        foreach ($queued_deletions as $deletion) {
    382384            foreach ($deletion as $fragment) {
  • linguise/trunk/src/FragmentHandler.php

    r3358294 r3366846  
    33namespace Linguise\WordPress;
    44
     5use Linguise\WordPress\FragmentBase;
     6use Linguise\WordPress\Helper;
     7use Linguise\WordPress\HTMLHelper;
    58use Linguise\Vendor\JsonPath\JsonObject;
    69use Linguise\Vendor\Linguise\Script\Core\Debug;
    710
    811defined('ABSPATH') || die('');
    9 
    10 /**
    11  * Check if the array is an actual object or not.
    12  *
    13  * @param array|object $arr_or_object The array or object to be checked
    14  *
    15  * @return boolean - True if it's an actual object, false if it's an array
    16  */
    17 function is_actual_object($arr_or_object): bool
    18 {
    19     if (is_object($arr_or_object)) {
    20         return true;
    21     }
    22 
    23     if (!is_array($arr_or_object)) {
    24         // preliminary check
    25         return false;
    26     }
    27 
    28     // https://stackoverflow.com/a/72949244 (PHP 7 compatible)
    29     if (function_exists('array_is_list')) {
    30         return array_is_list($arr_or_object) === false; // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound
    31     }
    32 
    33     $keys = array_keys($arr_or_object);
    34     return implode('', $keys) !== implode(range(0, count($keys) - 1));
    35 }
    36 
    37 /**
    38  * Check if the string has space or not.
    39  *
    40  * @param string $str The string to be checked
    41  *
    42  * @return boolean - True if it has space, false if it doesn't
    43  */
    44 function has_space($str)
    45 {
    46     return preg_match('/\s/', $str) > 0;
    47 }
    4812
    4913/**
    5014 * Class FragmentHandler
    5115 */
    52 class FragmentHandler
     16class FragmentHandler extends FragmentBase
    5317{
    5418    /**
     
    6630     */
    6731    protected static $frag_html_match_self_close = '/<(img) class="linguise-fragment" data-fragment-name="([^"]*)" data-fragment-param="([^"]*)" data-fragment-key="([^"]*)" data-fragment-format="(link|html|html-main|text|media-img|media-imgset)" data-fragment-mode="(auto|override|attribute)"(?: data-fragment-extra-id="([^"]*)")?(?: (?:href|src|srcset)="([^"]*)")?\s*\/?>/si';
    68 
    69     /**
    70      * Marker used to protect the HTML entities
    71      *
    72      * @var array
    73      */
    74     protected static $marker_entity = [
    75         'common' => 'linguise-internal-entity',
    76         'named' => 'linguise-internal-entity1',
    77         'numeric' => 'linguise-internal-entity2',
    78     ];
    79 
    80     /**
    81      * Default filters for the fragments
    82      *
    83      * @var array
    84      */
    85     protected static $default_filters = [
    86         [
    87             'key' => 'nonce',
    88             'mode' => 'wildcard',
    89             'kind' => 'deny',
    90         ],
    91         [
    92             'key' => 'i18n_.+',
    93             'mode' => 'regex',
    94             'kind' => 'allow',
    95             'cast' => 'html-main',
    96         ],
    97         [
    98             'key' => 'currency\..*',
    99             'mode' => 'regex_full',
    100             'kind' => 'deny',
    101         ],
    102         [
    103             'key' => 'wc.*?_currency',
    104             'mode' => 'regex',
    105             'kind' => 'deny',
    106         ],
    107         [
    108             'key' => 'dateFormat',
    109             'mode' => 'exact',
    110             'kind' => 'deny',
    111         ],
    112         [
    113             'key' => 'baseLocation.country',
    114             'mode' => 'path',
    115             'kind' => 'deny',
    116         ],
    117         [
    118             'key' => 'baseLocation.state',
    119             'mode' => 'path',
    120             'kind' => 'deny',
    121         ],
    122         [
    123             'key' => 'admin.wccomHelper.storeCountry',
    124             'mode' => 'path',
    125             'kind' => 'deny',
    126         ],
    127         [
    128             'key' => '.*-version',
    129             'mode' => 'regex',
    130             'kind' => 'deny',
    131         ],
    132         [
    133             'key' => 'orderStatuses\..*',
    134             'mode' => 'regex_full',
    135             'kind' => 'allow',
    136         ],
    137         [
    138             'key' => 'wc.*Url',
    139             'mode' => 'regex_full',
    140             'kind' => 'deny',
    141         ],
    142         [
    143             'key' => '^defaultFields\..*\.(autocapitalize|autocomplete)',
    144             'mode' => 'regex_full',
    145             'kind' => 'deny',
    146         ],
    147         [
    148             'key' => 'defaultAddressFormat',
    149             'mode' => 'exact',
    150             'kind' => 'deny',
    151         ],
    152         [
    153             'key' => 'dateFormat',
    154             'mode' => 'exact',
    155             'kind' => 'deny',
    156         ],
    157         [
    158             'key' => '^checkoutData\..*',
    159             'mode' => 'regex_full',
    160             'kind' => 'deny',
    161         ],
    162         [
    163             'key' => 'api_key',
    164             'mode' => 'exact',
    165             'kind' => 'deny',
    166         ],
    167         [
    168             'key' => '^countryData\..*\.format',
    169             'mode' => 'regex_full',
    170             'kind' => 'deny',
    171         ],
    172         [
    173             'key' => '.*?(hash_key|fragment_name|storage_key)',
    174             'mode' => 'regex',
    175             'kind' => 'deny',
    176         ],
    177         [
    178             'key' => 'wc_ajax_url',
    179             'mode' => 'exact',
    180             'kind' => 'deny',
    181         ],
    182         /**
    183          * Plugin : woocommerce-gateway-stripe
    184          */
    185         [
    186             'key' => 'paymentMethodsConfig.*?(card|us_bank_account|alipay|klarna|afterpay_clearpay|link|wechat_pay|cashapp)\.countries',
    187             'mode' => 'regex_full',
    188             'kind' => 'deny',
    189         ],
    190         [
    191             'key' => 'accountCountry',
    192             'mode' => 'exact',
    193             'kind' => 'deny',
    194         ],
    195         [
    196             'key' => 'appearance\..*',
    197             'mode' => 'regex_full',
    198             'kind' => 'deny',
    199         ],
    200         [
    201             'key' => 'blocksAppearance\..*',
    202             'mode' => 'regex_full',
    203             'kind' => 'deny',
    204         ],
    205         [
    206             'key' => 'paymentMethodData.*?stripe\.plugin_url',
    207             'mode' => 'regex_full',
    208             'kind' => 'deny',
    209         ],
    210         [
    211             'key' => 'currency',
    212             'mode' => 'exact',
    213             'kind' => 'deny',
    214         ],
    215     ];
    216 
    217     /**
    218      * Check with the Configuration for the allow list and deny list.
    219      *
    220      * @param string $key      The key to be checked
    221      * @param string $full_key The full JSON path key to be checked
    222      *
    223      * @return boolean|null - True if it's allowed, false if it's not
    224      */
    225     public static function isKeyAllowed($key, $full_key)
    226     {
    227         // the allow/deny list are formatted array like:
    228         // [
    229         //    [
    230         //        'key' => 'woocommerce',
    231         //        'mode' => 'regex' | 'exact | 'path' | 'wildcard',
    232         //        'kind' => 'allow' | 'deny',
    233         //    ]
    234         // ]
    235 
    236         $merged_defaults = self::$default_filters;
    237         if (self::isCurrentTheme('Woodmart')) {
    238             $regex_key_disallowed = [
    239                 'add_to_cart_action.*',
    240                 'age_verify.*',
    241                 'ajax_(?!url)(\w+)',
    242                 'carousel_breakpoints\..*',
    243                 'comment_images_upload_mimes\..*',
    244                 'tooltip_\w+_selector',
    245             ];
    246 
    247             foreach ($regex_key_disallowed as $regex_key) {
    248                 $merged_defaults[] = [
    249                     'key' => $regex_key,
    250                     'mode' => 'regex_full',
    251                     'kind' => 'deny',
    252                 ];
    253             }
    254 
    255             $exact_key_disallowed = [
    256                 'added_popup',
    257                 'base_hover_mobile_click',
    258                 'cart_redirect_after_add',
    259                 'categories_toggle',
    260                 'collapse_footer_widgets',
    261                 'compare_by_category',
    262                 'compare_save_button_state',
    263                 'countdown_timezone',
    264                 'whb_header_clone',
    265                 'vimeo_library_url',
    266                 'theme_dir',
    267                 'wishlist_page_nonce',
    268                 'photoswipe_template',
    269             ];
    270 
    271             foreach ($exact_key_disallowed as $exact_key) {
    272                 $merged_defaults[] = [
    273                     'key' => $exact_key,
    274                     'mode' => 'path',
    275                     'kind' => 'deny',
    276                 ];
    277             }
    278         }
    279 
    280         // Run through filters, provide our current default filters
    281         // User can change it by adding a filter and modify the array.
    282         if (function_exists('apply_filters')) {
    283             $wp_frag_list = apply_filters('linguise_fragment_filters', $merged_defaults);
    284         } else {
    285             $wp_frag_list = $merged_defaults;
    286         }
    287 
    288         foreach ($wp_frag_list as $frag_item) {
    289             $allow = $frag_item['kind'] === 'allow';
    290             $cast_data = isset($frag_item['cast']) ? $frag_item['cast'] : null;
    291             if ($frag_item['mode'] === 'path') {
    292                 // check if full key is the same
    293                 if ($frag_item['key'] === $full_key) {
    294                     // Return cast or bool
    295                     return $cast_data ? $cast_data : $allow;
    296                 }
    297             } elseif ($frag_item['mode'] === 'exact') {
    298                 // check if key is the same
    299                 if ($frag_item['key'] === $key) {
    300                     return $cast_data ? $cast_data : $allow;
    301                 }
    302             } elseif ($frag_item['mode'] === 'regex' || $frag_item['mode'] === 'regex_full') {
    303                 // check if regex matches
    304                 $key_match = $frag_item['mode'] === 'regex_full' ? $full_key : $key;
    305                 $match_re = '/' . $frag_item['key'] . '/';
    306                 if (preg_match($match_re, $key_match)) {
    307                     return $cast_data ? $cast_data : $allow;
    308                 }
    309             } elseif ($frag_item['mode'] === 'wildcard') {
    310                 // check if wildcard matches
    311                 $match_re = '/^.*?' . $frag_item['key'] . '.*?$/';
    312                 if (preg_match($match_re, $key)) {
    313                     return $cast_data ? $cast_data : $allow;
    314                 }
    315             }
    316         }
    317 
    318         return null;
    319     }
    320 
    321     /**
    322      * Check if the string is a translatable string or not.
    323      *
    324      * @param string $value The string to be checked
    325      *
    326      * @return boolean - True if it's a translatable string, false if it's not
    327      */
    328     private static function isTranslatableString($value)
    329     {
    330         $value = trim($value);
    331 
    332         if (empty($value) || !is_string($value)) {
    333             return false;
    334         }
    335 
    336         // Check if it's a JSON, if yes, do not translate
    337         $json_parse = json_decode($value);
    338         if (!is_null($json_parse)) {
    339             return false;
    340         }
    341 
    342         // Has space? Most likely a translateable string
    343         if (has_space($value)) {
    344             return true;
    345         }
    346 
    347         // Check if email
    348         if (!empty(filter_var($value, FILTER_VALIDATE_EMAIL))) {
    349             return false;
    350         }
    351 
    352         // Check if string is UUID
    353         if (preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/', $value)) {
    354             return false;
    355         }
    356 
    357         // Check if first word is lowercase (bad idea?)
    358         // Or, check if has a number/symbols
    359         if (ctype_lower($value[0]) || preg_match('/[0-9\W]/', $value)) {
    360             return false;
    361         }
    362 
    363         return true;
    364     }
    365 
    366     /**
    367      * Check if the string is a link or not.
    368      *
    369      * @param string $value The string to be checked
    370      *
    371      * @return boolean - True if it's a link, false if it's not
    372      */
    373     private static function isStringLink($value)
    374     {
    375         // Has http:// or https://
    376         // Has %%endpoint%%
    377         // Starts with / and has no space
    378         if (preg_match('/https?:\/\//', $value)) {
    379             // Validate the link
    380             if (filter_var($value, FILTER_VALIDATE_URL)) {
    381                 return true;
    382             }
    383 
    384             return false;
    385         }
    386 
    387         if (substr($value, 0, 1) === '/' && !has_space($value)) {
    388             $as_url = parse_url($value);
    389             if (empty($as_url)) {
    390                 return false;
    391             }
    392 
    393             // Check if it only have "path" and not other keys
    394             $array_keys = array_keys($as_url);
    395             if (count($array_keys) === 1 && $array_keys[0] === 'path') {
    396                 return true;
    397             }
    398 
    399             if (preg_match('/%%.*%%/', $value)) {
    400                 // Assume WC-AJAX
    401                 return true;
    402             }
    403         }
    404 
    405         return false;
    406     }
    407 
    408     /**
    409      * Check if the string is a image link or not.
    410      *
    411      * @param string $value The string to be checked
    412      *
    413      * @return boolean - True if it's a image link, false if it's not
    414      */
    415     private static function isImageLink($value)
    416     {
    417         // There is so much more image extension
    418         $extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp', 'tiff', 'tif', 'ico', 'avif', 'heic', 'heif'];
    419         $regex_matcher = '/\.(?:' . implode('|', $extensions) . ')$/i';
    420         if (preg_match($regex_matcher, $value)) {
    421             // We don't need to validate the link since this is called inside isStringLink
    422             return true;
    423         }
    424         return false;
    425     }
    426 
    427     /**
    428      * Check if the string is a HTML element or not.
    429      *
    430      * @param string $value The string to be checked
    431      *
    432      * @return string|false - True if it's a HTML element, false if it's not
    433      */
    434     private static function isHTMLElement($value)
    435     {
    436         if (empty($value)) {
    437             return false;
    438         }
    439 
    440         // use simplexml, suppress the warning
    441         if (extension_loaded('xml') && function_exists('simplexml_load_string')) {
    442             $doc = @simplexml_load_string($value); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
    443             if ($doc !== false) {
    444                 return 'html';
    445             }
    446         }
    447 
    448         // Use strip_tags method
    449         if (strip_tags($value) !== $value) {
    450             return 'html-main';
    451         }
    452 
    453         return false;
    454     }
    455 
    456     /**
    457      * Check and wrap key with ["$key"] if it use symbols
    458      *
    459      * @param string $key The key to be checked
    460      *
    461      * @return string
    462      */
    463     private static function wrapKey($key)
    464     {
    465         // only include symbols
    466         // alphanumeric is not included
    467         if (preg_match('/[^\w]/', $key)) {
    468             return "['" . $key . "']";
    469         }
    470 
    471         return $key;
    472     }
    47332
    47433    /**
     
    49857        }
    49958
    500         if (is_actual_object($value)) {
     59        if (Helper::isActualObject($value)) {
    50160            $collected_fragments = self::collectFragmentFromJson($value, $strict, $collected_fragments, $use_key);
    50261        } elseif (is_array($value)) {
     
    566125        }
    567126        return $collected_fragments;
    568     }
    569 
    570     /**
    571      * Checks if the given theme name is the current theme or the parent of the current theme.
    572      *
    573      * @param string         $theme_name   The name of the theme to check.
    574      * @param \WP_Theme|null $parent_theme Optional. The parent theme to check. Default is null.
    575      *
    576      * @return boolean True if the given theme name is the current theme or its parent, false otherwise.
    577      */
    578     private static function isCurrentTheme($theme_name, $parent_theme = \null)
    579     {
    580         if (!function_exists('wp_get_theme')) {
    581             return false;
    582         }
    583 
    584         $theme = $parent_theme ?: wp_get_theme();
    585         if (empty($theme)) {
    586             return false;
    587         }
    588 
    589         $is_theme = $theme->name === $theme_name;
    590         if ($is_theme) {
    591             return true;
    592         }
    593 
    594         $parent = $theme->parent();
    595         if ($parent !== false) {
    596             return self::isCurrentTheme($theme_name, $parent);
    597         }
    598         return false;
    599     }
    600 
    601     /**
    602      * Protect the HTML entities in the source code.
    603      *
    604      * Adapted from: https://github.com/ivopetkov/html5-dom-document-php/blob/master/src/HTML5DOMDocument.php
    605      *
    606      * @param string $source The source code to be protected
    607      *
    608      * @return string The protected source code
    609      */
    610     protected static function protectEntity($source)
    611     {
    612         // Replace the entity with our own
    613         $source = preg_replace('/&([a-zA-Z]*);/', self::$marker_entity['named'] . '-$1-end', $source);
    614         $source = preg_replace('/&#([0-9]*);/', self::$marker_entity['numeric'] . '-$1-end', $source);
    615 
    616         return $source;
    617     }
    618 
    619     /**
    620      * Unprotect the HTML entities in the source code.
    621      *
    622      * @param string $html The HTML code to be unprotected
    623      *
    624      * @return string The unprotected HTML code
    625      */
    626     protected static function unprotectEntity($html)
    627     {
    628         if (strpos($html, self::$marker_entity['common']) !== false) {
    629             $html = preg_replace('/' . self::$marker_entity['named'] . '-(.*?)-end/', '&$1;', $html);
    630             $html = preg_replace('/' . self::$marker_entity['numeric'] . '-(.*?)-end/', '&#$1;', $html);
    631         }
    632 
    633         return $html;
    634     }
    635 
    636     /**
    637      * Protect the HTML string before processing with DOMDocument.
    638      *
    639      * It does:
    640      * - Add CDATA around script tags content
    641      * - Preserve html entities
    642      *
    643      * Adapted from: https://github.com/ivopetkov/html5-dom-document-php/blob/master/src/HTML5DOMDocument.php
    644      *
    645      * @param string $source The HTML source code to be protected
    646      *
    647      * @return string The protected HTML source code
    648      */
    649     private static function protectHTML($source)
    650     {
    651         // Add CDATA around script tags content
    652         $matches = null;
    653         preg_match_all('/<script(.*?)>/', $source, $matches);
    654         if (isset($matches[0])) {
    655             $matches[0] = array_unique($matches[0]);
    656             foreach ($matches[0] as $match) {
    657                 if (substr($match, -2, 1) !== '/') { // check if ends with />
    658                     $source = str_replace($match, $match . '<![CDATA[-linguise-dom-internal-cdata', $source); // Add CDATA after the open tag
    659                 }
    660             }
    661         }
    662 
    663         $source = str_replace('</script>', '-linguise-dom-internal-cdata]]></script>', $source); // Add CDATA before the end tag
    664         $source = str_replace('<![CDATA[-linguise-dom-internal-cdata-linguise-dom-internal-cdata]]>', '', $source); // Clean empty script tags
    665         $matches = null;
    666         preg_match_all('/\<!\[CDATA\[-linguise-dom-internal-cdata.*?-linguise-dom-internal-cdata\]\]>/s', $source, $matches);
    667         if (isset($matches[0])) {
    668             $matches[0] = array_unique($matches[0]);
    669             foreach ($matches[0] as $match) {
    670                 if (strpos($match, '</') !== false) { // check if contains </
    671                     $source = str_replace($match, str_replace('</', '<-linguise-dom-internal-cdata-endtagfix/', $match), $source);
    672                 }
    673             }
    674         }
    675 
    676         // Preserve html entities
    677         $source = self::protectEntity($source);
    678 
    679         return $source;
    680     }
    681 
    682     /**
    683      * Load the HTML data into a DOMDocument object.
    684      *
    685      * @param string $html_data The HTML data to be loaded
    686      *
    687      * @return \DOMDocument|null The loaded HTML DOM object
    688      */
    689     protected static function loadHTML($html_data)
    690     {
    691         // Check if DOMDocument is available or xml extension is loaded
    692         if (!class_exists('DOMDocument') && !extension_loaded('xml')) {
    693             return null;
    694         }
    695 
    696         // Load HTML
    697         $html_dom = new \DOMDocument();
    698         @$html_dom->loadHTML(self::protectHTML($html_data), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
    699 
    700         /**
    701         * Avoid mangling the CSS and JS code with encoded HTML entities
    702         *
    703         * See: https://www.php.net/manual/en/domdocument.savehtml.php#119813
    704         *
    705         * While testing, we found this issue with css inner text got weirdly mangled
    706         * following the issue above, I manage to correct this by adding proper content-type equiv
    707         * which is really weird honestly but it manages to fix the issue.
    708         */
    709         $has_utf8 = false;
    710         $meta_attrs = $html_dom->getElementsByTagName('meta');
    711         foreach ($meta_attrs as $meta) {
    712             if ($meta->hasAttribute('http-equiv') && strtolower($meta->getAttribute('http-equiv')) === 'content-type') {
    713                 // force UTF-8s
    714                 $meta->setAttribute('content', 'text/html; charset=UTF-8');
    715                 $has_utf8 = true;
    716                 break;
    717             }
    718         }
    719 
    720         if (!$has_utf8) {
    721             // We didn't found any meta tag with content-type equiv, add our own
    722             $meta = $html_dom->createElement('meta');
    723             $meta->setAttribute('http-equiv', 'Content-Type');
    724             $meta->setAttribute('content', 'text/html; charset=UTF-8');
    725             $head_doc = $html_dom->getElementsByTagName('head');
    726             if ($head_doc->length > 0) {
    727                 // Add to head tag on the child as the first node
    728                 $head = $head_doc->item(0);
    729                 @$head->insertBefore($meta, $head->firstChild); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- ignore any errors for now
    730             }
    731         }
    732 
    733         return $html_dom;
    734     }
    735 
    736     /**
    737      * Save the HTML data into a string.
    738      *
    739      * @param \DOMDocument $dom The DOMDocument object to be saved
    740      *
    741      * @return string The saved HTML data
    742      */
    743     protected static function saveHTML($dom)
    744     {
    745         // Save HTML
    746         $html_data = $dom->saveHTML();
    747         if ($html_data === false) {
    748             return '';
    749         }
    750 
    751         // Unprotect HTML entities
    752         $html_data = self::unprotectEntity($html_data);
    753 
    754         // Unprotect HTML
    755         $code_to_be_removed = [
    756             'linguise-dom-internal-content',
    757             '<![CDATA[-linguise-dom-internal-cdata',
    758             '-linguise-dom-internal-cdata]]>',
    759             '-linguise-dom-internal-cdata-endtagfix'
    760         ];
    761         foreach ($code_to_be_removed as $code) {
    762             $html_data = str_replace($code, '', $html_data);
    763         }
    764 
    765         // Unmangle stuff like &amp;#xE5;
    766         $html_data = preg_replace('/&amp;#x([0-9A-Fa-f]+);/', '&#x$1;', $html_data);
    767 
    768         return $html_data;
    769     }
    770 
    771     /**
    772      * Unclobber the CDATA internal
    773      *
    774      * NOTE: Only use this when processing a script content internal data not the whole HTML data.
    775      *
    776      * This is used to protect the CDATA internal data from being mangled by the DOMDocument.
    777      *
    778      * @param string $html_data The HTML data to be unclobbered
    779      *
    780      * @return string The unclobbered HTML data
    781      */
    782     protected static function unclobberCdataInternal($html_data)
    783     {
    784         // Unclobber the CDATA internal
    785         $html_data = str_replace('<![CDATA[-linguise-dom-internal-cdata', '', $html_data);
    786         $html_data = str_replace('-linguise-dom-internal-cdata]]>', '', $html_data);
    787         $html_data = str_replace('<-linguise-dom-internal-cdata-endtagfix/', '</', $html_data);
    788 
    789         return $html_data;
    790     }
    791 
    792     /**
    793      * Clobber back the CDATA internal
    794      *
    795      * NOTE: Only use this when processing a script content internal data not the whole HTML data.
    796      *
    797      * This is used to protect the CDATA internal data from being mangled by the DOMDocument.
    798      *
    799      * @param string $html_data The HTML data to be clobbered
    800      *
    801      * @return string The clobbered HTML data
    802      */
    803     protected static function clobberCdataInternal($html_data)
    804     {
    805         // Append prefix and suffix
    806         return '<![CDATA[-linguise-dom-internal-cdata' . $html_data . '-linguise-dom-internal-cdata]]>';
    807     }
    808 
    809     /**
    810      * Get override JSON fragment matching
    811      *
    812      * The way the override works is by matching the script content with the regex, the schema of each item is:
    813      * - name: The name of the plugin, e.g. 'mailoptin', must be unique
    814      * - match: The regex to match the script content
    815      * - replacement: The replacement string, use $$JSON_DATA$$ as the placeholder for the JSON data
    816      * - position: The position of the JSON data, default to 1 (optional)
    817      * - encode: If the JSON data is URL encoded or not, default to false (optional)
    818      * - id: The id of the script, if it's not the same, then it will be skipped (optional)
    819      * - mode: The mode of the script, default to 'script' (available are: `script` and `app_json`)
    820      *
    821      * @param string $html_data The HTML data input
    822      *
    823      * @return array The array of JSON to match with fragment
    824      */
    825     private static function getJSONOverrideMatcher($html_data)
    826     {
    827         $current_list = [];
    828 
    829         if (is_plugin_active('mailoptin/mailoptin.php')) {
    830             $current_list[] = [
    831                 'name' => 'mailoptin',
    832                 'match' => '<script type="text\/javascript">var (.*)_lightbox = (.*);<\/script>',
    833                 'replacement' => '<script text="text/javascript">var $1_lightbox = $$JSON_DATA$$;</script>',
    834                 'position' => 2,
    835             ];
    836         }
    837 
    838         if (is_plugin_active('ninja-forms/ninja-forms.php')) {
    839             $current_list[] = [
    840                 'name' => 'ninjaforms_fields',
    841                 'match' => 'form.fields=(.*?);nfForms',
    842                 'replacement' => 'form.fields=$1;nfForms',
    843             ];
    844             $current_list[] = [
    845                 'name' => 'ninjaforms_i18n',
    846                 'match' => 'nfi18n = (.*?);',
    847                 'replacement' => 'nfi18n = $$JSON_DATA$$;',
    848             ];
    849             $current_list[] = [
    850                 'name' => 'ninjaforms_settings',
    851                 'match' => 'form.settings=(.*?);form',
    852                 'replacement' => 'form.settings=$$JSON_DATA$$;form',
    853             ];
    854         }
    855 
    856         if (is_plugin_active('wpforms-lite/wpforms.php')) {
    857             $current_list[] = [
    858                 'name' => 'wpforms-lite',
    859                 'match' => 'wpforms_settings = (.*?)(\n)(\/\* ]]> \*\/)',
    860                 'replacement' => 'wpforms_settings = $$JSON_DATA$$$2$3',
    861             ];
    862         }
    863 
    864         if (is_plugin_active('popup-maker/popup-maker.php')) {
    865             $current_list[] = [
    866                 'name' => 'popup-maker',
    867                 'match' => 'var pumAdminBarText = (.*?);',
    868                 'replacement' => 'var pumAdminBarText = $$JSON_DATA$$;',
    869             ];
    870         }
    871 
    872         if (is_plugin_active('mailpoet/mailpoet.php')) {
    873             $current_list[] = [
    874                 'name' => 'mailpoet',
    875                 'match' => 'var MailPoetForm = (.*?);',
    876                 'replacement' => 'var MailPoetForm = $$JSON_DATA$$;',
    877             ];
    878         }
    879 
    880         if (self::isCurrentTheme('Woodmart')) {
    881             $current_list[] = [
    882                 'name' => 'woodmart-theme',
    883                 'match' => 'var woodmart_settings = (.*?);',
    884                 'replacement' => 'var woodmart_settings = $$JSON_DATA$$;',
    885             ];
    886         }
    887 
    888         $current_list[] = [
    889             'name' => 'wc-settings-encoded',
    890             'match' => 'var wcSettings = wcSettings \|\| JSON\.parse\( decodeURIComponent\( \'(.*?)\' \) \);',
    891             'replacement' => 'var wcSettings = wcSettings || JSON.parse( decodeURIComponent( \'$$JSON_DATA$$\' ) );',
    892             'encode' => true,
    893         ];
    894 
    895         if (defined('CFCORE_VER')) {
    896             $current_list[] = [
    897                 'name' => 'calderaforms',
    898                 'match' => 'CF_VALIDATOR_STRINGS = (.*?);',
    899                 'replacement' => 'CF_VALIDATOR_STRINGS = $$JSON_DATA$$;',
    900             ];
    901         }
    902 
    903         $current_list[] = [
    904             'name' => 'surecart-store-data',
    905             'key' => 'sc-store-data',
    906             'mode' => 'app_json',
    907         ];
    908 
    909         // Merge with apply_filters
    910         if (function_exists('apply_filters')) {
    911             $current_list = apply_filters('linguise_fragment_override', $current_list, $html_data);
    912         }
    913 
    914         return $current_list;
    915127    }
    916128
     
    1061273
    1062274        foreach ($override_list as $override_item) {
    1063             $script_content = self::unclobberCdataInternal($script_content);
     275            $script_content = HTMLHelper::unclobberCdataInternal($script_content);
    1064276            if (isset($override_item['mode']) && $override_item['mode'] === 'app_json') {
    1065277                // If mode is app_json and key is the same
     
    1130342    public static function findWPFragments(&$html_data)
    1131343    {
    1132         $html_dom = self::loadHTML($html_data);
     344        $html_dom = HTMLHelper::loadHTML($html_data);
    1133345        if (empty($html_dom)) {
    1134346            return [];
     
    1154366            $frag_id = $attr_match[1];
    1155367
    1156             $script_content = self::unclobberCdataInternal($script->textContent);
     368            $script_content = HTMLHelper::unclobberCdataInternal($script->textContent);
    1157369
    1158370            $match_res = preg_match('/var ' . str_replace('-', '_', $frag_id) . '_params = (.*);/', $script_content, $json_matches);
     
    1202414
    1203415    /**
    1204      * Unpack/decode the key name from the JSON data.
    1205      *
    1206      * This is needed because the key name would be encoded sometimes.
    1207      *
    1208      * @param string $key The key to be decoded
    1209      *
    1210      * @return string
    1211      */
    1212     protected static function decodeKeyName($key)
    1213     {
    1214         $key = html_entity_decode($key, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    1215         // Would sometimes fails??
    1216         $key = str_replace('&apos;', "'", $key);
    1217         $key = str_replace('&quot;', '"', $key);
    1218         return $key;
    1219     }
    1220 
    1221     /**
    1222416     * Apply the translated fragments for the override.
    1223417     *
     
    1260454            $json_data = new JsonObject(json_decode('{' . $match_data . '}', true));
    1261455            foreach ($fragment_info['fragments'] as $fragment) {
     456                $decoded_key = self::unwrapKey($fragment['key']);
    1262457                try {
    1263                     $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     458                    $json_data->set('$.' . $decoded_key, $fragment['value']);
    1264459                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1265                     Debug::log('Failed to set key in override: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     460                    Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
    1266461                }
    1267462            }
     
    1289484            $json_data = new JsonObject(json_decode($before_match, true));
    1290485            foreach ($fragment_info['fragments'] as $fragment) {
     486                $decoded_key = self::unwrapKey($fragment['key']);
    1291487                try {
    1292                     $json_data->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     488                    $json_data->set('$.' . $decoded_key, $fragment['value']);
    1293489                } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1294                     Debug::log('Failed to set key in override: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     490                    Debug::log('Failed to set key in override: ' . $decoded_key . ' -> ' . $e->getMessage());
    1295491                }
    1296492            }
     
    1335531        foreach ($fragments as $fragment) {
    1336532            // remove the html fragment from the translated page
     533            $decoded_key = self::unwrapKey($fragment['key']);
    1337534            try {
    1338                 $json_path->set('$.' . self::decodeKeyName($fragment['key']), $fragment['value']);
     535                $json_path->set('$.' . $decoded_key, $fragment['value']);
    1339536            } catch (\Linguise\Vendor\JsonPath\InvalidJsonPathException $e) {
    1340                 Debug::log('Failed to set key in auto: ' . self::decodeKeyName($fragment['key']) . ' -> ' . $e->getMessage());
     537                Debug::log('Failed to set key in auto: ' . $decoded_key . ' -> ' . $e->getMessage());
    1341538            }
    1342539        }
  • linguise/trunk/src/Helper.php

    r3344947 r3366846  
    44
    55defined('ABSPATH') || die('');
    6 
    76
    87/**
     
    342341        return 'rgba(' . $color_p['r'] . ', ' . $color_p['g'] . ', ' . $color_p['b'] . ', ' . $alpha . ')';
    343342    }
     343
     344    /**
     345     * Check if the array is an actual object or not.
     346     *
     347     * @param array|object $arrOrObject The array or object to be checked
     348     *
     349     * @return boolean - True if it's an actual object, false if it's an array
     350     */
     351    public static function isActualObject($arrOrObject)
     352    {
     353        if (is_object($arrOrObject)) {
     354            return true;
     355        }
     356
     357        if (!is_array($arrOrObject)) {
     358            // preliminary check
     359            return false;
     360        }
     361
     362        // https://stackoverflow.com/a/72949244 (PHP 7 compatible)
     363        if (function_exists('array_is_list')) {
     364            return array_is_list($arrOrObject) === false; // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound
     365        }
     366
     367        $keys = array_keys($arrOrObject);
     368        return implode('', $keys) !== implode(range(0, count($keys) - 1));
     369    }
     370
     371    /**
     372     * Check if the string has space or not.
     373     *
     374     * @param string $str The string to be checked
     375     *
     376     * @return boolean - True if it has space, false if it doesn't
     377     */
     378    public static function hasSpace($str)
     379    {
     380        return preg_match('/\s/', $str) > 0;
     381    }
    344382}
  • linguise/trunk/src/constants.php

    r3362901 r3366846  
    11<?php
    22if (!defined('LINGUISE_SCRIPT_TRANSLATION_VERSION')) {
    3     define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.1.71');
     3    define('LINGUISE_SCRIPT_TRANSLATION_VERSION', 'wordpress_plugin/2.1.72');
    44}
    55
    66if (!defined('LINGUISE_VERSION')) {
    7     define('LINGUISE_VERSION', '2.1.71');
     7    define('LINGUISE_VERSION', '2.1.72');
    88}
  • linguise/trunk/vendor/composer/installed.json

    r3357604 r3366846  
    5757        {
    5858            "name": "linguise/script-php",
    59             "version": "v1.3.34",
    60             "version_normalized": "1.3.34.0",
     59            "version": "v1.3.35",
     60            "version_normalized": "1.3.35.0",
    6161            "source": {
    6262                "type": "git",
    6363                "url": "git@bitbucket.org:linguise/script-php.git",
    64                 "reference": "6b3fc442043092f8b4ab344cb4013972d515f2e8"
     64                "reference": "c3ec7ac41f08b8678c985e5ff2e8a2658ac4594d"
    6565            },
    6666            "require": {
     
    7171            },
    7272            "require-dev": {
    73                 "phpunit/phpunit": "^9"
    74             },
    75             "time": "2025-09-08T05:45:17+00:00",
     73                "phpunit/php-code-coverage": "9.2.32",
     74                "phpunit/phpunit": "^9",
     75                "vlucas/phpdotenv": "^5.6"
     76            },
     77            "time": "2025-09-18T08:53:06+00:00",
    7678            "type": "library",
    7779            "installation-source": "source",
  • linguise/trunk/vendor/composer/installed.php

    r3362901 r3366846  
    44        'pretty_version' => 'dev-master',
    55        'version' => 'dev-master',
    6         'reference' => 'c501b5b2201bfed3d5375935d80af464ce9ed5cc',
     6        'reference' => '3d43db286724933049dae05905587dd8108a9002',
    77        'type' => 'library',
    88        'install_path' => __DIR__ . '/../../',
     
    2121        ),
    2222        'linguise/script-php' => array(
    23             'pretty_version' => 'v1.3.34',
    24             'version' => '1.3.34.0',
    25             'reference' => '6b3fc442043092f8b4ab344cb4013972d515f2e8',
     23            'pretty_version' => 'v1.3.35',
     24            'version' => '1.3.35.0',
     25            'reference' => 'c3ec7ac41f08b8678c985e5ff2e8a2658ac4594d',
    2626            'type' => 'library',
    2727            'install_path' => __DIR__ . '/../linguise/script-php',
     
    3232            'pretty_version' => 'dev-master',
    3333            'version' => 'dev-master',
    34             'reference' => 'c501b5b2201bfed3d5375935d80af464ce9ed5cc',
     34            'reference' => '3d43db286724933049dae05905587dd8108a9002',
    3535            'type' => 'library',
    3636            'install_path' => __DIR__ . '/../../',
  • linguise/trunk/vendor/linguise/script-php/.version

    r3357604 r3366846  
    1 1.3.34
     11.3.35
  • linguise/trunk/vendor/linguise/script-php/composer.json

    r2718675 r3366846  
    2828  },
    2929  "require-dev": {
    30     "phpunit/phpunit": "^9"
     30    "phpunit/php-code-coverage": "9.2.32",
     31    "phpunit/phpunit": "^9",
     32    "vlucas/phpdotenv": "^5.6"
    3133  }
    3234}
  • linguise/trunk/vendor/linguise/script-php/composer.lock

    r2679984 r3366846  
    55        "This file is @generated automatically"
    66    ],
    7     "content-hash": "662cefddda37d75487a93c211e51de4e",
     7    "content-hash": "93d2aed00792824a33c47a2d587cfa8a",
    88    "packages": [],
    99    "packages-dev": [
    1010        {
    1111            "name": "doctrine/instantiator",
    12             "version": "1.4.0",
     12            "version": "1.5.0",
    1313            "source": {
    1414                "type": "git",
    1515                "url": "https://github.com/doctrine/instantiator.git",
    16                 "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
    17             },
    18             "dist": {
    19                 "type": "zip",
    20                 "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
    21                 "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
     16                "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
     17            },
     18            "dist": {
     19                "type": "zip",
     20                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
     21                "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
    2222                "shasum": ""
    2323            },
     
    2626            },
    2727            "require-dev": {
    28                 "doctrine/coding-standard": "^8.0",
     28                "doctrine/coding-standard": "^9 || ^11",
    2929                "ext-pdo": "*",
    3030                "ext-phar": "*",
    31                 "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
    32                 "phpstan/phpstan": "^0.12",
    33                 "phpstan/phpstan-phpunit": "^0.12",
    34                 "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
     31                "phpbench/phpbench": "^0.16 || ^1",
     32                "phpstan/phpstan": "^1.4",
     33                "phpstan/phpstan-phpunit": "^1",
     34                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
     35                "vimeo/psalm": "^4.30 || ^5.4"
    3536            },
    3637            "type": "library",
     
    5960            "support": {
    6061                "issues": "https://github.com/doctrine/instantiator/issues",
    61                 "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
     62                "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
    6263            },
    6364            "funding": [
     
    7576                }
    7677            ],
    77             "time": "2020-11-10T18:47:58+00:00"
     78            "time": "2022-12-30T00:15:36+00:00"
     79        },
     80        {
     81            "name": "graham-campbell/result-type",
     82            "version": "v1.1.3",
     83            "source": {
     84                "type": "git",
     85                "url": "https://github.com/GrahamCampbell/Result-Type.git",
     86                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
     87            },
     88            "dist": {
     89                "type": "zip",
     90                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
     91                "reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
     92                "shasum": ""
     93            },
     94            "require": {
     95                "php": "^7.2.5 || ^8.0",
     96                "phpoption/phpoption": "^1.9.3"
     97            },
     98            "require-dev": {
     99                "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
     100            },
     101            "type": "library",
     102            "autoload": {
     103                "psr-4": {
     104                    "GrahamCampbell\\ResultType\\": "src/"
     105                }
     106            },
     107            "notification-url": "https://packagist.org/downloads/",
     108            "license": [
     109                "MIT"
     110            ],
     111            "authors": [
     112                {
     113                    "name": "Graham Campbell",
     114                    "email": "hello@gjcampbell.co.uk",
     115                    "homepage": "https://github.com/GrahamCampbell"
     116                }
     117            ],
     118            "description": "An Implementation Of The Result Type",
     119            "keywords": [
     120                "Graham Campbell",
     121                "GrahamCampbell",
     122                "Result Type",
     123                "Result-Type",
     124                "result"
     125            ],
     126            "support": {
     127                "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
     128                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
     129            },
     130            "funding": [
     131                {
     132                    "url": "https://github.com/GrahamCampbell",
     133                    "type": "github"
     134                },
     135                {
     136                    "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
     137                    "type": "tidelift"
     138                }
     139            ],
     140            "time": "2024-07-20T21:45:45+00:00"
    78141        },
    79142        {
    80143            "name": "myclabs/deep-copy",
    81             "version": "1.10.2",
     144            "version": "1.13.4",
    82145            "source": {
    83146                "type": "git",
    84147                "url": "https://github.com/myclabs/DeepCopy.git",
    85                 "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
    86             },
    87             "dist": {
    88                 "type": "zip",
    89                 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
    90                 "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
     148                "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
     149            },
     150            "dist": {
     151                "type": "zip",
     152                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
     153                "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
    91154                "shasum": ""
    92155            },
     
    94157                "php": "^7.1 || ^8.0"
    95158            },
    96             "replace": {
    97                 "myclabs/deep-copy": "self.version"
    98             },
    99             "require-dev": {
    100                 "doctrine/collections": "^1.0",
    101                 "doctrine/common": "^2.6",
    102                 "phpunit/phpunit": "^7.1"
     159            "conflict": {
     160                "doctrine/collections": "<1.6.8",
     161                "doctrine/common": "<2.13.3 || >=3 <3.2.2"
     162            },
     163            "require-dev": {
     164                "doctrine/collections": "^1.6.8",
     165                "doctrine/common": "^2.13.3 || ^3.2.2",
     166                "phpspec/prophecy": "^1.10",
     167                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
    103168            },
    104169            "type": "library",
     
    125190            "support": {
    126191                "issues": "https://github.com/myclabs/DeepCopy/issues",
    127                 "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
     192                "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
    128193            },
    129194            "funding": [
     
    133198                }
    134199            ],
    135             "time": "2020-11-13T09:40:50+00:00"
     200            "time": "2025-08-01T08:46:24+00:00"
    136201        },
    137202        {
    138203            "name": "nikic/php-parser",
    139             "version": "v4.13.2",
     204            "version": "v5.6.1",
    140205            "source": {
    141206                "type": "git",
    142207                "url": "https://github.com/nikic/PHP-Parser.git",
    143                 "reference": "210577fe3cf7badcc5814d99455df46564f3c077"
    144             },
    145             "dist": {
    146                 "type": "zip",
    147                 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077",
    148                 "reference": "210577fe3cf7badcc5814d99455df46564f3c077",
    149                 "shasum": ""
    150             },
    151             "require": {
     208                "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2"
     209            },
     210            "dist": {
     211                "type": "zip",
     212                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
     213                "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
     214                "shasum": ""
     215            },
     216            "require": {
     217                "ext-ctype": "*",
     218                "ext-json": "*",
    152219                "ext-tokenizer": "*",
    153                 "php": ">=7.0"
     220                "php": ">=7.4"
    154221            },
    155222            "require-dev": {
    156223                "ircmaxell/php-yacc": "^0.0.7",
    157                 "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
     224                "phpunit/phpunit": "^9.0"
    158225            },
    159226            "bin": [
     
    163230            "extra": {
    164231                "branch-alias": {
    165                     "dev-master": "4.9-dev"
     232                    "dev-master": "5.x-dev"
    166233                }
    167234            },
     
    187254            "support": {
    188255                "issues": "https://github.com/nikic/PHP-Parser/issues",
    189                 "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2"
    190             },
    191             "time": "2021-11-30T19:35:32+00:00"
     256                "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1"
     257            },
     258            "time": "2025-08-13T20:13:15+00:00"
    192259        },
    193260        {
    194261            "name": "phar-io/manifest",
    195             "version": "2.0.3",
     262            "version": "2.0.4",
    196263            "source": {
    197264                "type": "git",
    198265                "url": "https://github.com/phar-io/manifest.git",
    199                 "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
    200             },
    201             "dist": {
    202                 "type": "zip",
    203                 "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
    204                 "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
     266                "reference": "54750ef60c58e43759730615a392c31c80e23176"
     267            },
     268            "dist": {
     269                "type": "zip",
     270                "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
     271                "reference": "54750ef60c58e43759730615a392c31c80e23176",
    205272                "shasum": ""
    206273            },
    207274            "require": {
    208275                "ext-dom": "*",
     276                "ext-libxml": "*",
    209277                "ext-phar": "*",
    210278                "ext-xmlwriter": "*",
     
    247315            "support": {
    248316                "issues": "https://github.com/phar-io/manifest/issues",
    249                 "source": "https://github.com/phar-io/manifest/tree/2.0.3"
    250             },
    251             "time": "2021-07-20T11:28:43+00:00"
     317                "source": "https://github.com/phar-io/manifest/tree/2.0.4"
     318            },
     319            "funding": [
     320                {
     321                    "url": "https://github.com/theseer",
     322                    "type": "github"
     323                }
     324            ],
     325            "time": "2024-03-03T12:33:53+00:00"
    252326        },
    253327        {
    254328            "name": "phar-io/version",
    255             "version": "3.1.1",
     329            "version": "3.2.1",
    256330            "source": {
    257331                "type": "git",
    258332                "url": "https://github.com/phar-io/version.git",
    259                 "reference": "15a90844ad40f127afd244c0cad228de2a80052a"
    260             },
    261             "dist": {
    262                 "type": "zip",
    263                 "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a",
    264                 "reference": "15a90844ad40f127afd244c0cad228de2a80052a",
     333                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
     334            },
     335            "dist": {
     336                "type": "zip",
     337                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
     338                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
    265339                "shasum": ""
    266340            },
     
    298372            "support": {
    299373                "issues": "https://github.com/phar-io/version/issues",
    300                 "source": "https://github.com/phar-io/version/tree/3.1.1"
    301             },
    302             "time": "2022-02-07T21:56:48+00:00"
    303         },
    304         {
    305             "name": "phpdocumentor/reflection-common",
    306             "version": "2.2.0",
    307             "source": {
    308                 "type": "git",
    309                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
    310                 "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
    311             },
    312             "dist": {
    313                 "type": "zip",
    314                 "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
    315                 "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
    316                 "shasum": ""
    317             },
    318             "require": {
    319                 "php": "^7.2 || ^8.0"
    320             },
    321             "type": "library",
    322             "extra": {
    323                 "branch-alias": {
    324                     "dev-2.x": "2.x-dev"
     374                "source": "https://github.com/phar-io/version/tree/3.2.1"
     375            },
     376            "time": "2022-02-21T01:04:05+00:00"
     377        },
     378        {
     379            "name": "phpoption/phpoption",
     380            "version": "1.9.4",
     381            "source": {
     382                "type": "git",
     383                "url": "https://github.com/schmittjoh/php-option.git",
     384                "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d"
     385            },
     386            "dist": {
     387                "type": "zip",
     388                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
     389                "reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
     390                "shasum": ""
     391            },
     392            "require": {
     393                "php": "^7.2.5 || ^8.0"
     394            },
     395            "require-dev": {
     396                "bamarni/composer-bin-plugin": "^1.8.2",
     397                "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34"
     398            },
     399            "type": "library",
     400            "extra": {
     401                "bamarni-bin": {
     402                    "bin-links": true,
     403                    "forward-command": false
     404                },
     405                "branch-alias": {
     406                    "dev-master": "1.9-dev"
    325407                }
    326408            },
    327409            "autoload": {
    328410                "psr-4": {
    329                     "phpDocumentor\\Reflection\\": "src/"
    330                 }
    331             },
    332             "notification-url": "https://packagist.org/downloads/",
    333             "license": [
    334                 "MIT"
    335             ],
    336             "authors": [
    337                 {
    338                     "name": "Jaap van Otterdijk",
    339                     "email": "opensource@ijaap.nl"
    340                 }
    341             ],
    342             "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
    343             "homepage": "http://www.phpdoc.org",
     411                    "PhpOption\\": "src/PhpOption/"
     412                }
     413            },
     414            "notification-url": "https://packagist.org/downloads/",
     415            "license": [
     416                "Apache-2.0"
     417            ],
     418            "authors": [
     419                {
     420                    "name": "Johannes M. Schmitt",
     421                    "email": "schmittjoh@gmail.com",
     422                    "homepage": "https://github.com/schmittjoh"
     423                },
     424                {
     425                    "name": "Graham Campbell",
     426                    "email": "hello@gjcampbell.co.uk",
     427                    "homepage": "https://github.com/GrahamCampbell"
     428                }
     429            ],
     430            "description": "Option Type for PHP",
    344431            "keywords": [
    345                 "FQSEN",
    346                 "phpDocumentor",
    347                 "phpdoc",
    348                 "reflection",
    349                 "static analysis"
    350             ],
    351             "support": {
    352                 "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
    353                 "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
    354             },
    355             "time": "2020-06-27T09:03:43+00:00"
    356         },
    357         {
    358             "name": "phpdocumentor/reflection-docblock",
    359             "version": "5.3.0",
    360             "source": {
    361                 "type": "git",
    362                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
    363                 "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
    364             },
    365             "dist": {
    366                 "type": "zip",
    367                 "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
    368                 "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
    369                 "shasum": ""
    370             },
    371             "require": {
    372                 "ext-filter": "*",
    373                 "php": "^7.2 || ^8.0",
    374                 "phpdocumentor/reflection-common": "^2.2",
    375                 "phpdocumentor/type-resolver": "^1.3",
    376                 "webmozart/assert": "^1.9.1"
    377             },
    378             "require-dev": {
    379                 "mockery/mockery": "~1.3.2",
    380                 "psalm/phar": "^4.8"
    381             },
    382             "type": "library",
    383             "extra": {
    384                 "branch-alias": {
    385                     "dev-master": "5.x-dev"
    386                 }
    387             },
    388             "autoload": {
    389                 "psr-4": {
    390                     "phpDocumentor\\Reflection\\": "src"
    391                 }
    392             },
    393             "notification-url": "https://packagist.org/downloads/",
    394             "license": [
    395                 "MIT"
    396             ],
    397             "authors": [
    398                 {
    399                     "name": "Mike van Riel",
    400                     "email": "me@mikevanriel.com"
    401                 },
    402                 {
    403                     "name": "Jaap van Otterdijk",
    404                     "email": "account@ijaap.nl"
    405                 }
    406             ],
    407             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
    408             "support": {
    409                 "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
    410                 "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
    411             },
    412             "time": "2021-10-19T17:43:47+00:00"
    413         },
    414         {
    415             "name": "phpdocumentor/type-resolver",
    416             "version": "1.6.0",
    417             "source": {
    418                 "type": "git",
    419                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
    420                 "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
    421             },
    422             "dist": {
    423                 "type": "zip",
    424                 "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
    425                 "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
    426                 "shasum": ""
    427             },
    428             "require": {
    429                 "php": "^7.2 || ^8.0",
    430                 "phpdocumentor/reflection-common": "^2.0"
    431             },
    432             "require-dev": {
    433                 "ext-tokenizer": "*",
    434                 "psalm/phar": "^4.8"
    435             },
    436             "type": "library",
    437             "extra": {
    438                 "branch-alias": {
    439                     "dev-1.x": "1.x-dev"
    440                 }
    441             },
    442             "autoload": {
    443                 "psr-4": {
    444                     "phpDocumentor\\Reflection\\": "src"
    445                 }
    446             },
    447             "notification-url": "https://packagist.org/downloads/",
    448             "license": [
    449                 "MIT"
    450             ],
    451             "authors": [
    452                 {
    453                     "name": "Mike van Riel",
    454                     "email": "me@mikevanriel.com"
    455                 }
    456             ],
    457             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
    458             "support": {
    459                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
    460                 "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0"
    461             },
    462             "time": "2022-01-04T19:58:01+00:00"
    463         },
    464         {
    465             "name": "phpspec/prophecy",
    466             "version": "v1.15.0",
    467             "source": {
    468                 "type": "git",
    469                 "url": "https://github.com/phpspec/prophecy.git",
    470                 "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
    471             },
    472             "dist": {
    473                 "type": "zip",
    474                 "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
    475                 "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
    476                 "shasum": ""
    477             },
    478             "require": {
    479                 "doctrine/instantiator": "^1.2",
    480                 "php": "^7.2 || ~8.0, <8.2",
    481                 "phpdocumentor/reflection-docblock": "^5.2",
    482                 "sebastian/comparator": "^3.0 || ^4.0",
    483                 "sebastian/recursion-context": "^3.0 || ^4.0"
    484             },
    485             "require-dev": {
    486                 "phpspec/phpspec": "^6.0 || ^7.0",
    487                 "phpunit/phpunit": "^8.0 || ^9.0"
    488             },
    489             "type": "library",
    490             "extra": {
    491                 "branch-alias": {
    492                     "dev-master": "1.x-dev"
    493                 }
    494             },
    495             "autoload": {
    496                 "psr-4": {
    497                     "Prophecy\\": "src/Prophecy"
    498                 }
    499             },
    500             "notification-url": "https://packagist.org/downloads/",
    501             "license": [
    502                 "MIT"
    503             ],
    504             "authors": [
    505                 {
    506                     "name": "Konstantin Kudryashov",
    507                     "email": "ever.zet@gmail.com",
    508                     "homepage": "http://everzet.com"
    509                 },
    510                 {
    511                     "name": "Marcello Duarte",
    512                     "email": "marcello.duarte@gmail.com"
    513                 }
    514             ],
    515             "description": "Highly opinionated mocking framework for PHP 5.3+",
    516             "homepage": "https://github.com/phpspec/prophecy",
    517             "keywords": [
    518                 "Double",
    519                 "Dummy",
    520                 "fake",
    521                 "mock",
    522                 "spy",
    523                 "stub"
    524             ],
    525             "support": {
    526                 "issues": "https://github.com/phpspec/prophecy/issues",
    527                 "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
    528             },
    529             "time": "2021-12-08T12:19:24+00:00"
     432                "language",
     433                "option",
     434                "php",
     435                "type"
     436            ],
     437            "support": {
     438                "issues": "https://github.com/schmittjoh/php-option/issues",
     439                "source": "https://github.com/schmittjoh/php-option/tree/1.9.4"
     440            },
     441            "funding": [
     442                {
     443                    "url": "https://github.com/GrahamCampbell",
     444                    "type": "github"
     445                },
     446                {
     447                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
     448                    "type": "tidelift"
     449                }
     450            ],
     451            "time": "2025-08-21T11:53:16+00:00"
    530452        },
    531453        {
    532454            "name": "phpunit/php-code-coverage",
    533             "version": "9.2.10",
     455            "version": "9.2.32",
    534456            "source": {
    535457                "type": "git",
    536458                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
    537                 "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687"
    538             },
    539             "dist": {
    540                 "type": "zip",
    541                 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687",
    542                 "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687",
     459                "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5"
     460            },
     461            "dist": {
     462                "type": "zip",
     463                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5",
     464                "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5",
    543465                "shasum": ""
    544466            },
     
    547469                "ext-libxml": "*",
    548470                "ext-xmlwriter": "*",
    549                 "nikic/php-parser": "^4.13.0",
     471                "nikic/php-parser": "^4.19.1 || ^5.1.0",
    550472                "php": ">=7.3",
    551                 "phpunit/php-file-iterator": "^3.0.3",
    552                 "phpunit/php-text-template": "^2.0.2",
    553                 "sebastian/code-unit-reverse-lookup": "^2.0.2",
    554                 "sebastian/complexity": "^2.0",
    555                 "sebastian/environment": "^5.1.2",
    556                 "sebastian/lines-of-code": "^1.0.3",
    557                 "sebastian/version": "^3.0.1",
    558                 "theseer/tokenizer": "^1.2.0"
    559             },
    560             "require-dev": {
    561                 "phpunit/phpunit": "^9.3"
     473                "phpunit/php-file-iterator": "^3.0.6",
     474                "phpunit/php-text-template": "^2.0.4",
     475                "sebastian/code-unit-reverse-lookup": "^2.0.3",
     476                "sebastian/complexity": "^2.0.3",
     477                "sebastian/environment": "^5.1.5",
     478                "sebastian/lines-of-code": "^1.0.4",
     479                "sebastian/version": "^3.0.2",
     480                "theseer/tokenizer": "^1.2.3"
     481            },
     482            "require-dev": {
     483                "phpunit/phpunit": "^9.6"
    562484            },
    563485            "suggest": {
    564                 "ext-pcov": "*",
    565                 "ext-xdebug": "*"
    566             },
    567             "type": "library",
    568             "extra": {
    569                 "branch-alias": {
    570                     "dev-master": "9.2-dev"
     486                "ext-pcov": "PHP extension that provides line coverage",
     487                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
     488            },
     489            "type": "library",
     490            "extra": {
     491                "branch-alias": {
     492                    "dev-main": "9.2.x-dev"
    571493                }
    572494            },
     
    596518            "support": {
    597519                "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
    598                 "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10"
     520                "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
     521                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32"
    599522            },
    600523            "funding": [
     
    604527                }
    605528            ],
    606             "time": "2021-12-05T09:12:13+00:00"
     529            "time": "2024-08-22T04:23:01+00:00"
    607530        },
    608531        {
     
    849772        {
    850773            "name": "phpunit/phpunit",
    851             "version": "9.5.13",
     774            "version": "9.6.25",
    852775            "source": {
    853776                "type": "git",
    854777                "url": "https://github.com/sebastianbergmann/phpunit.git",
    855                 "reference": "597cb647654ede35e43b137926dfdfef0fb11743"
    856             },
    857             "dist": {
    858                 "type": "zip",
    859                 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743",
    860                 "reference": "597cb647654ede35e43b137926dfdfef0fb11743",
    861                 "shasum": ""
    862             },
    863             "require": {
    864                 "doctrine/instantiator": "^1.3.1",
     778                "reference": "049c011e01be805202d8eebedef49f769a8ec7b7"
     779            },
     780            "dist": {
     781                "type": "zip",
     782                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/049c011e01be805202d8eebedef49f769a8ec7b7",
     783                "reference": "049c011e01be805202d8eebedef49f769a8ec7b7",
     784                "shasum": ""
     785            },
     786            "require": {
     787                "doctrine/instantiator": "^1.5.0 || ^2",
    865788                "ext-dom": "*",
    866789                "ext-json": "*",
     
    869792                "ext-xml": "*",
    870793                "ext-xmlwriter": "*",
    871                 "myclabs/deep-copy": "^1.10.1",
    872                 "phar-io/manifest": "^2.0.3",
    873                 "phar-io/version": "^3.0.2",
     794                "myclabs/deep-copy": "^1.13.4",
     795                "phar-io/manifest": "^2.0.4",
     796                "phar-io/version": "^3.2.1",
    874797                "php": ">=7.3",
    875                 "phpspec/prophecy": "^1.12.1",
    876                 "phpunit/php-code-coverage": "^9.2.7",
    877                 "phpunit/php-file-iterator": "^3.0.5",
     798                "phpunit/php-code-coverage": "^9.2.32",
     799                "phpunit/php-file-iterator": "^3.0.6",
    878800                "phpunit/php-invoker": "^3.1.1",
    879                 "phpunit/php-text-template": "^2.0.3",
    880                 "phpunit/php-timer": "^5.0.2",
    881                 "sebastian/cli-parser": "^1.0.1",
    882                 "sebastian/code-unit": "^1.0.6",
    883                 "sebastian/comparator": "^4.0.5",
    884                 "sebastian/diff": "^4.0.3",
    885                 "sebastian/environment": "^5.1.3",
    886                 "sebastian/exporter": "^4.0.3",
    887                 "sebastian/global-state": "^5.0.1",
    888                 "sebastian/object-enumerator": "^4.0.3",
    889                 "sebastian/resource-operations": "^3.0.3",
    890                 "sebastian/type": "^2.3.4",
     801                "phpunit/php-text-template": "^2.0.4",
     802                "phpunit/php-timer": "^5.0.3",
     803                "sebastian/cli-parser": "^1.0.2",
     804                "sebastian/code-unit": "^1.0.8",
     805                "sebastian/comparator": "^4.0.9",
     806                "sebastian/diff": "^4.0.6",
     807                "sebastian/environment": "^5.1.5",
     808                "sebastian/exporter": "^4.0.6",
     809                "sebastian/global-state": "^5.0.8",
     810                "sebastian/object-enumerator": "^4.0.4",
     811                "sebastian/resource-operations": "^3.0.4",
     812                "sebastian/type": "^3.2.1",
    891813                "sebastian/version": "^3.0.2"
    892814            },
    893             "require-dev": {
    894                 "ext-pdo": "*",
    895                 "phpspec/prophecy-phpunit": "^2.0.1"
    896             },
    897815            "suggest": {
    898                 "ext-soap": "*",
    899                 "ext-xdebug": "*"
     816                "ext-soap": "To be able to generate mocks based on WSDL files",
     817                "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
    900818            },
    901819            "bin": [
     
    905823            "extra": {
    906824                "branch-alias": {
    907                     "dev-master": "9.5-dev"
     825                    "dev-master": "9.6-dev"
    908826                }
    909827            },
     
    936854            "support": {
    937855                "issues": "https://github.com/sebastianbergmann/phpunit/issues",
    938                 "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13"
     856                "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
     857                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.25"
    939858            },
    940859            "funding": [
     
    946865                    "url": "https://github.com/sebastianbergmann",
    947866                    "type": "github"
    948                 }
    949             ],
    950             "time": "2022-01-24T07:33:35+00:00"
     867                },
     868                {
     869                    "url": "https://liberapay.com/sebastianbergmann",
     870                    "type": "liberapay"
     871                },
     872                {
     873                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     874                    "type": "thanks_dev"
     875                },
     876                {
     877                    "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
     878                    "type": "tidelift"
     879                }
     880            ],
     881            "time": "2025-08-20T14:38:31+00:00"
    951882        },
    952883        {
    953884            "name": "sebastian/cli-parser",
    954             "version": "1.0.1",
     885            "version": "1.0.2",
    955886            "source": {
    956887                "type": "git",
    957888                "url": "https://github.com/sebastianbergmann/cli-parser.git",
    958                 "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
    959             },
    960             "dist": {
    961                 "type": "zip",
    962                 "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
    963                 "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
     889                "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
     890            },
     891            "dist": {
     892                "type": "zip",
     893                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
     894                "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
    964895                "shasum": ""
    965896            },
     
    996927            "support": {
    997928                "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
    998                 "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
     929                "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
    999930            },
    1000931            "funding": [
     
    1004935                }
    1005936            ],
    1006             "time": "2020-09-28T06:08:49+00:00"
     937            "time": "2024-03-02T06:27:43+00:00"
    1007938        },
    1008939        {
     
    11191050        {
    11201051            "name": "sebastian/comparator",
    1121             "version": "4.0.6",
     1052            "version": "4.0.9",
    11221053            "source": {
    11231054                "type": "git",
    11241055                "url": "https://github.com/sebastianbergmann/comparator.git",
    1125                 "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
    1126             },
    1127             "dist": {
    1128                 "type": "zip",
    1129                 "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
    1130                 "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
     1056                "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
     1057            },
     1058            "dist": {
     1059                "type": "zip",
     1060                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
     1061                "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
    11311062                "shasum": ""
    11321063            },
     
    11811112            "support": {
    11821113                "issues": "https://github.com/sebastianbergmann/comparator/issues",
    1183                 "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
     1114                "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
    11841115            },
    11851116            "funding": [
     
    11871118                    "url": "https://github.com/sebastianbergmann",
    11881119                    "type": "github"
    1189                 }
    1190             ],
    1191             "time": "2020-10-26T15:49:45+00:00"
     1120                },
     1121                {
     1122                    "url": "https://liberapay.com/sebastianbergmann",
     1123                    "type": "liberapay"
     1124                },
     1125                {
     1126                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1127                    "type": "thanks_dev"
     1128                },
     1129                {
     1130                    "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
     1131                    "type": "tidelift"
     1132                }
     1133            ],
     1134            "time": "2025-08-10T06:51:50+00:00"
    11921135        },
    11931136        {
    11941137            "name": "sebastian/complexity",
    1195             "version": "2.0.2",
     1138            "version": "2.0.3",
    11961139            "source": {
    11971140                "type": "git",
    11981141                "url": "https://github.com/sebastianbergmann/complexity.git",
    1199                 "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
    1200             },
    1201             "dist": {
    1202                 "type": "zip",
    1203                 "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
    1204                 "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
    1205                 "shasum": ""
    1206             },
    1207             "require": {
    1208                 "nikic/php-parser": "^4.7",
     1142                "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
     1143            },
     1144            "dist": {
     1145                "type": "zip",
     1146                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
     1147                "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
     1148                "shasum": ""
     1149            },
     1150            "require": {
     1151                "nikic/php-parser": "^4.18 || ^5.0",
    12091152                "php": ">=7.3"
    12101153            },
     
    12381181            "support": {
    12391182                "issues": "https://github.com/sebastianbergmann/complexity/issues",
    1240                 "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
     1183                "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
    12411184            },
    12421185            "funding": [
     
    12461189                }
    12471190            ],
    1248             "time": "2020-10-26T15:52:27+00:00"
     1191            "time": "2023-12-22T06:19:30+00:00"
    12491192        },
    12501193        {
    12511194            "name": "sebastian/diff",
    1252             "version": "4.0.4",
     1195            "version": "4.0.6",
    12531196            "source": {
    12541197                "type": "git",
    12551198                "url": "https://github.com/sebastianbergmann/diff.git",
    1256                 "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
    1257             },
    1258             "dist": {
    1259                 "type": "zip",
    1260                 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
    1261                 "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
     1199                "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
     1200            },
     1201            "dist": {
     1202                "type": "zip",
     1203                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
     1204                "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
    12621205                "shasum": ""
    12631206            },
     
    13041247            "support": {
    13051248                "issues": "https://github.com/sebastianbergmann/diff/issues",
    1306                 "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
     1249                "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
    13071250            },
    13081251            "funding": [
     
    13121255                }
    13131256            ],
    1314             "time": "2020-10-26T13:10:38+00:00"
     1257            "time": "2024-03-02T06:30:58+00:00"
    13151258        },
    13161259        {
    13171260            "name": "sebastian/environment",
    1318             "version": "5.1.3",
     1261            "version": "5.1.5",
    13191262            "source": {
    13201263                "type": "git",
    13211264                "url": "https://github.com/sebastianbergmann/environment.git",
    1322                 "reference": "388b6ced16caa751030f6a69e588299fa09200ac"
    1323             },
    1324             "dist": {
    1325                 "type": "zip",
    1326                 "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac",
    1327                 "reference": "388b6ced16caa751030f6a69e588299fa09200ac",
     1265                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
     1266            },
     1267            "dist": {
     1268                "type": "zip",
     1269                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
     1270                "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
    13281271                "shasum": ""
    13291272            },
     
    13671310            "support": {
    13681311                "issues": "https://github.com/sebastianbergmann/environment/issues",
    1369                 "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3"
     1312                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
    13701313            },
    13711314            "funding": [
     
    13751318                }
    13761319            ],
    1377             "time": "2020-09-28T05:52:38+00:00"
     1320            "time": "2023-02-03T06:03:51+00:00"
    13781321        },
    13791322        {
    13801323            "name": "sebastian/exporter",
    1381             "version": "4.0.4",
     1324            "version": "4.0.6",
    13821325            "source": {
    13831326                "type": "git",
    13841327                "url": "https://github.com/sebastianbergmann/exporter.git",
    1385                 "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
    1386             },
    1387             "dist": {
    1388                 "type": "zip",
    1389                 "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
    1390                 "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
     1328                "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
     1329            },
     1330            "dist": {
     1331                "type": "zip",
     1332                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
     1333                "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
    13911334                "shasum": ""
    13921335            },
     
    14441387            "support": {
    14451388                "issues": "https://github.com/sebastianbergmann/exporter/issues",
    1446                 "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
     1389                "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
    14471390            },
    14481391            "funding": [
     
    14521395                }
    14531396            ],
    1454             "time": "2021-11-11T14:18:36+00:00"
     1397            "time": "2024-03-02T06:33:00+00:00"
    14551398        },
    14561399        {
    14571400            "name": "sebastian/global-state",
    1458             "version": "5.0.4",
     1401            "version": "5.0.8",
    14591402            "source": {
    14601403                "type": "git",
    14611404                "url": "https://github.com/sebastianbergmann/global-state.git",
    1462                 "reference": "19c519631c5a511b7ed0ad64a6713fdb3fd25fe4"
    1463             },
    1464             "dist": {
    1465                 "type": "zip",
    1466                 "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/19c519631c5a511b7ed0ad64a6713fdb3fd25fe4",
    1467                 "reference": "19c519631c5a511b7ed0ad64a6713fdb3fd25fe4",
     1405                "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
     1406            },
     1407            "dist": {
     1408                "type": "zip",
     1409                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
     1410                "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
    14681411                "shasum": ""
    14691412            },
     
    15081451            "support": {
    15091452                "issues": "https://github.com/sebastianbergmann/global-state/issues",
    1510                 "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.4"
     1453                "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
    15111454            },
    15121455            "funding": [
     
    15141457                    "url": "https://github.com/sebastianbergmann",
    15151458                    "type": "github"
    1516                 }
    1517             ],
    1518             "time": "2022-02-10T07:01:19+00:00"
     1459                },
     1460                {
     1461                    "url": "https://liberapay.com/sebastianbergmann",
     1462                    "type": "liberapay"
     1463                },
     1464                {
     1465                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1466                    "type": "thanks_dev"
     1467                },
     1468                {
     1469                    "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
     1470                    "type": "tidelift"
     1471                }
     1472            ],
     1473            "time": "2025-08-10T07:10:35+00:00"
    15191474        },
    15201475        {
    15211476            "name": "sebastian/lines-of-code",
    1522             "version": "1.0.3",
     1477            "version": "1.0.4",
    15231478            "source": {
    15241479                "type": "git",
    15251480                "url": "https://github.com/sebastianbergmann/lines-of-code.git",
    1526                 "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
    1527             },
    1528             "dist": {
    1529                 "type": "zip",
    1530                 "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
    1531                 "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
    1532                 "shasum": ""
    1533             },
    1534             "require": {
    1535                 "nikic/php-parser": "^4.6",
     1481                "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
     1482            },
     1483            "dist": {
     1484                "type": "zip",
     1485                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
     1486                "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
     1487                "shasum": ""
     1488            },
     1489            "require": {
     1490                "nikic/php-parser": "^4.18 || ^5.0",
    15361491                "php": ">=7.3"
    15371492            },
     
    15651520            "support": {
    15661521                "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
    1567                 "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
     1522                "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
    15681523            },
    15691524            "funding": [
     
    15731528                }
    15741529            ],
    1575             "time": "2020-11-28T06:42:11+00:00"
     1530            "time": "2023-12-22T06:20:34+00:00"
    15761531        },
    15771532        {
     
    16891644        {
    16901645            "name": "sebastian/recursion-context",
    1691             "version": "4.0.4",
     1646            "version": "4.0.6",
    16921647            "source": {
    16931648                "type": "git",
    16941649                "url": "https://github.com/sebastianbergmann/recursion-context.git",
    1695                 "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
    1696             },
    1697             "dist": {
    1698                 "type": "zip",
    1699                 "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
    1700                 "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
     1650                "reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
     1651            },
     1652            "dist": {
     1653                "type": "zip",
     1654                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
     1655                "reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
    17011656                "shasum": ""
    17021657            },
     
    17371692            ],
    17381693            "description": "Provides functionality to recursively process PHP variables",
    1739             "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
     1694            "homepage": "https://github.com/sebastianbergmann/recursion-context",
    17401695            "support": {
    17411696                "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
    1742                 "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
     1697                "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
    17431698            },
    17441699            "funding": [
     
    17461701                    "url": "https://github.com/sebastianbergmann",
    17471702                    "type": "github"
    1748                 }
    1749             ],
    1750             "time": "2020-10-26T13:17:30+00:00"
     1703                },
     1704                {
     1705                    "url": "https://liberapay.com/sebastianbergmann",
     1706                    "type": "liberapay"
     1707                },
     1708                {
     1709                    "url": "https://thanks.dev/u/gh/sebastianbergmann",
     1710                    "type": "thanks_dev"
     1711                },
     1712                {
     1713                    "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
     1714                    "type": "tidelift"
     1715                }
     1716            ],
     1717            "time": "2025-08-10T06:57:39+00:00"
    17511718        },
    17521719        {
    17531720            "name": "sebastian/resource-operations",
    1754             "version": "3.0.3",
     1721            "version": "3.0.4",
    17551722            "source": {
    17561723                "type": "git",
    17571724                "url": "https://github.com/sebastianbergmann/resource-operations.git",
    1758                 "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
    1759             },
    1760             "dist": {
    1761                 "type": "zip",
    1762                 "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
    1763                 "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
     1725                "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
     1726            },
     1727            "dist": {
     1728                "type": "zip",
     1729                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
     1730                "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
    17641731                "shasum": ""
    17651732            },
     
    17731740            "extra": {
    17741741                "branch-alias": {
    1775                     "dev-master": "3.0-dev"
     1742                    "dev-main": "3.0-dev"
    17761743                }
    17771744            },
     
    17941761            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
    17951762            "support": {
    1796                 "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
    1797                 "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
     1763                "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
    17981764            },
    17991765            "funding": [
     
    18031769                }
    18041770            ],
    1805             "time": "2020-09-28T06:45:17+00:00"
     1771            "time": "2024-03-14T16:00:52+00:00"
    18061772        },
    18071773        {
    18081774            "name": "sebastian/type",
    1809             "version": "2.3.4",
     1775            "version": "3.2.1",
    18101776            "source": {
    18111777                "type": "git",
    18121778                "url": "https://github.com/sebastianbergmann/type.git",
    1813                 "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
    1814             },
    1815             "dist": {
    1816                 "type": "zip",
    1817                 "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
    1818                 "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
     1779                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
     1780            },
     1781            "dist": {
     1782                "type": "zip",
     1783                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
     1784                "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
    18191785                "shasum": ""
    18201786            },
     
    18231789            },
    18241790            "require-dev": {
    1825                 "phpunit/phpunit": "^9.3"
    1826             },
    1827             "type": "library",
    1828             "extra": {
    1829                 "branch-alias": {
    1830                     "dev-master": "2.3-dev"
     1791                "phpunit/phpunit": "^9.5"
     1792            },
     1793            "type": "library",
     1794            "extra": {
     1795                "branch-alias": {
     1796                    "dev-master": "3.2-dev"
    18311797                }
    18321798            },
     
    18511817            "support": {
    18521818                "issues": "https://github.com/sebastianbergmann/type/issues",
    1853                 "source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
     1819                "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
    18541820            },
    18551821            "funding": [
     
    18591825                }
    18601826            ],
    1861             "time": "2021-06-15T12:49:02+00:00"
     1827            "time": "2023-02-03T06:13:03+00:00"
    18621828        },
    18631829        {
     
    19161882        {
    19171883            "name": "symfony/polyfill-ctype",
    1918             "version": "v1.24.0",
     1884            "version": "v1.33.0",
    19191885            "source": {
    19201886                "type": "git",
    19211887                "url": "https://github.com/symfony/polyfill-ctype.git",
    1922                 "reference": "30885182c981ab175d4d034db0f6f469898070ab"
    1923             },
    1924             "dist": {
    1925                 "type": "zip",
    1926                 "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
    1927                 "reference": "30885182c981ab175d4d034db0f6f469898070ab",
    1928                 "shasum": ""
    1929             },
    1930             "require": {
    1931                 "php": ">=7.1"
     1888                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
     1889            },
     1890            "dist": {
     1891                "type": "zip",
     1892                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
     1893                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
     1894                "shasum": ""
     1895            },
     1896            "require": {
     1897                "php": ">=7.2"
    19321898            },
    19331899            "provide": {
     
    19391905            "type": "library",
    19401906            "extra": {
    1941                 "branch-alias": {
    1942                     "dev-main": "1.23-dev"
    1943                 },
    19441907                "thanks": {
    1945                     "name": "symfony/polyfill",
    1946                     "url": "https://github.com/symfony/polyfill"
    1947                 }
    1948             },
    1949             "autoload": {
     1908                    "url": "https://github.com/symfony/polyfill",
     1909                    "name": "symfony/polyfill"
     1910                }
     1911            },
     1912            "autoload": {
     1913                "files": [
     1914                    "bootstrap.php"
     1915                ],
    19501916                "psr-4": {
    19511917                    "Symfony\\Polyfill\\Ctype\\": ""
    1952                 },
    1953                 "files": [
    1954                     "bootstrap.php"
    1955                 ]
     1918                }
    19561919            },
    19571920            "notification-url": "https://packagist.org/downloads/",
     
    19781941            ],
    19791942            "support": {
    1980                 "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
     1943                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
    19811944            },
    19821945            "funding": [
     
    19901953                },
    19911954                {
     1955                    "url": "https://github.com/nicolas-grekas",
     1956                    "type": "github"
     1957                },
     1958                {
    19921959                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
    19931960                    "type": "tidelift"
    19941961                }
    19951962            ],
    1996             "time": "2021-10-20T20:35:02+00:00"
     1963            "time": "2024-09-09T11:45:10+00:00"
     1964        },
     1965        {
     1966            "name": "symfony/polyfill-mbstring",
     1967            "version": "v1.33.0",
     1968            "source": {
     1969                "type": "git",
     1970                "url": "https://github.com/symfony/polyfill-mbstring.git",
     1971                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
     1972            },
     1973            "dist": {
     1974                "type": "zip",
     1975                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
     1976                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
     1977                "shasum": ""
     1978            },
     1979            "require": {
     1980                "ext-iconv": "*",
     1981                "php": ">=7.2"
     1982            },
     1983            "provide": {
     1984                "ext-mbstring": "*"
     1985            },
     1986            "suggest": {
     1987                "ext-mbstring": "For best performance"
     1988            },
     1989            "type": "library",
     1990            "extra": {
     1991                "thanks": {
     1992                    "url": "https://github.com/symfony/polyfill",
     1993                    "name": "symfony/polyfill"
     1994                }
     1995            },
     1996            "autoload": {
     1997                "files": [
     1998                    "bootstrap.php"
     1999                ],
     2000                "psr-4": {
     2001                    "Symfony\\Polyfill\\Mbstring\\": ""
     2002                }
     2003            },
     2004            "notification-url": "https://packagist.org/downloads/",
     2005            "license": [
     2006                "MIT"
     2007            ],
     2008            "authors": [
     2009                {
     2010                    "name": "Nicolas Grekas",
     2011                    "email": "p@tchwork.com"
     2012                },
     2013                {
     2014                    "name": "Symfony Community",
     2015                    "homepage": "https://symfony.com/contributors"
     2016                }
     2017            ],
     2018            "description": "Symfony polyfill for the Mbstring extension",
     2019            "homepage": "https://symfony.com",
     2020            "keywords": [
     2021                "compatibility",
     2022                "mbstring",
     2023                "polyfill",
     2024                "portable",
     2025                "shim"
     2026            ],
     2027            "support": {
     2028                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
     2029            },
     2030            "funding": [
     2031                {
     2032                    "url": "https://symfony.com/sponsor",
     2033                    "type": "custom"
     2034                },
     2035                {
     2036                    "url": "https://github.com/fabpot",
     2037                    "type": "github"
     2038                },
     2039                {
     2040                    "url": "https://github.com/nicolas-grekas",
     2041                    "type": "github"
     2042                },
     2043                {
     2044                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
     2045                    "type": "tidelift"
     2046                }
     2047            ],
     2048            "time": "2024-12-23T08:48:59+00:00"
     2049        },
     2050        {
     2051            "name": "symfony/polyfill-php80",
     2052            "version": "v1.33.0",
     2053            "source": {
     2054                "type": "git",
     2055                "url": "https://github.com/symfony/polyfill-php80.git",
     2056                "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
     2057            },
     2058            "dist": {
     2059                "type": "zip",
     2060                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
     2061                "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
     2062                "shasum": ""
     2063            },
     2064            "require": {
     2065                "php": ">=7.2"
     2066            },
     2067            "type": "library",
     2068            "extra": {
     2069                "thanks": {
     2070                    "url": "https://github.com/symfony/polyfill",
     2071                    "name": "symfony/polyfill"
     2072                }
     2073            },
     2074            "autoload": {
     2075                "files": [
     2076                    "bootstrap.php"
     2077                ],
     2078                "psr-4": {
     2079                    "Symfony\\Polyfill\\Php80\\": ""
     2080                },
     2081                "classmap": [
     2082                    "Resources/stubs"
     2083                ]
     2084            },
     2085            "notification-url": "https://packagist.org/downloads/",
     2086            "license": [
     2087                "MIT"
     2088            ],
     2089            "authors": [
     2090                {
     2091                    "name": "Ion Bazan",
     2092                    "email": "ion.bazan@gmail.com"
     2093                },
     2094                {
     2095                    "name": "Nicolas Grekas",
     2096                    "email": "p@tchwork.com"
     2097                },
     2098                {
     2099                    "name": "Symfony Community",
     2100                    "homepage": "https://symfony.com/contributors"
     2101                }
     2102            ],
     2103            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
     2104            "homepage": "https://symfony.com",
     2105            "keywords": [
     2106                "compatibility",
     2107                "polyfill",
     2108                "portable",
     2109                "shim"
     2110            ],
     2111            "support": {
     2112                "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
     2113            },
     2114            "funding": [
     2115                {
     2116                    "url": "https://symfony.com/sponsor",
     2117                    "type": "custom"
     2118                },
     2119                {
     2120                    "url": "https://github.com/fabpot",
     2121                    "type": "github"
     2122                },
     2123                {
     2124                    "url": "https://github.com/nicolas-grekas",
     2125                    "type": "github"
     2126                },
     2127                {
     2128                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
     2129                    "type": "tidelift"
     2130                }
     2131            ],
     2132            "time": "2025-01-02T08:10:11+00:00"
    19972133        },
    19982134        {
    19992135            "name": "theseer/tokenizer",
    2000             "version": "1.2.1",
     2136            "version": "1.2.3",
    20012137            "source": {
    20022138                "type": "git",
    20032139                "url": "https://github.com/theseer/tokenizer.git",
    2004                 "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
    2005             },
    2006             "dist": {
    2007                 "type": "zip",
    2008                 "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
    2009                 "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
     2140                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
     2141            },
     2142            "dist": {
     2143                "type": "zip",
     2144                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
     2145                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
    20102146                "shasum": ""
    20112147            },
     
    20362172            "support": {
    20372173                "issues": "https://github.com/theseer/tokenizer/issues",
    2038                 "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
     2174                "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
    20392175            },
    20402176            "funding": [
     
    20442180                }
    20452181            ],
    2046             "time": "2021-07-28T10:34:58+00:00"
    2047         },
    2048         {
    2049             "name": "webmozart/assert",
    2050             "version": "1.10.0",
    2051             "source": {
    2052                 "type": "git",
    2053                 "url": "https://github.com/webmozarts/assert.git",
    2054                 "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
    2055             },
    2056             "dist": {
    2057                 "type": "zip",
    2058                 "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
    2059                 "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
    2060                 "shasum": ""
    2061             },
    2062             "require": {
    2063                 "php": "^7.2 || ^8.0",
    2064                 "symfony/polyfill-ctype": "^1.8"
    2065             },
    2066             "conflict": {
    2067                 "phpstan/phpstan": "<0.12.20",
    2068                 "vimeo/psalm": "<4.6.1 || 4.6.2"
    2069             },
    2070             "require-dev": {
    2071                 "phpunit/phpunit": "^8.5.13"
    2072             },
    2073             "type": "library",
    2074             "extra": {
    2075                 "branch-alias": {
    2076                     "dev-master": "1.10-dev"
     2182            "time": "2024-03-03T12:36:25+00:00"
     2183        },
     2184        {
     2185            "name": "vlucas/phpdotenv",
     2186            "version": "v5.6.2",
     2187            "source": {
     2188                "type": "git",
     2189                "url": "https://github.com/vlucas/phpdotenv.git",
     2190                "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af"
     2191            },
     2192            "dist": {
     2193                "type": "zip",
     2194                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
     2195                "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
     2196                "shasum": ""
     2197            },
     2198            "require": {
     2199                "ext-pcre": "*",
     2200                "graham-campbell/result-type": "^1.1.3",
     2201                "php": "^7.2.5 || ^8.0",
     2202                "phpoption/phpoption": "^1.9.3",
     2203                "symfony/polyfill-ctype": "^1.24",
     2204                "symfony/polyfill-mbstring": "^1.24",
     2205                "symfony/polyfill-php80": "^1.24"
     2206            },
     2207            "require-dev": {
     2208                "bamarni/composer-bin-plugin": "^1.8.2",
     2209                "ext-filter": "*",
     2210                "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
     2211            },
     2212            "suggest": {
     2213                "ext-filter": "Required to use the boolean validator."
     2214            },
     2215            "type": "library",
     2216            "extra": {
     2217                "bamarni-bin": {
     2218                    "bin-links": true,
     2219                    "forward-command": false
     2220                },
     2221                "branch-alias": {
     2222                    "dev-master": "5.6-dev"
    20772223                }
    20782224            },
    20792225            "autoload": {
    20802226                "psr-4": {
    2081                     "Webmozart\\Assert\\": "src/"
    2082                 }
    2083             },
    2084             "notification-url": "https://packagist.org/downloads/",
    2085             "license": [
    2086                 "MIT"
    2087             ],
    2088             "authors": [
    2089                 {
    2090                     "name": "Bernhard Schussek",
    2091                     "email": "bschussek@gmail.com"
    2092                 }
    2093             ],
    2094             "description": "Assertions to validate method input/output with nice error messages.",
     2227                    "Dotenv\\": "src/"
     2228                }
     2229            },
     2230            "notification-url": "https://packagist.org/downloads/",
     2231            "license": [
     2232                "BSD-3-Clause"
     2233            ],
     2234            "authors": [
     2235                {
     2236                    "name": "Graham Campbell",
     2237                    "email": "hello@gjcampbell.co.uk",
     2238                    "homepage": "https://github.com/GrahamCampbell"
     2239                },
     2240                {
     2241                    "name": "Vance Lucas",
     2242                    "email": "vance@vancelucas.com",
     2243                    "homepage": "https://github.com/vlucas"
     2244                }
     2245            ],
     2246            "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
    20952247            "keywords": [
    2096                 "assert",
    2097                 "check",
    2098                 "validate"
    2099             ],
    2100             "support": {
    2101                 "issues": "https://github.com/webmozarts/assert/issues",
    2102                 "source": "https://github.com/webmozarts/assert/tree/1.10.0"
    2103             },
    2104             "time": "2021-03-09T10:59:23+00:00"
     2248                "dotenv",
     2249                "env",
     2250                "environment"
     2251            ],
     2252            "support": {
     2253                "issues": "https://github.com/vlucas/phpdotenv/issues",
     2254                "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2"
     2255            },
     2256            "funding": [
     2257                {
     2258                    "url": "https://github.com/GrahamCampbell",
     2259                    "type": "github"
     2260                },
     2261                {
     2262                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
     2263                    "type": "tidelift"
     2264                }
     2265            ],
     2266            "time": "2025-04-30T23:37:27+00:00"
    21052267        }
    21062268    ],
    21072269    "aliases": [],
    21082270    "minimum-stability": "stable",
    2109     "stability-flags": [],
     2271    "stability-flags": {},
    21102272    "prefer-stable": false,
    21112273    "prefer-lowest": false,
     
    21162278        "ext-zip": "*"
    21172279    },
    2118     "platform-dev": [],
    2119     "plugin-api-version": "2.0.0"
     2280    "platform-dev": {},
     2281    "plugin-api-version": "2.6.0"
    21202282}
Note: See TracChangeset for help on using the changeset viewer.