!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.3.27 

uname -a: Linux pdx1-shared-a4-04 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64 

uid=6659440(dh_z2jmpm) gid=2086089(pg10499364) groups=2086089(pg10499364)  

Safe-mode: OFF (not secure)

/usr/local/wp/vendor/wp-cli/cache-command/src/   drwxr-xr-x
Free 709.01 GB of 879.6 GB (80.61%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     Transient_Command.php (21.43 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

use WP_CLI\Traverser\RecursiveDataStructureTraverser;
use WP_CLI\Utils;

/**
 * Adds, gets, and deletes entries in the WordPress Transient Cache.
 *
 * By default, the transient cache uses the WordPress database to persist values
 * between requests. On a single site installation, values are stored in the
 * `wp_options` table. On a multisite installation, values are stored in the
 * `wp_options` or the `wp_sitemeta` table, depending on use of the `--network`
 * flag.
 *
 * When a persistent object cache drop-in is installed (e.g. Redis or Memcached),
 * the transient cache skips the database and simply wraps the WP Object Cache.
 *
 * ## EXAMPLES
 *
 *     # Set transient.
 *     $ wp transient set sample_key "test data" 3600
 *     Success: Transient added.
 *
 *     # Get transient.
 *     $ wp transient get sample_key
 *     test data
 *
 *     # Delete transient.
 *     $ wp transient delete sample_key
 *     Success: Transient deleted.
 *
 *     # Delete expired transients.
 *     $ wp transient delete --expired
 *     Success: 12 expired transients deleted from the database.
 *
 *     # Delete all transients.
 *     $ wp transient delete --all
 *     Success: 14 transients deleted from the database.
 */
class Transient_Command extends WP_CLI_Command {

    /**
     * Gets a transient value.
     *
     * For a more complete explanation of the transient cache, including the
     * network|site cache, please see docs for `wp transient`.
     *
     * ## OPTIONS
     *
     * <key>
     * : Key for the transient.
     *
     * [--format=<format>]
     * : Render output in a particular format.
     * ---
     * default: table
     * options:
     *   - table
     *   - csv
     *   - json
     *   - yaml
     * ---
     *
     * [--network]
     * : Get the value of a network|site transient. On single site, this is
     * is a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     *
     * ## EXAMPLES
     *
     *     $ wp transient get sample_key
     *     test data
     *
     *     $ wp transient get random_key
     *     Warning: Transient with key "random_key" is not set.
     */
    public function get( $args, $assoc_args ) {
        list( $key ) = $args;

        $func  = Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient';
        $value = $func( $key );

        if ( false === $value ) {
            WP_CLI::warning( 'Transient with key "' . $key . '" is not set.' );
            exit;
        }

        WP_CLI::print_value( $value, $assoc_args );
    }

    /**
     * Sets a transient value.
     *
     * `<expiration>` is the time until expiration, in seconds.
     *
     * For a more complete explanation of the transient cache, including the
     * network|site cache, please see docs for `wp transient`.
     *
     * ## OPTIONS
     *
     * <key>
     * : Key for the transient.
     *
     * <value>
     * : Value to be set for the transient.
     *
     * [<expiration>]
     * : Time until expiration, in seconds.
     *
     * [--network]
     * : Set the value of a network|site transient. On single site, this is
     * is a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     *
     * ## EXAMPLES
     *
     *     $ wp transient set sample_key "test data" 3600
     *     Success: Transient added.
     */
    public function set( $args, $assoc_args ) {
        list( $key, $value ) = $args;

        $expiration = Utils\get_flag_value( $args, 2, 0 );

        $func = Utils\get_flag_value( $assoc_args, 'network' ) ? 'set_site_transient' : 'set_transient';
        if ( $func( $key, $value, $expiration ) ) {
            WP_CLI::success( 'Transient added.' );
        } else {
            WP_CLI::error( 'Transient could not be set.' );
        }
    }

    /**
     * Deletes a transient value.
     *
     * For a more complete explanation of the transient cache, including the
     * network|site cache, please see docs for `wp transient`.
     *
     * ## OPTIONS
     *
     * [<key>]
     * : Key for the transient.
     *
     * [--network]
     * : Delete the value of a network|site transient. On single site, this is
     * is a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     *
     * [--all]
     * : Delete all transients.
     *
     * [--expired]
     * : Delete all expired transients.
     *
     * ## EXAMPLES
     *
     *     # Delete transient.
     *     $ wp transient delete sample_key
     *     Success: Transient deleted.
     *
     *     # Delete expired transients.
     *     $ wp transient delete --expired
     *     Success: 12 expired transients deleted from the database.
     *
     *     # Delete expired site transients.
     *     $ wp transient delete --expired --network
     *     Success: 1 expired transient deleted from the database.
     *
     *     # Delete all transients.
     *     $ wp transient delete --all
     *     Success: 14 transients deleted from the database.
     *
     *     # Delete all site transients.
     *     $ wp transient delete --all --network
     *     Success: 2 transients deleted from the database.
     *
     *     # Delete all transients in a multisite.
     *     $ wp transient delete --all --network && wp site list --field=url | xargs -n1 -I % wp --url=% transient delete --all
     */
    public function delete( $args, $assoc_args ) {
        $key = ( ! empty( $args ) ) ? $args[0] : null;

        $all     = Utils\get_flag_value( $assoc_args, 'all' );
        $expired = Utils\get_flag_value( $assoc_args, 'expired' );
        $network = Utils\get_flag_value( $assoc_args, 'network' );

        if ( true === $all ) {
            $this->delete_all( $network );
            return;
        } elseif ( true === $expired ) {
            $this->delete_expired( $network );
            return;
        }

        if ( ! $key ) {
            WP_CLI::error( 'Please specify transient key, or use --all or --expired.' );
        }

        $func = $network ? 'delete_site_transient' : 'delete_transient';

        if ( $func( $key ) ) {
            WP_CLI::success( 'Transient deleted.' );
        } else {
            $func = Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient';
            if ( $func( $key ) ) {
                WP_CLI::error( 'Transient was not deleted even though the transient appears to exist.' );
            } else {
                WP_CLI::warning( 'Transient was not deleted; however, the transient does not appear to exist.' );
            }
        }
    }

    /**
     * Determines the type of transients implementation.
     *
     * Indicates whether the transients API is using an object cache or the
     * database.
     *
     * For a more complete explanation of the transient cache, including the
     * network|site cache, please see docs for `wp transient`.
     *
     * ## EXAMPLES
     *
     *     $ wp transient type
     *     Transients are saved to the database.
     */
    public function type() {
        if ( wp_using_ext_object_cache() ) {
            $message = 'Transients are saved to the object cache.';
        } else {
            $message = 'Transients are saved to the database.';
        }

        WP_CLI::line( $message );
    }

    /**
     * Lists transients and their values.
     *
     * ## OPTIONS
     *
     * [--search=<pattern>]
     * : Use wildcards ( * and ? ) to match transient name.
     *
     * [--exclude=<pattern>]
     * : Pattern to exclude. Use wildcards ( * and ? ) to match transient name.
     *
     * [--network]
     * : Get the values of network|site transients. On single site, this is
     * a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     *
     * [--unserialize]
     * : Unserialize transient values in output.
     *
     * [--human-readable]
     * : Human-readable output for expirations.
     *
     * [--fields=<fields>]
     * : Limit the output to specific object fields.
     *
     * [--format=<format>]
     * : The serialization format for the value.
     * ---
     * default: table
     * options:
     *   - table
     *   - json
     *   - csv
     *   - count
     *   - yaml
     * ---
     *
     * ## AVAILABLE FIELDS
     *
     * This field will be displayed by default for each matching option:
     *
     * * name
     * * value
     * * expiration
     *
     * ## EXAMPLES
     *
     *     # List all transients
     *     $ wp transient list
    *      +------+-------+---------------+
    *      | name | value | expiration    |
    *      +------+-------+---------------+
    *      | foo  | bar   | 39 mins       |
    *      | foo2 | bar2  | no expiration |
    *      | foo3 | bar2  | expired       |
    *      | foo4 | bar4  | 4 hours       |
    *      +------+-------+---------------+
     *
     * @subcommand list
     */
    public function list_( $args, $assoc_args ) {
        global $wpdb;

        if ( wp_using_ext_object_cache() ) {
            WP_CLI::warning( 'Transients are stored in an external object cache, and this command only shows those stored in the database.' );
        }

        $network        = Utils\get_flag_value( $assoc_args, 'network', false );
        $unserialize    = Utils\get_flag_value( $assoc_args, 'unserialize', false );
        $human_readable = Utils\get_flag_value( $assoc_args, 'human-readable', false );

        $fields = array( 'name', 'value', 'expiration' );
        if ( isset( $assoc_args['fields'] ) ) {
            $fields = explode( ',', $assoc_args['fields'] );
        }

        $pattern = '%';
        $exclude = '';
        if ( isset( $assoc_args['search'] ) ) {
            $pattern = Utils\esc_like( $assoc_args['search'] );
            // Substitute wildcards.
            $pattern = str_replace(
                array( '*', '?' ),
                array( '%', '_' ),
                $pattern
            );
        }
        if ( isset( $assoc_args['exclude'] ) ) {
            $exclude = Utils\esc_like( $assoc_args['exclude'] );
            // Substitute wildcards.
            $exclude = str_replace(
                array( '*', '?' ),
                array( '%', '_' ),
                $exclude
            );
        }

        if ( $network ) {
            if ( is_multisite() ) {
                $where  = $wpdb->prepare(
                    'WHERE `meta_key` LIKE %s',
                    Utils\esc_like( '_site_transient_' ) . $pattern
                );
                $where .= $wpdb->prepare(
                    ' AND meta_key NOT LIKE %s',
                    Utils\esc_like( '_site_transient_timeout_' ) . '%'
                );
                if ( $exclude ) {
                    $where .= $wpdb->prepare(
                        ' AND meta_key NOT LIKE %s',
                        Utils\esc_like( '_site_transient_' ) . $exclude
                    );
                }

                $query = "SELECT `meta_key` as `name`, `meta_value` as `value` FROM {$wpdb->sitemeta} {$where}";
            } else {
                $where  = $wpdb->prepare(
                    'WHERE `option_name` LIKE %s',
                    Utils\esc_like( '_site_transient_' ) . $pattern
                );
                $where .= $wpdb->prepare(
                    ' AND option_name NOT LIKE %s',
                    Utils\esc_like( '_site_transient_timeout_' ) . '%'
                );
                if ( $exclude ) {
                    $where .= $wpdb->prepare(
                        ' AND option_name NOT LIKE %s',
                        Utils\esc_like( '_site_transient_' ) . $exclude
                    );
                }

                $query = "SELECT `option_name` as `name`, `option_value` as `value` FROM {$wpdb->options} {$where}";
            }
        } else {
            $where  = $wpdb->prepare(
                'WHERE `option_name` LIKE %s',
                Utils\esc_like( '_transient_' ) . $pattern
            );
            $where .= $wpdb->prepare(
                ' AND option_name NOT LIKE %s',
                Utils\esc_like( '_transient_timeout_' ) . '%'
            );
            if ( $exclude ) {
                $where .= $wpdb->prepare(
                    ' AND option_name NOT LIKE %s',
                    Utils\esc_like( '_transient_' ) . $exclude
                );
            }

            $query = "SELECT `option_name` as `name`, `option_value` as `value` FROM {$wpdb->options} {$where}";
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Prepared properly above.
        $results = $wpdb->get_results( $query );

        foreach ( $results as $result ) {
            $result->name       = str_replace( array( '_site_transient_', '_transient_' ), '', $result->name );
            $result->expiration = $this->get_transient_expiration( $result->name, $network, $human_readable );

            if ( $unserialize ) {
                $result->value = maybe_unserialize( $result->value );
            }
        }

        $formatter = new \WP_CLI\Formatter(
            $assoc_args,
            $fields
        );
        $formatter->display_items( $results );
    }

    /**
     * Get a nested value from a transient.
     *
     * ## OPTIONS
     *
     * <key>
     * : Key for the transient.
     *
     * <key-path>...
     * : The name(s) of the keys within the value to locate the value to pluck.
     *
     * [--format=<format>]
     * : The output format of the value.
     * ---
     * default: plaintext
     * options:
     *   - plaintext
     *   - json
     *   - yaml
     * ---
     *
     * [--network]
     * : Get the value of a network|site transient. On single site, this is
     * a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     */
    public function pluck( $args, $assoc_args ) {
        list( $key ) = $args;

        $func  = Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient';
        $value = $func( $key );

        if ( false === $value ) {
            WP_CLI::warning( 'Transient with key "' . $key . '" is not set.' );
            exit;
        }

        $key_path = array_map(
            function ( $key ) {
                if ( is_numeric( $key ) && ( (string) intval( $key ) === $key ) ) {
                    return (int) $key;
                }
                return $key;
            },
            array_slice( $args, 1 )
        );

        $traverser = new RecursiveDataStructureTraverser( $value );

        try {
            $value = $traverser->get( $key_path );
        } catch ( \Exception $e ) {
            die( 1 );
        }

        WP_CLI::print_value( $value, $assoc_args );
    }

    /**
     * Update a nested value from a transient.
     *
     * ## OPTIONS
     *
     * <action>
     * : Patch action to perform.
     * ---
     * options:
     *   - insert
     *   - update
     *   - delete
     * ---
     *
     * <key>
     * : Key for the transient.
     *
     * <key-path>...
     * : The name(s) of the keys within the value to locate the value to patch.
     *
     * [<value>]
     * : The new value. If omitted, the value is read from STDIN.
     *
     * [--format=<format>]
     * : The serialization format for the value.
     * ---
     * default: plaintext
     * options:
     *   - plaintext
     *   - json
     * ---
     *
     * [--expiration=<expiration>]
     * : Time until expiration, in seconds.
     *
     * [--network]
     * : Get the value of a network|site transient. On single site, this is
     * a specially-named cache key. On multisite, this is a global cache
     * (instead of local to the site).
     */
    public function patch( $args, $assoc_args ) {
        list( $action, $key ) = $args;
        $expiration           = (int) Utils\get_flag_value( $assoc_args, 'expiration', 0 );

        $read_func  = Utils\get_flag_value( $assoc_args, 'network' ) ? 'get_site_transient' : 'get_transient';
        $write_func = Utils\get_flag_value( $assoc_args, 'network' ) ? 'set_site_transient' : 'set_transient';

        $key_path = array_map(
            function ( $key ) {
                if ( is_numeric( $key ) && ( (string) intval( $key ) === $key ) ) {
                    return (int) $key;
                }

                return $key;
            },
            array_slice( $args, 2 )
        );

        if ( 'delete' === $action ) {
            $patch_value = null;
        } else {
            $stdin_value = Utils\has_stdin()
                ? trim( WP_CLI::get_value_from_arg_or_stdin( $args, -1 ) )
                : null;

            if ( ! empty( $stdin_value ) ) {
                $patch_value = WP_CLI::read_value( $stdin_value, $assoc_args );
            } elseif ( count( $key_path ) > 1 ) {
                $patch_value = WP_CLI::read_value( array_pop( $key_path ), $assoc_args );
            } else {
                $patch_value = null;
            }

            if ( null === $patch_value ) {
                WP_CLI::error( 'Please provide value to update.' );
            }
        }

        /* Need to make a copy of $current_value here as it is modified by reference */
        $old_value     = $read_func( $key );
        $current_value = $old_value;
        if ( is_object( $old_value ) ) {
            $current_value = clone $old_value;
        }

        $traverser = new RecursiveDataStructureTraverser( $current_value );

        try {
            $traverser->$action( $key_path, $patch_value );
        } catch ( \Exception $e ) {
            WP_CLI::error( $e->getMessage() );
        }

        $patched_value = $traverser->value();

        if ( $patched_value === $old_value ) {
            WP_CLI::success( "Value passed for transient '$key' is unchanged." );
        } else {
            $success = $write_func( $key, $patched_value, $expiration );
            if ( $success ) {
                WP_CLI::success( "Updated transient '$key'." );
            } else {
                WP_CLI::error( "Could not update transient '$key'." );
            }
        }
    }

    /**
     * Retrieves the expiration time.
     *
     * @param string $name              Transient name.
     * @param bool   $is_site_transient Optional. Whether this is a site transient. Default false.
     * @param bool   $human_readable    Optional. Whether to return the difference between now and the
     *                                  expiration time in a human-readable format. Default false.
     * @return string Expiration time string.
     */
    private function get_transient_expiration( $name, $is_site_transient = false, $human_readable = false ) {
        if ( $is_site_transient ) {
            if ( is_multisite() ) {
                $expiration = (int) get_site_option( '_site_transient_timeout_' . $name );
            } else {
                $expiration = (int) get_option( '_site_transient_timeout_' . $name );
            }
        } else {
            $expiration = (int) get_option( '_transient_timeout_' . $name );
        }

        if ( 0 === $expiration ) {
            return $human_readable ? 'never expires' : 'false';
        }

        if ( ! $human_readable ) {
            return $expiration;
        }

        $now = time();

        if ( $now > $expiration ) {
            return 'expired';
        }

        return human_time_diff( $now, $expiration );
    }

    /**
     * Deletes all expired transients.
     *
     * Only deletes the expired transients from the database.
     *
     * @param bool $network Whether to delete transients or network|site transients.
     */
    private function delete_expired( $network ) {
        global $wpdb;

        $count = 0;

        if ( ! $network ) {
            $count += $wpdb->query(
                $wpdb->prepare(
                    "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
                        WHERE a.option_name LIKE %s
                        AND a.option_name NOT LIKE %s
                        AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
                        AND b.option_value < %d",
                    Utils\esc_like( '_transient_' ) . '%',
                    Utils\esc_like( '_transient_timeout_' ) . '%',
                    time()
                )
            );
        } elseif ( ! is_multisite() ) {
                // Non-Multisite stores site transients in the options table.
                $count += $wpdb->query(
                    $wpdb->prepare(
                        "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
                            WHERE a.option_name LIKE %s
                            AND a.option_name NOT LIKE %s
                            AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )
                            AND b.option_value < %d",
                        Utils\esc_like( '_site_transient_' ) . '%',
                        Utils\esc_like( '_site_transient_timeout_' ) . '%',
                        time()
                    )
                );
        } else {
            // Multisite stores site transients in the sitemeta table.
            $count += $wpdb->query(
                $wpdb->prepare(
                    "DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b
                            WHERE a.meta_key LIKE %s
                            AND a.meta_key NOT LIKE %s
                            AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )
                            AND b.meta_value < %d",
                    Utils\esc_like( '_site_transient_' ) . '%',
                    Utils\esc_like( '_site_transient_timeout_' ) . '%',
                    time()
                )
            );
        }

        // The above queries delete the transient and the transient timeout
        // thus each transient is counted twice.
        $count = $count / 2;

        if ( $count > 0 ) {
            WP_CLI::success(
                sprintf(
                    '%d expired %s deleted from the database.',
                    $count,
                    Utils\pluralize( 'transient', $count )
                )
            );
        } else {
            WP_CLI::success( 'No expired transients found.' );
        }

        if ( wp_using_ext_object_cache() ) {
            WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.' );
        }
    }

    /**
     * Deletes all transients.
     *
     * Only deletes the transients from the database.
     *
     * @param bool $network Whether to delete transients or network|site transients.
     */
    private function delete_all( $network ) {
        global $wpdb;

        // To ensure proper count values we first delete all transients with a timeout
        // and then the remaining transients without a timeout.
        $count = 0;

        if ( ! $network ) {
            $deleted = $wpdb->query(
                $wpdb->prepare(
                    "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
                        WHERE a.option_name LIKE %s
                        AND a.option_name NOT LIKE %s
                        AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )",
                    Utils\esc_like( '_transient_' ) . '%',
                    Utils\esc_like( '_transient_timeout_' ) . '%'
                )
            );

            $count += $deleted / 2; // Ignore affected rows for timeouts.

            $count += $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM $wpdb->options WHERE option_name LIKE %s",
                    Utils\esc_like( '_transient_' ) . '%'
                )
            );
        } elseif ( ! is_multisite() ) {
                // Non-Multisite stores site transients in the options table.
                $deleted = $wpdb->query(
                    $wpdb->prepare(
                        "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b
                            WHERE a.option_name LIKE %s
                            AND a.option_name NOT LIKE %s
                            AND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )",
                        Utils\esc_like( '_site_transient_' ) . '%',
                        Utils\esc_like( '_site_transient_timeout_' ) . '%'
                    )
                );

                $count += $deleted / 2; // Ignore affected rows for timeouts.

                $count += $wpdb->query(
                    $wpdb->prepare(
                        "DELETE FROM $wpdb->options WHERE option_name LIKE %s",
                        Utils\esc_like( '_site_transient_' ) . '%'
                    )
                );
        } else {
            // Multisite stores site transients in the sitemeta table.
            $deleted = $wpdb->query(
                $wpdb->prepare(
                    "DELETE a, b FROM {$wpdb->sitemeta} a, {$wpdb->sitemeta} b
                            WHERE a.meta_key LIKE %s
                            AND a.meta_key NOT LIKE %s
                            AND b.meta_key = CONCAT( '_site_transient_timeout_', SUBSTRING( a.meta_key, 17 ) )",
                    Utils\esc_like( '_site_transient_' ) . '%',
                    Utils\esc_like( '_site_transient_timeout_' ) . '%'
                )
            );

            $count += $deleted / 2; // Ignore affected rows for timeouts.

            $count += $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM $wpdb->sitemeta WHERE meta_key LIKE %s",
                    Utils\esc_like( '_site_transient_' ) . '%'
                )
            );
        }

        if ( $count > 0 ) {
            WP_CLI::success(
                sprintf(
                    '%d %s deleted from the database.',
                    $count,
                    Utils\pluralize( 'transient', $count )
                )
            );
        } else {
            WP_CLI::success( 'No transients found.' );
        }

        if ( wp_using_ext_object_cache() ) {
            WP_CLI::warning( 'Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.' );
        }
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0233 ]--