delay(); $action = (string) filter_input(\INPUT_GET, 'action', \FILTER_DEFAULT); if ( ! $action) { return; } // for php54 foreach ([ 'Poll\\PollAction', 'Script\\ScriptAction', 'Style\\StyleAction', 'Ping\\PingAction', 'ServerInfo\\ServerInfoPublicIpv4Action', 'ServerInfo\\ServerInfoPublicIpv6Action', 'PhpInfo\\PhpInfoLatestPhpVersionAction', 'PhpInfoDetail\\PhpInfoDetailAction', 'Updater\\UpdaterActionVersion', 'Updater\\UpdaterActionUpdate', 'ServerBenchmark\\ServerBenchmarkPerformanceAction', 'ServerBenchmark\\ServerBenchmarkServersAction', 'Location\\LocationIpv4Action', 'Nodes\\NodesAction', ] as $fn) { $class = "\\InnStudio\\Prober\\Components\\{$fn}"; (new $class())->render($action); } (new RestResponse()) ->setStatus(StatusCode::BAD_REQUEST) ->end(); } } namespace InnStudio\Prober\Components\PhpInfo; class PhpInfoConstants { const ID = 'phpInfo'; } namespace InnStudio\Prober\Components\PhpInfo; use InnStudio\Prober\Components\Config\ConfigApi; use InnStudio\Prober\Components\Rest\RestResponse; use InnStudio\Prober\Components\Rest\StatusCode; use InnStudio\Prober\Components\UserConfig\UserConfigApi; final class PhpInfoLatestPhpVersionAction { public function render($action) { $id = PhpInfoConstants::ID; if ('latestPhpVersion' !== $action) { return; } $response = new RestResponse(); if (UserConfigApi::isDisabled($id)) { $response ->setStatus(StatusCode::FORBIDDEN) ->end(); } $content = file_get_contents('https://www.php.net/releases/?json'); if ( ! $content) { $response ->setStatus(StatusCode::NO_CONTENT) ->end(); } $versions = json_decode($content, true); if ( ! $versions) { $response ->setStatus(StatusCode::NO_CONTENT) ->end(); } $version = isset($versions[ConfigApi::$config['LATEST_PHP_STABLE_VERSION']]['version']) ? $versions[ConfigApi::$config['LATEST_PHP_STABLE_VERSION']]['version'] : ''; if ( ! $version) { $response ->setStatus(StatusCode::NO_CONTENT) ->end(); } $response ->setData([ 'version' => $version, 'date' => $versions[ConfigApi::$config['LATEST_PHP_STABLE_VERSION']]['date'], ]) ->end(); } } namespace InnStudio\Prober\Components\PhpInfo; use InnStudio\Prober\Components\UserConfig\UserConfigApi; final class PhpInfoPoll { public function render() { $id = PhpInfoConstants::ID; if (UserConfigApi::isDisabled($id)) { return [ $id => null, ]; } return [ $id => [ 'version' => \PHP_VERSION, 'sapi' => \PHP_SAPI, 'displayErrors' => (bool) \ini_get('display_errors'), 'errorReporting' => (int) \ini_get('error_reporting'), 'memoryLimit' => (string) \ini_get('memory_limit'), 'postMaxSize' => (string) \ini_get('post_max_size'), 'uploadMaxFilesize' => (string) \ini_get('upload_max_filesize'), 'maxInputVars' => (int) \ini_get('max_input_vars'), 'maxExecutionTime' => (int) \ini_get('max_execution_time'), 'defaultSocketTimeout' => (int) \ini_get('default_socket_timeout'), 'allowUrlFopen' => (bool) \ini_get('allow_url_fopen'), 'smtp' => (bool) \ini_get('SMTP'), 'disableFunctions' => UserConfigApi::isDisabled('phpDisabledFunctions') ? [] : array_filter(explode(',', (string) \ini_get('disable_functions'))), 'disableClasses' => UserConfigApi::isDisabled('phpDisabledClasses') ? [] : array_filter(explode(',', (string) \ini_get('disable_classes'))), ], ]; } } namespace InnStudio\Prober\Components\Events; final class EventsApi { private static $events = []; private static $PRIORITY_ID = 'priority'; private static $CALLBACK_ID = 'callback'; public static function on($name, $callback, $priority = 10) { if ( ! isset(self::$events[$name])) { self::$events[$name] = []; } self::$events[$name][] = [ self::$PRIORITY_ID => $priority, self::$CALLBACK_ID => $callback, ]; } public static function emit() { $args = \func_get_args(); $name = $args[0]; $return = isset($args[1]) ? $args[1] : null; unset($args[0], $args[1]); $events = isset(self::$events[$name]) ? self::$events[$name] : false; if ( ! $events) { return $return; } $sortArr = []; foreach ($events as $k => $filter) { $sortArr[$k] = $filter[self::$PRIORITY_ID]; } array_multisort($sortArr, $events); foreach ($events as $filter) { $return = \call_user_func_array($filter[self::$CALLBACK_ID], [$return, $args]); } return $return; } } namespace InnStudio\Prober\Components\PhpInfoDetail; use InnStudio\Prober\Components\Rest\RestResponse; use InnStudio\Prober\Components\Rest\StatusCode; use InnStudio\Prober\Components\UserConfig\UserConfigApi; final class PhpInfoDetailAction { public function render($action) { $id = PhpInfoDetailConstants::ID; if ($action !== $id) { return; } if (UserConfigApi::isDisabled($id)) { (new RestResponse()) ->setStatus(StatusCode::FORBIDDEN) ->end(); } phpinfo(); exit; } } namespace InnStudio\Prober\Components\PhpInfoDetail; class PhpInfoDetailConstants { const ID = 'phpInfoDetail'; } namespace InnStudio\Prober\Components\Ping; class PingConstants { const ID = 'ping'; } namespace InnStudio\Prober\Components\Ping; use InnStudio\Prober\Components\Rest\RestResponse; use InnStudio\Prober\Components\Rest\StatusCode; use InnStudio\Prober\Components\UserConfig\UserConfigApi; final class PingAction { public function render($action) { $id = PingConstants::ID; if ($action !== $id) { return; } $response = new RestResponse(); if (UserConfigApi::isDisabled($id)) { $response ->setStatus(StatusCode::NOT_IMPLEMENTED) ->end(); } $response ->setData([ 'time' => \defined('XPROBER_TIMER') ? microtime(true) - XPROBER_TIMER : 0, ]) ->end(); } } namespace InnStudio\Prober\Components\PhpExtensions; class PhpExtensionsConstants { const ID = 'phpExtensions'; } namespace InnStudio\Prober\Components\PhpExtensions; use InnStudio\Prober\Components\UserConfig\UserConfigApi; final class PhpExtensionsPoll { public function render() { $id = PhpExtensionsConstants::ID; if (UserConfigApi::isDisabled($id)) { return [ $id => null, ]; } $jitEnabled = false; if (\function_exists('opcache_get_status')) { $status = opcache_get_status(); if (isset($status['jit']['enabled']) && true === $status['jit']['enabled']) { $jitEnabled = true; } } return [ $id => [ 'redis' => \extension_loaded('redis') && class_exists('Redis'), 'sqlite3' => \extension_loaded('sqlite3') && class_exists('Sqlite3'), 'memcache' => \extension_loaded('memcache') && class_exists('Memcache'), 'memcached' => \extension_loaded('memcached') && class_exists('Memcached'), 'opcache' => \function_exists('opcache_get_status'), 'opcacheEnabled' => $this->isOpcEnabled(), 'opcacheJitEnabled' => $jitEnabled, 'swoole' => \extension_loaded('swoole') && \function_exists('swoole_version'), 'imagick' => \extension_loaded('imagick') && class_exists('Imagick'), 'gmagick' => \extension_loaded('gmagick'), 'exif' => \extension_loaded('exif') && \function_exists('exif_imagetype'), 'fileinfo' => \extension_loaded('fileinfo'), 'simplexml' => \extension_loaded('simplexml'), 'sockets' => \extension_loaded('sockets') && \function_exists('socket_accept'), 'mysqli' => \extension_loaded('mysqli') && class_exists('mysqli'), 'zip' => \extension_loaded('zip') && class_exists('ZipArchive'), 'mbstring' => \extension_loaded('mbstring') && \function_exists('mb_substr'), 'phalcon' => \extension_loaded('phalcon'), 'xdebug' => \extension_loaded('xdebug'), 'zendOptimizer' => \function_exists('zend_optimizer_version'), 'ionCube' => \extension_loaded('ioncube loader'), 'sourceGuardian' => \extension_loaded('sourceguardian'), 'ldap' => \function_exists('ldap_connect'), 'curl' => \function_exists('curl_init'), 'loadedExtensions' => UserConfigApi::isDisabled('phpExtensionsLoaded') ? [] : get_loaded_extensions(), ], ]; } private function isOpcEnabled() { $isOpcEnabled = \function_exists('opcache_get_configuration'); if ($isOpcEnabled) { $isOpcEnabled = opcache_get_configuration(); $isOpcEnabled = isset($isOpcEnabled['directives']['opcache.enable']) && true === $isOpcEnabled['directives']['opcache.enable']; } return $isOpcEnabled; } } namespace InnStudio\Prober\Components\Footer; use InnStudio\Prober\Components\Events\EventsApi; final class Footer { private $ID = 'footer'; public function __construct() { EventsApi::on('conf', function (array $conf) { $conf[$this->ID] = [ 'memUsage' => memory_get_usage(), 'time' => microtime(true) - (\defined('XPROBER_TIMER') ? XPROBER_TIMER : 0), ]; return $conf; }, \PHP_INT_MAX); } } namespace InnStudio\Prober\Components\DiskUsage; class DiskUsageConstants { const ID = 'diskUsage'; } namespace InnStudio\Prober\Components\DiskUsage; use InnStudio\Prober\Components\UserConfig\UserConfigApi; use InnStudio\Prober\Components\Utils\UtilsDisk; final class DiskUsagePoll { public function render() { $id = DiskUsageConstants::ID; if (UserConfigApi::isDisabled($id)) { return [ $id => null, ]; } return [ $id => [ 'items' => UtilsDisk::getItems(), ], ]; } } namespace InnStudio\Prober\Components\Location; class LocationConstants { const ID = 'locationIpv4'; const FEATURE_LOCATION = 'locationIpv4'; } namespace InnStudio\Prober\Components\Location; use InnStudio\Prober\Components\Rest\RestResponse; use InnStudio\Prober\Components\Rest\StatusCode; use InnStudio\Prober\Components\UserConfig\UserConfigApi; use InnStudio\Prober\Components\Utils\UtilsLocation; final class LocationIpv4Action { public function render($action) { if (LocationConstants::ID !== $action) { return; } $response = new RestResponse(); if (UserConfigApi::isDisabled(LocationConstants::FEATURE_LOCATION)) { $response ->setStatus(StatusCode::FORBIDDEN) ->end(); } $ip = filter_input(\INPUT_GET, 'ip', \FILTER_VALIDATE_IP, [ 'flags' => \FILTER_FLAG_IPV4, ]); if ( ! $ip) { $response ->setStatus(StatusCode::BAD_REQUEST) ->end(); } $response ->setData(UtilsLocation::getLocation($ip)) ->end(); } } namespace InnStudio\Prober\Components\ServerStatus; class ServerStatusConstants { const ID = 'serverStatus'; } namespace InnStudio\Prober\Components\ServerStatus; use InnStudio\Prober\Components\UserConfig\UserConfigApi; use InnStudio\Prober\Components\Utils\UtilsCpu; use InnStudio\Prober\Components\Utils\UtilsMemory; final class ServerStatusPoll { public function render() { $id = ServerStatusConstants::ID; if (UserConfigApi::isDisabled($id)) { return [ $id => null, ]; } return [ $id => [ 'sysLoad' => UtilsCpu::getLoadAvg(), 'cpuUsage' => UtilsCpu::getUsage(), 'memRealUsage' => [ 'value' => UtilsMemory::getMemoryUsage('MemRealUsage'), 'max' => UtilsMemory::getMemoryUsage('MemTotal'), ], 'memBuffers' => [ 'value' => UtilsMemory::getMemoryUsage('Buffers'), 'max' => UtilsMemory::getMemoryUsage('MemUsage'), ], 'memCached' => [ 'value' => UtilsMemory::getMemoryUsage('Cached'), 'max' => UtilsMemory::getMemoryUsage('MemUsage'), ], 'swapUsage' => [ 'value' => UtilsMemory::getMemoryUsage('SwapUsage'), 'max' => UtilsMemory::getMemoryUsage('SwapTotal'), ], 'swapCached' => [ 'value' => UtilsMemory::getMemoryUsage('SwapCached'), 'max' => UtilsMemory::getMemoryUsage('SwapUsage'), ], ], ]; } } namespace InnStudio\Prober\Components\Timezone; final class Timezone { public function __construct() { if ( ! \ini_get('date.timezone')) { date_default_timezone_set('GMT'); } } } namespace InnStudio\Prober\Components\Rest; final class RestResponse { private $data; private $headers = []; private $status = StatusCode::OK; public function __construct($data = null, $status = StatusCode::OK, array $headers = []) { $this->setData($data); $this->setStatus($status); $this->setHeaders($headers); } public function setHeader($key, $value, $replace = true) { if ($replace || ! isset($this->headers[$key])) { $this->headers[$key] = $value; } else { $this->headers[$key] .= ", {$value}"; } } public function setHeaders(array $headers) { $this->headers = $headers; } public function getHeaders() { return $this->headers; } public function setStatus($status) { $this->status = $status; return $this; } public function getStatus() { return $this->status; } public function setData($data) { $this->data = $data; return $this; } public function getData() { return $this->data; } public function json() { // header('Content-Type: application/json'); // header('Expires: 0'); // header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // header('Cache-Control: no-store, no-cache, must-revalidate'); // header('Pragma: no-cache'); // echo $this->toJson(); return $this; } public function end() { $this->httpResponseCode($this->status); header('Content-Type: application/json'); header('Expires: 0'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-store, no-cache, must-revalidate'); header('Pragma: no-cache'); if (null !== $this->data) { echo $this->toJson(); } exit; } private function toJson() { $data = $this->getData(); if (null === $data) { return ''; } return json_encode($data, \JSON_UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES); } private function httpResponseCode($code) { if (\function_exists('http_response_code')) { return http_response_code($code); } $statusCode = [ 100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => '(Unused)', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => "I'm a teapot", 419 => 'Authentication Timeout', 420 => 'Enhance Your Calm', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 424 => 'Method Failure', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 444 => 'No Response', 449 => 'Retry With', 450 => 'Blocked by Windows Parental Controls', 451 => 'Unavailable For Legal Reasons', 494 => 'Request Header Too Large', 495 => 'Cert Error', 496 => 'No Cert', 497 => 'HTTP to HTTPS', 499 => 'Client Closed Request', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 509 => 'Bandwidth Limit Exceeded', 510 => 'Not Extended', 511 => 'Network Authentication Required', 598 => 'Network read timeout error', 599 => 'Network connect timeout error', ]; $msg = isset($statusCode[$code]) ? $statusCode[$code] : 'Unknow error'; $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); header("{$protocol} {$code} {$msg}"); } } namespace InnStudio\Prober\Components\Rest; final class StatusCode { const CONTINUE = 100; const SWITCHING_PROTOCOLS = 101; const PROCESSING = 102; // WEBDAV;_RFC_2518 const OK = 200; const CREATED = 201; const ACCEPTED = 202; const NON_AUTHORITATIVE_INFORMATION = 203; // SINCE_HTTP/1.1 const NO_CONTENT = 204; const RESET_CONTENT = 205; const PARTIAL_CONTENT = 206; const MULTI_STATUS = 207; // WEBDAV;_RFC_4918 const ALREADY_REPORTED = 208; // WEBDAV;_RFC_5842 const IM_USED = 226; // RFC_3229 const MULTIPLE_CHOICES = 300; const MOVED_PERMANENTLY = 301; const FOUND = 302; const SEE_OTHER = 303; // SINCE_HTTP/1.1 const NOT_MODIFIED = 304; const USE_PROXY = 305; // SINCE_HTTP/1.1 const SWITCH_PROXY = 306; const TEMPORARY_REDIRECT = 307; // SINCE_HTTP/1.1 const PERMANENT_REDIRECT = 308; // APPROVED_AS_EXPERIMENTAL_RFC const BAD_REQUEST = 400; const UNAUTHORIZED = 401; const PAYMENT_REQUIRED = 402; const FORBIDDEN = 403; const NOT_FOUND = 404; const METHOD_NOT_ALLOWED = 405; const NOT_ACCEPTABLE = 406; const PROXY_AUTHENTICATION_REQUIRED = 407; const REQUEST_TIMEOUT = 408; const CONFLICT = 409; const GONE = 410; const LENGTH_REQUIRED = 411; const PRECONDITION_FAILED = 412; const REQUEST_ENTITY_TOO_LARGE = 413; const REQUEST_URI_TOO_LONG = 414; const UNSUPPORTED_MEDIA_TYPE = 415; const REQUESTED_RANGE_NOT_SATISFIABLE = 416; const EXPECTATION_FAILED = 417; const I_AM_A_TEAPOT = 418; const AUTHENTICATION_TIMEOUT = 419; // NOT_IN_RFC_2616 const ENHANCE_YOUR_CALM = 420; // TWITTER const METHOD_FAILURE = 420; // SPRING_FRAMEWORK const UNPROCESSABLE_ENTITY = 422; // WEBDAV;_RFC_4918 const LOCKED = 423; // WEBDAV;_RFC_4918 const FAILED_DEPENDENCY = 424; // WEBDAV const UNORDERED_COLLECTION = 425; // INTERNET_DRAFT const UPGRADE_REQUIRED = 426; // RFC_2817 const PRECONDITION_REQUIRED = 428; // RFC_6585 const TOO_MANY_REQUESTS = 429; // RFC_6585 const REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC_6585 const NO_RESPONSE = 444; // NGINX const RETRY_WITH = 449; // MICROSOFT const BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS = 450; // MICROSOFT const REDIRECT = 451; // MICROSOFT const UNAVAILABLE_FOR_LEGAL_REASONS = 451; // INTERNET_DRAFT const REQUEST_HEADER_TOO_LARGE = 494; // NGINX const CERT_ERROR = 495; // NGINX const NO_CERT = 496; // NGINX const HTTP_TO_HTTPS = 497; // NGINX const CLIENT_CLOSED_REQUEST = 499; // NGINX const INTERNAL_SERVER_ERROR = 500; const NOT_IMPLEMENTED = 501; const BAD_GATEWAY = 502; const SERVICE_UNAVAILABLE = 503; const GATEWAY_TIMEOUT = 504; const HTTP_VERSION_NOT_SUPPORTED = 505; const VARIANT_ALSO_NEGOTIATES = 506; // RFC_2295 const INSUFFICIENT_STORAGE = 507; // WEBDAV;_RFC_4918 const LOOP_DETECTED = 508; // WEBDAV;_RFC_5842 const BANDWIDTH_LIMIT_EXCEEDED = 509; // APACHE_BW/LIMITED_EXTENSION const NOT_EXTENDED = 510; // RFC_2774 const NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC_6585 const NETWORK_READ_TIMEOUT_ERROR = 598; // UNKNOWN const NETWORK_CONNECT_TIMEOUT_ERROR = 599; // Unknown } namespace InnStudio\Prober\Components\Poll; use InnStudio\Prober\Components\Rest\RestResponse; final class PollAction extends PoolConstants { public function render($action) { if (PoolConstants::ID !== $action) { return; } $data = []; foreach ([ 'Config\\ConfigPoll', 'UserConfig\\UserConfigPoll', 'PhpInfo\\PhpInfoPoll', 'Database\\DatabasePoll', 'MyInfo\\MyInfoPoll', 'DiskUsage\\DiskUsagePoll', 'PhpExtensions\\PhpExtensionsPoll', 'NetworkStats\\NetworkStatsPoll', 'ServerStatus\\ServerStatusPoll', 'ServerInfo\\ServerInfoPoll', 'Nodes\\NodesPoll', 'TemperatureSensor\\TemperatureSensorPoll', 'ServerBenchmark\\ServerBenchmarkPoll', ] as $fn) { $class = "\\InnStudio\\Prober\\Components\\{$fn}"; $data = array_merge($data, (new $class())->render()); } (new RestResponse()) ->setData($data) ->end(); } } namespace InnStudio\Prober\Components\Poll; class PoolConstants { const ID = 'poll'; } namespace InnStudio\Prober\Components\MyInfo; class MyInfoConstants { const ID = 'myInfo'; } namespace InnStudio\Prober\Components\MyInfo; use InnStudio\Prober\Components\UserConfig\UserConfigApi; use InnStudio\Prober\Components\Utils\UtilsClientIp; final class MyInfoPoll { public function render() { $id = MyInfoConstants::ID; if (UserConfigApi::isDisabled($id)) { return [ $id => null, ]; } return [ $id => [ 'phpLanguage' => isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '-', 'ipv4' => UtilsClientIp::getV4(), 'ipv6' => UtilsClientIp::getV6(), ], ]; } } namespace InnStudio\Prober\Components\Bootstrap; use InnStudio\Prober\Components\Action\Action; use InnStudio\Prober\Components\Timezone\Timezone; final class Bootstrap { public static $dir; public function __construct($dir) { error_reporting(\E_ALL); self::$dir = $dir; new Timezone(); new Action(); new Render(); } } namespace InnStudio\Prober\Components\Bootstrap; class BootstrapConstants { const ID = 'bootstrap'; } namespace InnStudio\Prober\Components\Bootstrap; use InnStudio\Prober\Components\Config\ConfigApi; use InnStudio\Prober\Components\WindowConfig\WindowConfigApi; final class Render { public function __construct() { if (\defined('XPROBER_IS_DEV') && XPROBER_IS_DEV) { return; } $appName = ConfigApi::$config['APP_NAME']; $version = ConfigApi::$config['APP_VERSION']; $loadScript = \defined('XPROBER_IS_DEV') && XPROBER_IS_DEV ? '' : ""; $loadStyle = \defined('XPROBER_IS_DEV') && XPROBER_IS_DEV ? '' : ""; $globalConfig = WindowConfigApi::getGlobalConfig(); echo <<
De?(P.sortIndex=oe,s(I,P),u(L)===null&&P===u(I)&&(qe?(Ne(at),at=-1):qe=!0,j(b,oe-De))):(P.sortIndex=H,s(L,P),He||Qe||(He=!0,ee||(ee=!0,st()))),P},i.unstable_shouldYield=g,i.unstable_wrapCallback=function(P){var ue=ie;return function(){var oe=ie;ie=ue;try{return P.apply(this,arguments)}finally{ie=oe}}},typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())})()}(nd)),nd}var Cv;function I1(){return Cv||(Cv=1,td.exports=X1()),td.exports}var ad={exports:{}},Nt={},Mv;function Q1(){if(Mv)return Nt;Mv=1;/**
* @license React
* react-dom.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/return function(){function i(){}function r(R){return""+R}function s(R,O,L){var I=3