diff --git a/.gitignore b/.gitignore index 2ee60b4c4..4ada49d1a 100644 --- a/.gitignore +++ b/.gitignore @@ -339,9 +339,6 @@ MaiBot.code-workspace src/chat/planner_actions/planner (2).py rust_video/Cargo.lock .claude/settings.local.json -/package-lock.json -/package.json +package-lock.json +package.json src/chat/planner_actions/新建 文本文档.txt -# WebUI不忽略 -!/webui/ -!/webui/** diff --git a/.venv311/Include/site/python3.11/greenlet/greenlet.h b/.venv311/Include/site/python3.11/greenlet/greenlet.h deleted file mode 100644 index d02a16e43..000000000 --- a/.venv311/Include/site/python3.11/greenlet/greenlet.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */ - -/* Greenlet object interface */ - -#ifndef Py_GREENLETOBJECT_H -#define Py_GREENLETOBJECT_H - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is deprecated and undocumented. It does not change. */ -#define GREENLET_VERSION "1.0.0" - -#ifndef GREENLET_MODULE -#define implementation_ptr_t void* -#endif - -typedef struct _greenlet { - PyObject_HEAD - PyObject* weakreflist; - PyObject* dict; - implementation_ptr_t pimpl; -} PyGreenlet; - -#define PyGreenlet_Check(op) (op && PyObject_TypeCheck(op, &PyGreenlet_Type)) - - -/* C API functions */ - -/* Total number of symbols that are exported */ -#define PyGreenlet_API_pointers 12 - -#define PyGreenlet_Type_NUM 0 -#define PyExc_GreenletError_NUM 1 -#define PyExc_GreenletExit_NUM 2 - -#define PyGreenlet_New_NUM 3 -#define PyGreenlet_GetCurrent_NUM 4 -#define PyGreenlet_Throw_NUM 5 -#define PyGreenlet_Switch_NUM 6 -#define PyGreenlet_SetParent_NUM 7 - -#define PyGreenlet_MAIN_NUM 8 -#define PyGreenlet_STARTED_NUM 9 -#define PyGreenlet_ACTIVE_NUM 10 -#define PyGreenlet_GET_PARENT_NUM 11 - -#ifndef GREENLET_MODULE -/* This section is used by modules that uses the greenlet C API */ -static void** _PyGreenlet_API = NULL; - -# define PyGreenlet_Type \ - (*(PyTypeObject*)_PyGreenlet_API[PyGreenlet_Type_NUM]) - -# define PyExc_GreenletError \ - ((PyObject*)_PyGreenlet_API[PyExc_GreenletError_NUM]) - -# define PyExc_GreenletExit \ - ((PyObject*)_PyGreenlet_API[PyExc_GreenletExit_NUM]) - -/* - * PyGreenlet_New(PyObject *args) - * - * greenlet.greenlet(run, parent=None) - */ -# define PyGreenlet_New \ - (*(PyGreenlet * (*)(PyObject * run, PyGreenlet * parent)) \ - _PyGreenlet_API[PyGreenlet_New_NUM]) - -/* - * PyGreenlet_GetCurrent(void) - * - * greenlet.getcurrent() - */ -# define PyGreenlet_GetCurrent \ - (*(PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM]) - -/* - * PyGreenlet_Throw( - * PyGreenlet *greenlet, - * PyObject *typ, - * PyObject *val, - * PyObject *tb) - * - * g.throw(...) - */ -# define PyGreenlet_Throw \ - (*(PyObject * (*)(PyGreenlet * self, \ - PyObject * typ, \ - PyObject * val, \ - PyObject * tb)) \ - _PyGreenlet_API[PyGreenlet_Throw_NUM]) - -/* - * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args) - * - * g.switch(*args, **kwargs) - */ -# define PyGreenlet_Switch \ - (*(PyObject * \ - (*)(PyGreenlet * greenlet, PyObject * args, PyObject * kwargs)) \ - _PyGreenlet_API[PyGreenlet_Switch_NUM]) - -/* - * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent) - * - * g.parent = new_parent - */ -# define PyGreenlet_SetParent \ - (*(int (*)(PyGreenlet * greenlet, PyGreenlet * nparent)) \ - _PyGreenlet_API[PyGreenlet_SetParent_NUM]) - -/* - * PyGreenlet_GetParent(PyObject* greenlet) - * - * return greenlet.parent; - * - * This could return NULL even if there is no exception active. - * If it does not return NULL, you are responsible for decrementing the - * reference count. - */ -# define PyGreenlet_GetParent \ - (*(PyGreenlet* (*)(PyGreenlet*)) \ - _PyGreenlet_API[PyGreenlet_GET_PARENT_NUM]) - -/* - * deprecated, undocumented alias. - */ -# define PyGreenlet_GET_PARENT PyGreenlet_GetParent - -# define PyGreenlet_MAIN \ - (*(int (*)(PyGreenlet*)) \ - _PyGreenlet_API[PyGreenlet_MAIN_NUM]) - -# define PyGreenlet_STARTED \ - (*(int (*)(PyGreenlet*)) \ - _PyGreenlet_API[PyGreenlet_STARTED_NUM]) - -# define PyGreenlet_ACTIVE \ - (*(int (*)(PyGreenlet*)) \ - _PyGreenlet_API[PyGreenlet_ACTIVE_NUM]) - - - - -/* Macro that imports greenlet and initializes C API */ -/* NOTE: This has actually moved to ``greenlet._greenlet._C_API``, but we - keep the older definition to be sure older code that might have a copy of - the header still works. */ -# define PyGreenlet_Import() \ - { \ - _PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \ - } - -#endif /* GREENLET_MODULE */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_GREENLETOBJECT_H */ diff --git a/.venv311/Include/site/python3.11/igraph/igraphmodule_api.h b/.venv311/Include/site/python3.11/igraph/igraphmodule_api.h deleted file mode 100644 index 8ab364b50..000000000 --- a/.venv311/Include/site/python3.11/igraph/igraphmodule_api.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- mode: C -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* - IGraph library. - Copyright (C) 2006-2023 Tamas Nepusz - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - -*/ - -#ifndef Py_IGRAPHMODULE_H -#define Py_IGRAPHMODULE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* C API functions */ -#define PyIGraph_FromCGraph_NUM 0 -#define PyIGraph_FromCGraph_RETURN PyObject* -#define PyIGraph_FromCGraph_PROTO (igraph_t *graph) - -#define PyIGraph_ToCGraph_NUM 1 -#define PyIGraph_ToCGraph_RETURN igraph_t* -#define PyIGraph_ToCGraph_PROTO (PyObject *graph) - -/* Total number of C API pointers */ -#define PyIGraph_API_pointers 2 - -#ifdef IGRAPH_MODULE - /* This section is used when compiling igraphmodule.c */ - static PyIGraph_FromCGraph_RETURN PyIGraph_FromCGraph PyIGraph_FromCGraph_PROTO; - static PyIGraph_ToCGraph_RETURN PyIGraph_ToCGraph PyIGraph_ToCGraph_PROTO; -#else - /* This section is used in modules that use igraph's API */ - static void** PyIGraph_API; -# define PyIGraph_FromCGraph \ - (*(PyIGraph_FromCGraph_RETURN (*)PyIGraph_FromCGraph_PROTO) \ - PyIGraph_API[PyIGraph_FromCGraph_NUM]) -# define PyIGraph_ToCGraph \ - (*(PyIGraph_ToCGraph_RETURN (*)PyIGraph_ToCGraph_PROTO) \ - PyIGraph_API[PyIGraph_ToCGraph_NUM]) - - /* Return -1 and set exception on error, 0 on success */ - static int import_igraph(void) { - PyIGraph_API = (void **)PyCapsule_Import("igraph._igraph._C_API", 0); - return (PyIGraph_API != NULL) ? 0 : -1; - } - -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !defined(Py_IGRAPHMODULE_H) */ diff --git a/.venv311/Scripts/Activate.ps1 b/.venv311/Scripts/Activate.ps1 deleted file mode 100644 index dbbf985cb..000000000 --- a/.venv311/Scripts/Activate.ps1 +++ /dev/null @@ -1,502 +0,0 @@ -<# -.Synopsis -Activate a Python virtual environment for the current PowerShell session. - -.Description -Pushes the python executable for a virtual environment to the front of the -$Env:PATH environment variable and sets the prompt to signify that you are -in a Python virtual environment. Makes use of the command line switches as -well as the `pyvenv.cfg` file values present in the virtual environment. - -.Parameter VenvDir -Path to the directory that contains the virtual environment to activate. The -default value for this is the parent of the directory that the Activate.ps1 -script is located within. - -.Parameter Prompt -The prompt prefix to display when this virtual environment is activated. By -default, this prompt is the name of the virtual environment folder (VenvDir) -surrounded by parentheses and followed by a single space (ie. '(.venv) '). - -.Example -Activate.ps1 -Activates the Python virtual environment that contains the Activate.ps1 script. - -.Example -Activate.ps1 -Verbose -Activates the Python virtual environment that contains the Activate.ps1 script, -and shows extra information about the activation as it executes. - -.Example -Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv -Activates the Python virtual environment located in the specified location. - -.Example -Activate.ps1 -Prompt "MyPython" -Activates the Python virtual environment that contains the Activate.ps1 script, -and prefixes the current prompt with the specified string (surrounded in -parentheses) while the virtual environment is active. - -.Notes -On Windows, it may be required to enable this Activate.ps1 script by setting the -execution policy for the user. You can do this by issuing the following PowerShell -command: - -PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - -For more information on Execution Policies: -https://go.microsoft.com/fwlink/?LinkID=135170 - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove VIRTUAL_ENV_PROMPT altogether. - if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { - Remove-Item -Path env:VIRTUAL_ENV_PROMPT - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0, 1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} -else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} -else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } - $env:VIRTUAL_ENV_PROMPT = $Prompt -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" - -# SIG # Begin signature block -# MIIvIwYJKoZIhvcNAQcCoIIvFDCCLxACAQExDzANBglghkgBZQMEAgEFADB5Bgor -# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk -# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCE8MwggWQMIIDeKADAgECAhAFmxtXno4h -# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK -# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV -# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z -# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ -# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 -# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z -# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ -# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s -# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL -# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb -# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 -# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c -# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx -# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 -# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL -# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud -# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf -# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk -# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS -# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK -# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB -# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp -# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg -# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri -# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 -# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 -# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 -# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H -# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G -# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ -# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 -# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla -# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE -# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz -# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C -# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce -# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da -# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T -# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA -# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh -# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM -# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z -# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 -# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY -# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP -# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T -# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD -# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG -# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY -# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj -# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV -# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU -# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN -# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry -# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL -# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf -# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh -# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh -# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV -# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j -# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH -# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC -# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l -# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW -# eE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0GCSqGSIb3DQEBCwUA -# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE -# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz -# ODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1MjM1OTU5WjB8MQsw -# CQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQHEwlCZWF2ZXJ0b24x -# IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQDExpQ -# eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -# ADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiSYgDFfwhjQy89koM7 -# uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi0GGAZUegEAeRlSXx -# xhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN16yS8skFa3IHyvWdb -# D9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGuppxcia6a7xCyKoOA -# GjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu352diDY+iCMpk9Zanm -# SjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0ZFYKeb6BLA66d2GA -# LwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oERzTzEiV6nCO1M3U1 -# HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZI7IWe7JKhHohqKuc -# eQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16xot2KVPdfyPAWd81w -# tZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapPUnwo8ygflJJ74J+B -# Yxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3ZIly+qIqDAgMBAAGj -# ggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4E -# FgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM -# MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp -# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI -# QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v -# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex -# LmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v -# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUF -# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6 -# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu -# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZI -# hvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcWTiNc2rskrNLrfH1N -# s0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+VVzxC88pOEvz68nA -# 82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfLIJQsAHBla0i7QRF2 -# de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izWOXM95BSkFSKdE45O -# q3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86WmjRUqbrnvdyR2yd -# I5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+W1scCpnA8YTs2d50 -# jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM58WEDkbeoriDk3hxU -# 8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMfZOm5cuclMnUHs2uq -# rRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw/TKqVL4Oaz3bkMSs -# M46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3r7bjyHTxOgqxRCVa -# 18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VHxaZg2unjHY3rMYIa -# tjCCGrICAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu -# Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT -# QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM0NHdMA0GCWCGSAFl -# AwQCAQUAoIHIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC -# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBnAZ6P7YvTwq0fbF62 -# o7E75R0LxsW5OtyYiFESQckLhjBcBgorBgEEAYI3AgEMMU4wTKBGgEQAQgB1AGkA -# bAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAxAC4AOQBfADIAMAAyADQA -# MAA0ADAAMgAuADAAMqECgAAwDQYJKoZIhvcNAQEBBQAEggIAg5wQO5NiKFirm9vr -# 1//X5G4t+z318Uagu8vJT/vTjkMTau86CF+SwP3pqC1H2ZMUyVYmVHae5dswKAMR -# hHY1VJV/0lJI+LdYcaxHI/WYzaFLbDrQI/Mty5cabjveG6geMlcJG4nYZlyQX+fJ -# 1k0ogeIF1owldecXP8t5e10WlHBlWb8IBnIPwMtJVZ2/y8NASxsnSJE7pEe7ijGe -# 5Bv9DXvoltKnMSVYv9u2vn7PeIq+Jm3n3kOGSIYtfdytEd1Fd6spfdcmIhqyzVk0 -# Hslq7Aqd7soT0xdmNa/amzEA4HRHpWGUhzOtcC+EqEIIJk9kTjyVgCiyWaB5gGko -# OAZfsxQn+a916iWwA7RrQ+TzBZq/pleUTLZzJmI3DXFjuJ1NDP6Sdw6KREgx6Yw4 -# q2NnnodKlGZkMDcGYPTM2sA4i6i6FsznWY4d8wE4J261YeUrVfIyTx+Q81W4KXoi -# C0x7Pe9Bjh4oJGM3YiLyhVL56sXZWxAC2C/vD3nvIvra9EpvlMvQh6b0xl0V4TSN -# dJ7T7VttR/WNjau46JIgbGZWCDBTTUAydQNoAZ4KnCrcIZCN6Y0qVokXsYHsVIto -# TsnM2+Ca09wxuOIfCOSKpAmqdJ/w2NwLwp+0gwrO2uzpCfbSbkAd+UQNv0joPyUp -# ywmsQndxqA8TaADp8TfkkpJywJGhghc/MIIXOwYKKwYBBAGCNwMDATGCFyswghcn -# BgkqhkiG9w0BBwKgghcYMIIXFAIBAzEPMA0GCWCGSAFlAwQCAQUAMHcGCyqGSIb3 -# DQEJEAEEoGgEZjBkAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQg+Jhe -# IOzOttA8vliuL+r3CiY4EJTzfvPasXkI/vwkoI8CEHZ95Ht1TmSmU8+fM0kIG00Y -# DzIwMjQwNDAyMTIzMjEwWqCCEwkwggbCMIIEqqADAgECAhAFRK/zlJ0IOaa/2z9f -# 5WEWMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp -# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2 -# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjMwNzE0MDAwMDAwWhcNMzQxMDEz -# MjM1OTU5WjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x -# IDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIzMIICIjANBgkqhkiG9w0B -# AQEFAAOCAg8AMIICCgKCAgEAo1NFhx2DjlusPlSzI+DPn9fl0uddoQ4J3C9Io5d6 -# OyqcZ9xiFVjBqZMRp82qsmrdECmKHmJjadNYnDVxvzqX65RQjxwg6seaOy+WZuNp -# 52n+W8PWKyAcwZeUtKVQgfLPywemMGjKg0La/H8JJJSkghraarrYO8pd3hkYhftF -# 6g1hbJ3+cV7EBpo88MUueQ8bZlLjyNY+X9pD04T10Mf2SC1eRXWWdf7dEKEbg8G4 -# 5lKVtUfXeCk5a+B4WZfjRCtK1ZXO7wgX6oJkTf8j48qG7rSkIWRw69XloNpjsy7p -# Be6q9iT1HbybHLK3X9/w7nZ9MZllR1WdSiQvrCuXvp/k/XtzPjLuUjT71Lvr1KAs -# NJvj3m5kGQc3AZEPHLVRzapMZoOIaGK7vEEbeBlt5NkP4FhB+9ixLOFRr7StFQYU -# 6mIIE9NpHnxkTZ0P387RXoyqq1AVybPKvNfEO2hEo6U7Qv1zfe7dCv95NBB+plwK -# WEwAPoVpdceDZNZ1zY8SdlalJPrXxGshuugfNJgvOuprAbD3+yqG7HtSOKmYCaFx -# smxxrz64b5bV4RAT/mFHCoz+8LbH1cfebCTwv0KCyqBxPZySkwS0aXAnDU+3tTbR -# yV8IpHCj7ArxES5k4MsiK8rxKBMhSVF+BmbTO77665E42FEHypS34lCh8zrTioPL -# QHsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYG -# A1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG -# SAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4E -# FgQUpbbvE+fvzdBkodVWqWUxo97V40kwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov -# L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1 -# NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUH -# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDov -# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNI -# QTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAgRrW3qCp -# tZgXvHCNT4o8aJzYJf/LLOTN6l0ikuyMIgKpuM+AqNnn48XtJoKKcS8Y3U623mzX -# 4WCcK+3tPUiOuGu6fF29wmE3aEl3o+uQqhLXJ4Xzjh6S2sJAOJ9dyKAuJXglnSoF -# eoQpmLZXeY/bJlYrsPOnvTcM2Jh2T1a5UsK2nTipgedtQVyMadG5K8TGe8+c+nji -# kxp2oml101DkRBK+IA2eqUTQ+OVJdwhaIcW0z5iVGlS6ubzBaRm6zxbygzc0brBB -# Jt3eWpdPM43UjXd9dUWhpVgmagNF3tlQtVCMr1a9TMXhRsUo063nQwBw3syYnhmJ -# A+rUkTfvTVLzyWAhxFZH7doRS4wyw4jmWOK22z75X7BC1o/jF5HRqsBV44a/rCcs -# QdCaM0qoNtS5cpZ+l3k4SF/Kwtw9Mt911jZnWon49qfH5U81PAC9vpwqbHkB3NpE -# 5jreODsHXjlY9HxzMVWggBHLFAx+rrz+pOt5Zapo1iLKO+uagjVXKBbLafIymrLS -# 2Dq4sUaGa7oX/cR3bBVsrquvczroSUa31X/MtjjA2Owc9bahuEMs305MfR5ocMB3 -# CtQC4Fxguyj/OOVSWtasFyIjTvTs0xf7UGv/B3cfcZdEQcm4RtNsMnxYL2dHZeUb -# c7aZ+WssBkbvQR7w8F/g29mtkIBEr4AQQYowggauMIIElqADAgECAhAHNje3JFR8 -# 2Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK -# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV -# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0z -# NzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg -# SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1 -# NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -# AQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI -# 82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9 -# xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ -# 3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5Emfv -# DqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDET -# qVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHe -# IhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jo -# n7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ -# 9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/T -# Xkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJg -# o1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkw -# EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+e -# yG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQD -# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEF -# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRw -# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy -# dDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln -# aUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg -# hkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGw -# GC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0 -# MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1D -# X+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw -# 1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY -# +/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0I -# SQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr -# 5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7y -# Rp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDop -# hrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/ -# AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMO -# Hds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq -# hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j -# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB -# c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5 -# WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -# ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv -# b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K -# PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r -# snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C -# 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf -# sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY -# QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8 -# rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY -# dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+ -# wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw -# ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N -# P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F -# wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw -# AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU -# Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB -# BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG -# AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1 -# cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp -# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow -# CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/ -# Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe -# JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE -# 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda -# XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO -# byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYID -# djCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu -# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg -# VGltZVN0YW1waW5nIENBAhAFRK/zlJ0IOaa/2z9f5WEWMA0GCWCGSAFlAwQCAQUA -# oIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcN -# MjQwNDAyMTIzMjEwWjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBRm8CsywsLJD4Jd -# zqqKycZPGZzPQDAvBgkqhkiG9w0BCQQxIgQg58bvIvjFkyBb2O0xwLgtU8RJLcMV -# kvIdXiq3TCLuhq4wNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQg0vbkbe10IszR1EBX -# aEE2b4KK2lWarjMWr00amtQMeCgwDQYJKoZIhvcNAQEBBQAEggIAhU3imuIvql4+ -# IqPz0Anf0ZIB5hbafNTx1WEVhPEG9iJr24gpjbWvepQrbWJf0FBj8wY9GeRab6iv -# 79MMxZkPpR/DMK1qFr1vIlw67JhpqqNkaNIa5G3pAHDYdHYcB+Utw1p5XPOBRu0A -# f4wQ5fwWugys4CGGAboq4prLNRKeUGVexMDK7Eorsv9xmzK0tE9QSMA3SxLCcSIX -# mrMkKzTR3vn0dqaDG4Ge7U2w7dVnQYGBX+s6C9CCjvCtenCAQLbF+OyYhkMNDVtJ -# lTmzxxwyyA5fFZJpG/Wfo/84/P8lQXUTuwOBpFoLE65OqNEG03SoqKsW4aTqkVM7 -# b6fKLsygm1w23+UlHGF/fbExeqxgOZiuJWWt/OFy9T3HIcAF1SMh7mot5ciu7btS -# xjkr/fhsi1M3M1g/giyn0I8N24mgaICPtXAzAbZW7GSC0R5T2qnW6gYoAcY62Qdz -# jl/Ey1rnOQ26TuQODyPVHhfhoIBbdIDpDJ2Vu2mxyxUnjATbizphcBgsU1fBYvZR -# v+SuK1MYZOGqgzugfiufdeFAlBDA/e64yRkJvDBEkcyGvj6FS6nVm7ekJpJhLU3z -# sSSmcYwdx1YQCr48HEjcmGrj5sAzzg4U4WU/GrLWz2sSRmh5rKcDAa0ewfYi13Z2 -# a/cdr8Or2RQ5ZSQ8OHgr3GBw7koDWR8= -# SIG # End signature block diff --git a/.venv311/Scripts/activate b/.venv311/Scripts/activate deleted file mode 100644 index c9bf7cf98..000000000 --- a/.venv311/Scripts/activate +++ /dev/null @@ -1,63 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - -deactivate () { - # reset old environment variables - if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then - PATH="${_OLD_VIRTUAL_PATH:-}" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then - PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # Call hash to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - hash -r 2> /dev/null - - if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then - PS1="${_OLD_VIRTUAL_PS1:-}" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - unset VIRTUAL_ENV_PROMPT - if [ ! "${1:-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="D:\code\MoFox_Bot\.venv311" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/Scripts:$PATH" -export PATH - -# unset PYTHONHOME if set -# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) -# could use `if (set -u; : $PYTHONHOME) ;` in bash -if [ -n "${PYTHONHOME:-}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1:-}" - PS1="(.venv311) ${PS1:-}" - export PS1 - VIRTUAL_ENV_PROMPT="(.venv311) " - export VIRTUAL_ENV_PROMPT -fi - -# Call hash to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -hash -r 2> /dev/null diff --git a/.venv311/Scripts/activate.bat b/.venv311/Scripts/activate.bat deleted file mode 100644 index a9e4e1d76..000000000 --- a/.venv311/Scripts/activate.bat +++ /dev/null @@ -1,34 +0,0 @@ -@echo off - -rem This file is UTF-8 encoded, so we need to update the current code page while executing it -for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( - set _OLD_CODEPAGE=%%a -) -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" 65001 > nul -) - -set VIRTUAL_ENV=D:\code\MoFox_Bot\.venv311 - -if not defined PROMPT set PROMPT=$P$G - -if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% -if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% - -set _OLD_VIRTUAL_PROMPT=%PROMPT% -set PROMPT=(.venv311) %PROMPT% - -if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% -set PYTHONHOME= - -if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% -if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% - -set PATH=%VIRTUAL_ENV%\Scripts;%PATH% -set VIRTUAL_ENV_PROMPT=(.venv311) - -:END -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul - set _OLD_CODEPAGE= -) diff --git a/.venv311/Scripts/chroma.exe b/.venv311/Scripts/chroma.exe deleted file mode 100644 index 7259a145f..000000000 Binary files a/.venv311/Scripts/chroma.exe and /dev/null differ diff --git a/.venv311/Scripts/coloredlogs.exe b/.venv311/Scripts/coloredlogs.exe deleted file mode 100644 index 7b5c2d334..000000000 Binary files a/.venv311/Scripts/coloredlogs.exe and /dev/null differ diff --git a/.venv311/Scripts/deactivate.bat b/.venv311/Scripts/deactivate.bat deleted file mode 100644 index 62a39a758..000000000 --- a/.venv311/Scripts/deactivate.bat +++ /dev/null @@ -1,22 +0,0 @@ -@echo off - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) -set _OLD_VIRTUAL_PROMPT= - -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" - set _OLD_VIRTUAL_PYTHONHOME= -) - -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) - -set _OLD_VIRTUAL_PATH= - -set VIRTUAL_ENV= -set VIRTUAL_ENV_PROMPT= - -:END diff --git a/.venv311/Scripts/distro.exe b/.venv311/Scripts/distro.exe deleted file mode 100644 index 0e88f3c59..000000000 Binary files a/.venv311/Scripts/distro.exe and /dev/null differ diff --git a/.venv311/Scripts/dotenv.exe b/.venv311/Scripts/dotenv.exe deleted file mode 100644 index 1f25f5a2a..000000000 Binary files a/.venv311/Scripts/dotenv.exe and /dev/null differ diff --git a/.venv311/Scripts/f2py.exe b/.venv311/Scripts/f2py.exe deleted file mode 100644 index 99fa1c06a..000000000 Binary files a/.venv311/Scripts/f2py.exe and /dev/null differ diff --git a/.venv311/Scripts/fastapi.exe b/.venv311/Scripts/fastapi.exe deleted file mode 100644 index 190783c59..000000000 Binary files a/.venv311/Scripts/fastapi.exe and /dev/null differ diff --git a/.venv311/Scripts/fonttools.exe b/.venv311/Scripts/fonttools.exe deleted file mode 100644 index b0a011c4d..000000000 Binary files a/.venv311/Scripts/fonttools.exe and /dev/null differ diff --git a/.venv311/Scripts/hf.exe b/.venv311/Scripts/hf.exe deleted file mode 100644 index 97789eaab..000000000 Binary files a/.venv311/Scripts/hf.exe and /dev/null differ diff --git a/.venv311/Scripts/httpx.exe b/.venv311/Scripts/httpx.exe deleted file mode 100644 index 5798a217d..000000000 Binary files a/.venv311/Scripts/httpx.exe and /dev/null differ diff --git a/.venv311/Scripts/huggingface-cli.exe b/.venv311/Scripts/huggingface-cli.exe deleted file mode 100644 index 9d56cbb77..000000000 Binary files a/.venv311/Scripts/huggingface-cli.exe and /dev/null differ diff --git a/.venv311/Scripts/humanfriendly.exe b/.venv311/Scripts/humanfriendly.exe deleted file mode 100644 index 7f4f51c5d..000000000 Binary files a/.venv311/Scripts/humanfriendly.exe and /dev/null differ diff --git a/.venv311/Scripts/igraph.exe b/.venv311/Scripts/igraph.exe deleted file mode 100644 index 3f2f32752..000000000 Binary files a/.venv311/Scripts/igraph.exe and /dev/null differ diff --git a/.venv311/Scripts/isympy.exe b/.venv311/Scripts/isympy.exe deleted file mode 100644 index 58aa210bd..000000000 Binary files a/.venv311/Scripts/isympy.exe and /dev/null differ diff --git a/.venv311/Scripts/json_repair.exe b/.venv311/Scripts/json_repair.exe deleted file mode 100644 index f987f43a9..000000000 Binary files a/.venv311/Scripts/json_repair.exe and /dev/null differ diff --git a/.venv311/Scripts/jsonschema.exe b/.venv311/Scripts/jsonschema.exe deleted file mode 100644 index 3d631e3a0..000000000 Binary files a/.venv311/Scripts/jsonschema.exe and /dev/null differ diff --git a/.venv311/Scripts/markdown-it.exe b/.venv311/Scripts/markdown-it.exe deleted file mode 100644 index 37bee95d1..000000000 Binary files a/.venv311/Scripts/markdown-it.exe and /dev/null differ diff --git a/.venv311/Scripts/mcp.exe b/.venv311/Scripts/mcp.exe deleted file mode 100644 index a0b129942..000000000 Binary files a/.venv311/Scripts/mcp.exe and /dev/null differ diff --git a/.venv311/Scripts/normalizer.exe b/.venv311/Scripts/normalizer.exe deleted file mode 100644 index 6ec1f0d83..000000000 Binary files a/.venv311/Scripts/normalizer.exe and /dev/null differ diff --git a/.venv311/Scripts/numpy-config.exe b/.venv311/Scripts/numpy-config.exe deleted file mode 100644 index 193d1e356..000000000 Binary files a/.venv311/Scripts/numpy-config.exe and /dev/null differ diff --git a/.venv311/Scripts/onnxruntime_test.exe b/.venv311/Scripts/onnxruntime_test.exe deleted file mode 100644 index c19bdc49f..000000000 Binary files a/.venv311/Scripts/onnxruntime_test.exe and /dev/null differ diff --git a/.venv311/Scripts/openai.exe b/.venv311/Scripts/openai.exe deleted file mode 100644 index 39099834f..000000000 Binary files a/.venv311/Scripts/openai.exe and /dev/null differ diff --git a/.venv311/Scripts/pip.exe b/.venv311/Scripts/pip.exe deleted file mode 100644 index dac071469..000000000 Binary files a/.venv311/Scripts/pip.exe and /dev/null differ diff --git a/.venv311/Scripts/pip3.11.exe b/.venv311/Scripts/pip3.11.exe deleted file mode 100644 index dac071469..000000000 Binary files a/.venv311/Scripts/pip3.11.exe and /dev/null differ diff --git a/.venv311/Scripts/pip3.exe b/.venv311/Scripts/pip3.exe deleted file mode 100644 index dac071469..000000000 Binary files a/.venv311/Scripts/pip3.exe and /dev/null differ diff --git a/.venv311/Scripts/pwiz.py b/.venv311/Scripts/pwiz.py deleted file mode 100644 index 75fe3f707..000000000 --- a/.venv311/Scripts/pwiz.py +++ /dev/null @@ -1,228 +0,0 @@ -#!D:\code\MoFox_Bot\.venv311\Scripts\python.exe - -import datetime -import os -import sys -from getpass import getpass -from optparse import OptionParser - -from peewee import * -from peewee import print_ -from peewee import __version__ as peewee_version -from playhouse.cockroachdb import CockroachDatabase -from playhouse.reflection import * - - -HEADER = """from peewee import *%s - -database = %s('%s'%s) -""" - -BASE_MODEL = """\ -class BaseModel(Model): - class Meta: - database = database -""" - -UNKNOWN_FIELD = """\ -class UnknownField(object): - def __init__(self, *_, **__): pass -""" - -DATABASE_ALIASES = { - CockroachDatabase: ['cockroach', 'cockroachdb', 'crdb'], - MySQLDatabase: ['mysql', 'mysqldb'], - PostgresqlDatabase: ['postgres', 'postgresql'], - SqliteDatabase: ['sqlite', 'sqlite3'], -} - -DATABASE_MAP = dict((value, key) - for key in DATABASE_ALIASES - for value in DATABASE_ALIASES[key]) - -def make_introspector(database_type, database_name, **kwargs): - if database_type not in DATABASE_MAP: - err('Unrecognized database, must be one of: %s' % - ', '.join(DATABASE_MAP.keys())) - sys.exit(1) - - schema = kwargs.pop('schema', None) - DatabaseClass = DATABASE_MAP[database_type] - db = DatabaseClass(database_name, **kwargs) - return Introspector.from_database(db, schema=schema) - -def print_models(introspector, tables=None, preserve_order=False, - include_views=False, ignore_unknown=False, snake_case=True): - database = introspector.introspect(table_names=tables, - include_views=include_views, - snake_case=snake_case) - - db_kwargs = introspector.get_database_kwargs() - header = HEADER % ( - introspector.get_additional_imports(), - introspector.get_database_class().__name__, - introspector.get_database_name().replace('\\', '\\\\'), - ', **%s' % repr(db_kwargs) if db_kwargs else '') - print_(header) - - if not ignore_unknown: - print_(UNKNOWN_FIELD) - - print_(BASE_MODEL) - - def _print_table(table, seen, accum=None): - accum = accum or [] - foreign_keys = database.foreign_keys[table] - for foreign_key in foreign_keys: - dest = foreign_key.dest_table - - # In the event the destination table has already been pushed - # for printing, then we have a reference cycle. - if dest in accum and table not in accum: - print_('# Possible reference cycle: %s' % dest) - - # If this is not a self-referential foreign key, and we have - # not already processed the destination table, do so now. - if dest not in seen and dest not in accum: - seen.add(dest) - if dest != table: - _print_table(dest, seen, accum + [table]) - - print_('class %s(BaseModel):' % database.model_names[table]) - columns = database.columns[table].items() - if not preserve_order: - columns = sorted(columns) - primary_keys = database.primary_keys[table] - for name, column in columns: - skip = all([ - name in primary_keys, - name == 'id', - len(primary_keys) == 1, - column.field_class in introspector.pk_classes]) - if skip: - continue - if column.primary_key and len(primary_keys) > 1: - # If we have a CompositeKey, then we do not want to explicitly - # mark the columns as being primary keys. - column.primary_key = False - - is_unknown = column.field_class is UnknownField - if is_unknown and ignore_unknown: - disp = '%s - %s' % (column.name, column.raw_column_type or '?') - print_(' # %s' % disp) - else: - print_(' %s' % column.get_field()) - - print_('') - print_(' class Meta:') - print_(' table_name = \'%s\'' % table) - multi_column_indexes = database.multi_column_indexes(table) - if multi_column_indexes: - print_(' indexes = (') - for fields, unique in sorted(multi_column_indexes): - print_(' ((%s), %s),' % ( - ', '.join("'%s'" % field for field in fields), - unique, - )) - print_(' )') - - if introspector.schema: - print_(' schema = \'%s\'' % introspector.schema) - if len(primary_keys) > 1: - pk_field_names = sorted([ - field.name for col, field in columns - if col in primary_keys]) - pk_list = ', '.join("'%s'" % pk for pk in pk_field_names) - print_(' primary_key = CompositeKey(%s)' % pk_list) - elif not primary_keys: - print_(' primary_key = False') - print_('') - - seen.add(table) - - seen = set() - for table in sorted(database.model_names.keys()): - if table not in seen: - if not tables or table in tables: - _print_table(table, seen) - -def print_header(cmd_line, introspector): - timestamp = datetime.datetime.now() - print_('# Code generated by:') - print_('# python -m pwiz %s' % cmd_line) - print_('# Date: %s' % timestamp.strftime('%B %d, %Y %I:%M%p')) - print_('# Database: %s' % introspector.get_database_name()) - print_('# Peewee version: %s' % peewee_version) - print_('') - - -def err(msg): - sys.stderr.write('\033[91m%s\033[0m\n' % msg) - sys.stderr.flush() - -def get_option_parser(): - parser = OptionParser(usage='usage: %prog [options] database_name') - ao = parser.add_option - ao('-H', '--host', dest='host') - ao('-p', '--port', dest='port', type='int') - ao('-u', '--user', dest='user') - ao('-P', '--password', dest='password', action='store_true') - engines = sorted(DATABASE_MAP) - ao('-e', '--engine', dest='engine', choices=engines, - help=('Database type, e.g. sqlite, mysql, postgresql or cockroachdb. ' - 'Default is "postgresql".')) - ao('-s', '--schema', dest='schema') - ao('-t', '--tables', dest='tables', - help=('Only generate the specified tables. Multiple table names should ' - 'be separated by commas.')) - ao('-v', '--views', dest='views', action='store_true', - help='Generate model classes for VIEWs in addition to tables.') - ao('-i', '--info', dest='info', action='store_true', - help=('Add database information and other metadata to top of the ' - 'generated file.')) - ao('-o', '--preserve-order', action='store_true', dest='preserve_order', - help='Model definition column ordering matches source table.') - ao('-I', '--ignore-unknown', action='store_true', dest='ignore_unknown', - help='Ignore fields whose type cannot be determined.') - ao('-L', '--legacy-naming', action='store_true', dest='legacy_naming', - help='Use legacy table- and column-name generation.') - return parser - -def get_connect_kwargs(options): - ops = ('host', 'port', 'user', 'schema') - kwargs = dict((o, getattr(options, o)) for o in ops if getattr(options, o)) - if options.password: - kwargs['password'] = getpass() - return kwargs - - -if __name__ == '__main__': - raw_argv = sys.argv - - parser = get_option_parser() - options, args = parser.parse_args() - - if len(args) < 1: - err('Missing required parameter "database"') - parser.print_help() - sys.exit(1) - - connect = get_connect_kwargs(options) - database = args[-1] - - tables = None - if options.tables: - tables = [table.strip() for table in options.tables.split(',') - if table.strip()] - - engine = options.engine - if engine is None: - engine = 'sqlite' if os.path.exists(database) else 'postgresql' - - introspector = make_introspector(engine, database, **connect) - if options.info: - cmd_line = ' '.join(raw_argv[1:]) - print_header(cmd_line, introspector) - - print_models(introspector, tables, options.preserve_order, options.views, - options.ignore_unknown, not options.legacy_naming) diff --git a/.venv311/Scripts/pybase64.exe b/.venv311/Scripts/pybase64.exe deleted file mode 100644 index 99d955763..000000000 Binary files a/.venv311/Scripts/pybase64.exe and /dev/null differ diff --git a/.venv311/Scripts/pyftmerge.exe b/.venv311/Scripts/pyftmerge.exe deleted file mode 100644 index 8dc45a2f9..000000000 Binary files a/.venv311/Scripts/pyftmerge.exe and /dev/null differ diff --git a/.venv311/Scripts/pyftsubset.exe b/.venv311/Scripts/pyftsubset.exe deleted file mode 100644 index b97e14524..000000000 Binary files a/.venv311/Scripts/pyftsubset.exe and /dev/null differ diff --git a/.venv311/Scripts/pygmentize.exe b/.venv311/Scripts/pygmentize.exe deleted file mode 100644 index bd9906ee6..000000000 Binary files a/.venv311/Scripts/pygmentize.exe and /dev/null differ diff --git a/.venv311/Scripts/pyjson5.exe b/.venv311/Scripts/pyjson5.exe deleted file mode 100644 index 739457e94..000000000 Binary files a/.venv311/Scripts/pyjson5.exe and /dev/null differ diff --git a/.venv311/Scripts/pypinyin.exe b/.venv311/Scripts/pypinyin.exe deleted file mode 100644 index 9e87ae6f4..000000000 Binary files a/.venv311/Scripts/pypinyin.exe and /dev/null differ diff --git a/.venv311/Scripts/pyproject-build.exe b/.venv311/Scripts/pyproject-build.exe deleted file mode 100644 index e8cb24efb..000000000 Binary files a/.venv311/Scripts/pyproject-build.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-decrypt.exe b/.venv311/Scripts/pyrsa-decrypt.exe deleted file mode 100644 index 6aa8e7603..000000000 Binary files a/.venv311/Scripts/pyrsa-decrypt.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-encrypt.exe b/.venv311/Scripts/pyrsa-encrypt.exe deleted file mode 100644 index 187c51032..000000000 Binary files a/.venv311/Scripts/pyrsa-encrypt.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-keygen.exe b/.venv311/Scripts/pyrsa-keygen.exe deleted file mode 100644 index ab55affe2..000000000 Binary files a/.venv311/Scripts/pyrsa-keygen.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-priv2pub.exe b/.venv311/Scripts/pyrsa-priv2pub.exe deleted file mode 100644 index 8968abb7d..000000000 Binary files a/.venv311/Scripts/pyrsa-priv2pub.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-sign.exe b/.venv311/Scripts/pyrsa-sign.exe deleted file mode 100644 index 61a4140e2..000000000 Binary files a/.venv311/Scripts/pyrsa-sign.exe and /dev/null differ diff --git a/.venv311/Scripts/pyrsa-verify.exe b/.venv311/Scripts/pyrsa-verify.exe deleted file mode 100644 index 81559d71e..000000000 Binary files a/.venv311/Scripts/pyrsa-verify.exe and /dev/null differ diff --git a/.venv311/Scripts/python.exe b/.venv311/Scripts/python.exe deleted file mode 100644 index f7cb1e389..000000000 Binary files a/.venv311/Scripts/python.exe and /dev/null differ diff --git a/.venv311/Scripts/pythonw.exe b/.venv311/Scripts/pythonw.exe deleted file mode 100644 index 4fc3f9090..000000000 Binary files a/.venv311/Scripts/pythonw.exe and /dev/null differ diff --git a/.venv311/Scripts/pywin32_postinstall.exe b/.venv311/Scripts/pywin32_postinstall.exe deleted file mode 100644 index 1cb93c202..000000000 Binary files a/.venv311/Scripts/pywin32_postinstall.exe and /dev/null differ diff --git a/.venv311/Scripts/pywin32_postinstall.py b/.venv311/Scripts/pywin32_postinstall.py deleted file mode 100644 index 3348b8cdd..000000000 --- a/.venv311/Scripts/pywin32_postinstall.py +++ /dev/null @@ -1,733 +0,0 @@ -# postinstall script for pywin32 -# -# copies pywintypesXX.dll and pythoncomXX.dll into the system directory, -# and creates a pth file -import argparse -import glob -import os -import shutil -import sys -import sysconfig -import tempfile -import winreg - -tee_f = open( - os.path.join( - tempfile.gettempdir(), # Send output somewhere so it can be found if necessary... - "pywin32_postinstall.log", - ), - "w", -) - - -class Tee: - def __init__(self, file): - self.f = file - - def write(self, what): - if self.f is not None: - try: - self.f.write(what.replace("\n", "\r\n")) - except OSError: - pass - tee_f.write(what) - - def flush(self): - if self.f is not None: - try: - self.f.flush() - except OSError: - pass - tee_f.flush() - - -sys.stderr = Tee(sys.stderr) -sys.stdout = Tee(sys.stdout) - -com_modules = [ - # module_name, class_names - ("win32com.servers.interp", "Interpreter"), - ("win32com.servers.dictionary", "DictionaryPolicy"), - ("win32com.axscript.client.pyscript", "PyScript"), -] - -# Is this a 'silent' install - ie, avoid all dialogs. -# Different than 'verbose' -silent = 0 - -# Verbosity of output messages. -verbose = 1 - -root_key_name = "Software\\Python\\PythonCore\\" + sys.winver - - -def get_root_hkey(): - try: - winreg.OpenKey( - winreg.HKEY_LOCAL_MACHINE, root_key_name, 0, winreg.KEY_CREATE_SUB_KEY - ) - return winreg.HKEY_LOCAL_MACHINE - except OSError: - # Either not exist, or no permissions to create subkey means - # must be HKCU - return winreg.HKEY_CURRENT_USER - - -# Create a function with the same signature as create_shortcut -# previously provided by bdist_wininst -def create_shortcut( - path, description, filename, arguments="", workdir="", iconpath="", iconindex=0 -): - import pythoncom - from win32com.shell import shell - - ilink = pythoncom.CoCreateInstance( - shell.CLSID_ShellLink, - None, - pythoncom.CLSCTX_INPROC_SERVER, - shell.IID_IShellLink, - ) - ilink.SetPath(path) - ilink.SetDescription(description) - if arguments: - ilink.SetArguments(arguments) - if workdir: - ilink.SetWorkingDirectory(workdir) - if iconpath or iconindex: - ilink.SetIconLocation(iconpath, iconindex) - # now save it. - ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile) - ipf.Save(filename, 0) - - -# Support the same list of "path names" as bdist_wininst used to -def get_special_folder_path(path_name): - from win32com.shell import shell, shellcon - - for maybe in """ - CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA - CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY - CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP - CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON - CSIDL_PROGRAM_FILES CSIDL_FONTS""".split(): - if maybe == path_name: - csidl = getattr(shellcon, maybe) - return shell.SHGetSpecialFolderPath(0, csidl, False) - raise ValueError(f"{path_name} is an unknown path ID") - - -def CopyTo(desc, src, dest): - import win32api - import win32con - - while 1: - try: - win32api.CopyFile(src, dest, 0) - return - except win32api.error as details: - if details.winerror == 5: # access denied - user not admin. - raise - if silent: - # Running silent mode - just re-raise the error. - raise - full_desc = ( - f"Error {desc}\n\n" - "If you have any Python applications running, " - f"please close them now\nand select 'Retry'\n\n{details.strerror}" - ) - rc = win32api.MessageBox( - 0, full_desc, "Installation Error", win32con.MB_ABORTRETRYIGNORE - ) - if rc == win32con.IDABORT: - raise - elif rc == win32con.IDIGNORE: - return - # else retry - around we go again. - - -# We need to import win32api to determine the Windows system directory, -# so we can copy our system files there - but importing win32api will -# load the pywintypes.dll already in the system directory preventing us -# from updating them! -# So, we pull the same trick pywintypes.py does, but it loads from -# our pywintypes_system32 directory. -def LoadSystemModule(lib_dir, modname): - # See if this is a debug build. - import importlib.machinery - import importlib.util - - suffix = "_d" if "_d.pyd" in importlib.machinery.EXTENSION_SUFFIXES else "" - filename = "%s%d%d%s.dll" % ( - modname, - sys.version_info.major, - sys.version_info.minor, - suffix, - ) - filename = os.path.join(lib_dir, "pywin32_system32", filename) - loader = importlib.machinery.ExtensionFileLoader(modname, filename) - spec = importlib.machinery.ModuleSpec(name=modname, loader=loader, origin=filename) - mod = importlib.util.module_from_spec(spec) - loader.exec_module(mod) - - -def SetPyKeyVal(key_name, value_name, value): - root_hkey = get_root_hkey() - root_key = winreg.OpenKey(root_hkey, root_key_name) - try: - my_key = winreg.CreateKey(root_key, key_name) - try: - winreg.SetValueEx(my_key, value_name, 0, winreg.REG_SZ, value) - if verbose: - print(f"-> {root_key_name}\\{key_name}[{value_name}]={value!r}") - finally: - my_key.Close() - finally: - root_key.Close() - - -def UnsetPyKeyVal(key_name, value_name, delete_key=False): - root_hkey = get_root_hkey() - root_key = winreg.OpenKey(root_hkey, root_key_name) - try: - my_key = winreg.OpenKey(root_key, key_name, 0, winreg.KEY_SET_VALUE) - try: - winreg.DeleteValue(my_key, value_name) - if verbose: - print(f"-> DELETE {root_key_name}\\{key_name}[{value_name}]") - finally: - my_key.Close() - if delete_key: - winreg.DeleteKey(root_key, key_name) - if verbose: - print(f"-> DELETE {root_key_name}\\{key_name}") - except OSError as why: - winerror = getattr(why, "winerror", why.errno) - if winerror != 2: # file not found - raise - finally: - root_key.Close() - - -def RegisterCOMObjects(register=True): - import win32com.server.register - - if register: - func = win32com.server.register.RegisterClasses - else: - func = win32com.server.register.UnregisterClasses - flags = {} - if not verbose: - flags["quiet"] = 1 - for module, klass_name in com_modules: - __import__(module) - mod = sys.modules[module] - flags["finalize_register"] = getattr(mod, "DllRegisterServer", None) - flags["finalize_unregister"] = getattr(mod, "DllUnregisterServer", None) - klass = getattr(mod, klass_name) - func(klass, **flags) - - -def RegisterHelpFile(register=True, lib_dir=None): - if lib_dir is None: - lib_dir = sysconfig.get_paths()["platlib"] - if register: - # Register the .chm help file. - chm_file = os.path.join(lib_dir, "PyWin32.chm") - if os.path.isfile(chm_file): - # This isn't recursive, so if 'Help' doesn't exist, we croak - SetPyKeyVal("Help", None, None) - SetPyKeyVal("Help\\Pythonwin Reference", None, chm_file) - return chm_file - else: - print("NOTE: PyWin32.chm can not be located, so has not been registered") - else: - UnsetPyKeyVal("Help\\Pythonwin Reference", None, delete_key=True) - return None - - -def RegisterPythonwin(register=True, lib_dir=None): - """Add (or remove) Pythonwin to context menu for python scripts. - ??? Should probably also add Edit command for pys files also. - Also need to remove these keys on uninstall, but there's no function - to add registry entries to uninstall log ??? - """ - import os - - if lib_dir is None: - lib_dir = sysconfig.get_paths()["platlib"] - classes_root = get_root_hkey() - ## Installer executable doesn't seem to pass anything to postinstall script indicating if it's a debug build - pythonwin_exe = os.path.join(lib_dir, "Pythonwin", "Pythonwin.exe") - pythonwin_edit_command = pythonwin_exe + ' -edit "%1"' - - keys_vals = [ - ( - "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Pythonwin.exe", - "", - pythonwin_exe, - ), - ( - "Software\\Classes\\Python.File\\shell\\Edit with Pythonwin", - "command", - pythonwin_edit_command, - ), - ( - "Software\\Classes\\Python.NoConFile\\shell\\Edit with Pythonwin", - "command", - pythonwin_edit_command, - ), - ] - - try: - if register: - for key, sub_key, val in keys_vals: - ## Since winreg only uses the character Api functions, this can fail if Python - ## is installed to a path containing non-ascii characters - hkey = winreg.CreateKey(classes_root, key) - if sub_key: - hkey = winreg.CreateKey(hkey, sub_key) - winreg.SetValueEx(hkey, None, 0, winreg.REG_SZ, val) - hkey.Close() - else: - for key, sub_key, val in keys_vals: - try: - if sub_key: - hkey = winreg.OpenKey(classes_root, key) - winreg.DeleteKey(hkey, sub_key) - hkey.Close() - winreg.DeleteKey(classes_root, key) - except OSError as why: - winerror = getattr(why, "winerror", why.errno) - if winerror != 2: # file not found - raise - finally: - # tell windows about the change - from win32com.shell import shell, shellcon - - shell.SHChangeNotify( - shellcon.SHCNE_ASSOCCHANGED, shellcon.SHCNF_IDLIST, None, None - ) - - -def get_shortcuts_folder(): - if get_root_hkey() == winreg.HKEY_LOCAL_MACHINE: - try: - fldr = get_special_folder_path("CSIDL_COMMON_PROGRAMS") - except OSError: - # No CSIDL_COMMON_PROGRAMS on this platform - fldr = get_special_folder_path("CSIDL_PROGRAMS") - else: - # non-admin install - always goes in this user's start menu. - fldr = get_special_folder_path("CSIDL_PROGRAMS") - - try: - install_group = winreg.QueryValue( - get_root_hkey(), root_key_name + "\\InstallPath\\InstallGroup" - ) - except OSError: - install_group = "Python %d.%d" % ( - sys.version_info.major, - sys.version_info.minor, - ) - return os.path.join(fldr, install_group) - - -# Get the system directory, which may be the Wow64 directory if we are a 32bit -# python on a 64bit OS. -def get_system_dir(): - import win32api # we assume this exists. - - try: - import pythoncom - import win32process - from win32com.shell import shell, shellcon - - try: - if win32process.IsWow64Process(): - return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEMX86) - return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEM) - except (pythoncom.com_error, win32process.error): - return win32api.GetSystemDirectory() - except ImportError: - return win32api.GetSystemDirectory() - - -def fixup_dbi(): - # We used to have a dbi.pyd with our .pyd files, but now have a .py file. - # If the user didn't uninstall, they will find the .pyd which will cause - # problems - so handle that. - import win32api - import win32con - - pyd_name = os.path.join(os.path.dirname(win32api.__file__), "dbi.pyd") - pyd_d_name = os.path.join(os.path.dirname(win32api.__file__), "dbi_d.pyd") - py_name = os.path.join(os.path.dirname(win32con.__file__), "dbi.py") - for this_pyd in (pyd_name, pyd_d_name): - this_dest = this_pyd + ".old" - if os.path.isfile(this_pyd) and os.path.isfile(py_name): - try: - if os.path.isfile(this_dest): - print( - f"Old dbi '{this_dest}' already exists - deleting '{this_pyd}'" - ) - os.remove(this_pyd) - else: - os.rename(this_pyd, this_dest) - print(f"renamed '{this_pyd}'->'{this_pyd}.old'") - except OSError as exc: - print(f"FAILED to rename '{this_pyd}': {exc}") - - -def install(lib_dir): - import traceback - - # The .pth file is now installed as a regular file. - # Create the .pth file in the site-packages dir, and use only relative paths - # We used to write a .pth directly to sys.prefix - clobber it. - if os.path.isfile(os.path.join(sys.prefix, "pywin32.pth")): - os.unlink(os.path.join(sys.prefix, "pywin32.pth")) - # The .pth may be new and therefore not loaded in this session. - # Setup the paths just in case. - for name in "win32 win32\\lib Pythonwin".split(): - sys.path.append(os.path.join(lib_dir, name)) - # It is possible people with old versions installed with still have - # pywintypes and pythoncom registered. We no longer need this, and stale - # entries hurt us. - for name in "pythoncom pywintypes".split(): - keyname = "Software\\Python\\PythonCore\\" + sys.winver + "\\Modules\\" + name - for root in winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER: - try: - winreg.DeleteKey(root, keyname + "\\Debug") - except OSError: - pass - try: - winreg.DeleteKey(root, keyname) - except OSError: - pass - LoadSystemModule(lib_dir, "pywintypes") - LoadSystemModule(lib_dir, "pythoncom") - import win32api - - # and now we can get the system directory: - files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) - if not files: - raise RuntimeError("No system files to copy!!") - # Try the system32 directory first - if that fails due to "access denied", - # it implies a non-admin user, and we use sys.prefix - for dest_dir in [get_system_dir(), sys.prefix]: - # and copy some files over there - worked = 0 - try: - for fname in files: - base = os.path.basename(fname) - dst = os.path.join(dest_dir, base) - CopyTo("installing %s" % base, fname, dst) - if verbose: - print(f"Copied {base} to {dst}") - worked = 1 - # Nuke any other versions that may exist - having - # duplicates causes major headaches. - bad_dest_dirs = [ - os.path.join(sys.prefix, "Library\\bin"), - os.path.join(sys.prefix, "Lib\\site-packages\\win32"), - ] - if dest_dir != sys.prefix: - bad_dest_dirs.append(sys.prefix) - for bad_dest_dir in bad_dest_dirs: - bad_fname = os.path.join(bad_dest_dir, base) - if os.path.exists(bad_fname): - # let exceptions go here - delete must succeed - os.unlink(bad_fname) - if worked: - break - except win32api.error as details: - if details.winerror == 5: - # access denied - user not admin - try sys.prefix dir, - # but first check that a version doesn't already exist - # in that place - otherwise that one will still get used! - if os.path.exists(dst): - msg = ( - "The file '%s' exists, but can not be replaced " - "due to insufficient permissions. You must " - "reinstall this software as an Administrator" % dst - ) - print(msg) - raise RuntimeError(msg) - continue - raise - else: - raise RuntimeError( - "You don't have enough permissions to install the system files" - ) - - # Register our demo COM objects. - try: - try: - RegisterCOMObjects() - except win32api.error as details: - if details.winerror != 5: # ERROR_ACCESS_DENIED - raise - print("You do not have the permissions to install COM objects.") - print("The sample COM objects were not registered.") - except Exception: - print("FAILED to register the Python COM objects") - traceback.print_exc() - - # There may be no main Python key in HKCU if, eg, an admin installed - # python itself. - winreg.CreateKey(get_root_hkey(), root_key_name) - - chm_file = None - try: - chm_file = RegisterHelpFile(True, lib_dir) - except Exception: - print("Failed to register help file") - traceback.print_exc() - else: - if verbose: - print("Registered help file") - - # misc other fixups. - fixup_dbi() - - # Register Pythonwin in context menu - try: - RegisterPythonwin(True, lib_dir) - except Exception: - print("Failed to register pythonwin as editor") - traceback.print_exc() - else: - if verbose: - print("Pythonwin has been registered in context menu") - - # Create the win32com\gen_py directory. - make_dir = os.path.join(lib_dir, "win32com", "gen_py") - if not os.path.isdir(make_dir): - if verbose: - print(f"Creating directory {make_dir}") - os.mkdir(make_dir) - - try: - # create shortcuts - # CSIDL_COMMON_PROGRAMS only available works on NT/2000/XP, and - # will fail there if the user has no admin rights. - fldr = get_shortcuts_folder() - # If the group doesn't exist, then we don't make shortcuts - its - # possible that this isn't a "normal" install. - if os.path.isdir(fldr): - dst = os.path.join(fldr, "PythonWin.lnk") - create_shortcut( - os.path.join(lib_dir, "Pythonwin\\Pythonwin.exe"), - "The Pythonwin IDE", - dst, - "", - sys.prefix, - ) - if verbose: - print("Shortcut for Pythonwin created") - # And the docs. - if chm_file: - dst = os.path.join(fldr, "Python for Windows Documentation.lnk") - doc = "Documentation for the PyWin32 extensions" - create_shortcut(chm_file, doc, dst) - if verbose: - print("Shortcut to documentation created") - else: - if verbose: - print(f"Can't install shortcuts - {fldr!r} is not a folder") - except Exception as details: - print(details) - - # importing win32com.client ensures the gen_py dir created - not strictly - # necessary to do now, but this makes the installation "complete" - try: - import win32com.client # noqa - except ImportError: - # Don't let this error sound fatal - pass - print("The pywin32 extensions were successfully installed.") - - -def uninstall(lib_dir): - # First ensure our system modules are loaded from pywin32_system, so - # we can remove the ones we copied... - LoadSystemModule(lib_dir, "pywintypes") - LoadSystemModule(lib_dir, "pythoncom") - - try: - RegisterCOMObjects(False) - except Exception as why: - print(f"Failed to unregister COM objects: {why}") - - try: - RegisterHelpFile(False, lib_dir) - except Exception as why: - print(f"Failed to unregister help file: {why}") - else: - if verbose: - print("Unregistered help file") - - try: - RegisterPythonwin(False, lib_dir) - except Exception as why: - print(f"Failed to unregister Pythonwin: {why}") - else: - if verbose: - print("Unregistered Pythonwin") - - try: - # remove gen_py directory. - gen_dir = os.path.join(lib_dir, "win32com", "gen_py") - if os.path.isdir(gen_dir): - shutil.rmtree(gen_dir) - if verbose: - print(f"Removed directory {gen_dir}") - - # Remove pythonwin compiled "config" files. - pywin_dir = os.path.join(lib_dir, "Pythonwin", "pywin") - for fname in glob.glob(os.path.join(pywin_dir, "*.cfc")): - os.remove(fname) - - # The dbi.pyd.old files we may have created. - try: - os.remove(os.path.join(lib_dir, "win32", "dbi.pyd.old")) - except OSError: - pass - try: - os.remove(os.path.join(lib_dir, "win32", "dbi_d.pyd.old")) - except OSError: - pass - - except Exception as why: - print(f"Failed to remove misc files: {why}") - - try: - fldr = get_shortcuts_folder() - for link in ("PythonWin.lnk", "Python for Windows Documentation.lnk"): - fqlink = os.path.join(fldr, link) - if os.path.isfile(fqlink): - os.remove(fqlink) - if verbose: - print(f"Removed {link}") - except Exception as why: - print(f"Failed to remove shortcuts: {why}") - # Now remove the system32 files. - files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) - # Try the system32 directory first - if that fails due to "access denied", - # it implies a non-admin user, and we use sys.prefix - try: - for dest_dir in [get_system_dir(), sys.prefix]: - # and copy some files over there - worked = 0 - for fname in files: - base = os.path.basename(fname) - dst = os.path.join(dest_dir, base) - if os.path.isfile(dst): - try: - os.remove(dst) - worked = 1 - if verbose: - print("Removed file %s" % (dst)) - except Exception: - print(f"FAILED to remove {dst}") - if worked: - break - except Exception as why: - print(f"FAILED to remove system files: {why}") - - -# NOTE: This used to be run from inside the bdist_wininst created binary un/installer. -# From inside the binary installer this script HAD to NOT -# call sys.exit() or raise SystemExit, otherwise the installer would also terminate! -# Out of principle, we're still not using system exits. - - -def verify_destination(location: str) -> str: - location = os.path.abspath(location) - if not os.path.isdir(location): - raise argparse.ArgumentTypeError( - f'Path "{location}" is not an existing directory!' - ) - return location - - -def main(): - parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description="""A post-install script for the pywin32 extensions. - - * Typical usage: - - > python -m pywin32_postinstall -install - - * or (shorter but you don't have control over which python environment is used) - - > pywin32_postinstall -install - - You need to execute this script, with a '-install' parameter, - to ensure the environment is setup correctly to install COM objects, services, etc. - """, - ) - parser.add_argument( - "-install", - default=False, - action="store_true", - help="Configure the Python environment correctly for pywin32.", - ) - parser.add_argument( - "-remove", - default=False, - action="store_true", - help="Try and remove everything that was installed or copied.", - ) - parser.add_argument( - "-wait", - type=int, - help="Wait for the specified process to terminate before starting.", - ) - parser.add_argument( - "-silent", - default=False, - action="store_true", - help='Don\'t display the "Abort/Retry/Ignore" dialog for files in use.', - ) - parser.add_argument( - "-quiet", - default=False, - action="store_true", - help="Don't display progress messages.", - ) - parser.add_argument( - "-destination", - default=sysconfig.get_paths()["platlib"], - type=verify_destination, - help="Location of the PyWin32 installation", - ) - - args = parser.parse_args() - - if not args.quiet: - print(f"Parsed arguments are: {args}") - - if not args.install ^ args.remove: - parser.error("You need to either choose to -install or -remove!") - - if args.wait is not None: - try: - os.waitpid(args.wait, 0) - except OSError: - # child already dead - pass - - silent = args.silent - verbose = not args.quiet - - if args.install: - install(args.destination) - - if args.remove: - uninstall(args.destination) - - -if __name__ == "__main__": - main() diff --git a/.venv311/Scripts/pywin32_testall.exe b/.venv311/Scripts/pywin32_testall.exe deleted file mode 100644 index 6c59de50a..000000000 Binary files a/.venv311/Scripts/pywin32_testall.exe and /dev/null differ diff --git a/.venv311/Scripts/pywin32_testall.py b/.venv311/Scripts/pywin32_testall.py deleted file mode 100644 index 345d6413f..000000000 --- a/.venv311/Scripts/pywin32_testall.py +++ /dev/null @@ -1,120 +0,0 @@ -"""A test runner for pywin32""" - -import os -import site -import subprocess -import sys - -# locate the dirs based on where this script is - it may be either in the -# source tree, or in an installed Python 'Scripts' tree. -project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) -site_packages = [site.getusersitepackages()] + site.getsitepackages() - -failures = [] - - -# Run a test using subprocess and wait for the result. -# If we get an returncode != 0, we know that there was an error, but we don't -# abort immediately - we run as many tests as we can. -def run_test(script, cmdline_extras): - dirname, scriptname = os.path.split(script) - # some tests prefer to be run from their directory. - cmd = [sys.executable, "-u", scriptname] + cmdline_extras - print("--- Running '%s' ---" % script) - sys.stdout.flush() - result = subprocess.run(cmd, check=False, cwd=dirname) - print(f"*** Test script '{script}' exited with {result.returncode}") - sys.stdout.flush() - if result.returncode: - failures.append(script) - - -def find_and_run(possible_locations, extras): - for maybe in possible_locations: - if os.path.isfile(maybe): - run_test(maybe, extras) - break - else: - raise RuntimeError( - "Failed to locate a test script in one of %s" % possible_locations - ) - - -def main(): - import argparse - - code_directories = [project_root] + site_packages - - parser = argparse.ArgumentParser( - description="A script to trigger tests in all subprojects of PyWin32." - ) - parser.add_argument( - "-no-user-interaction", - default=False, - action="store_true", - help="(This is now the default - use `-user-interaction` to include them)", - ) - - parser.add_argument( - "-user-interaction", - action="store_true", - help="Include tests which require user interaction", - ) - - parser.add_argument( - "-skip-adodbapi", - default=False, - action="store_true", - help="Skip the adodbapi tests; useful for CI where there's no provider", - ) - - args, remains = parser.parse_known_args() - - # win32, win32ui / Pythonwin - - extras = [] - if args.user_interaction: - extras.append("-user-interaction") - extras.extend(remains) - scripts = [ - "win32/test/testall.py", - "Pythonwin/pywin/test/all.py", - ] - for script in scripts: - maybes = [os.path.join(directory, script) for directory in code_directories] - find_and_run(maybes, extras) - - # win32com - maybes = [ - os.path.join(directory, "win32com", "test", "testall.py") - for directory in [os.path.join(project_root, "com")] + site_packages - ] - extras = remains + ["1"] # only run "level 1" tests in CI - find_and_run(maybes, extras) - - # adodbapi - if not args.skip_adodbapi: - maybes = [ - os.path.join(directory, "adodbapi", "test", "adodbapitest.py") - for directory in code_directories - ] - find_and_run(maybes, remains) - # This script has a hard-coded sql server name in it, (and markh typically - # doesn't have a different server to test on) but there is now supposed to be a server out there on the Internet - # just to run these tests, so try it... - maybes = [ - os.path.join(directory, "adodbapi", "test", "test_adodbapi_dbapi20.py") - for directory in code_directories - ] - find_and_run(maybes, remains) - - if failures: - print("The following scripts failed") - for failure in failures: - print(">", failure) - sys.exit(1) - print("All tests passed \\o/") - - -if __name__ == "__main__": - main() diff --git a/.venv311/Scripts/ruff.exe b/.venv311/Scripts/ruff.exe deleted file mode 100644 index 8f5a5fe0c..000000000 Binary files a/.venv311/Scripts/ruff.exe and /dev/null differ diff --git a/.venv311/Scripts/strawberry.exe b/.venv311/Scripts/strawberry.exe deleted file mode 100644 index 5a06452c1..000000000 Binary files a/.venv311/Scripts/strawberry.exe and /dev/null differ diff --git a/.venv311/Scripts/tiny-agents.exe b/.venv311/Scripts/tiny-agents.exe deleted file mode 100644 index 572d84c21..000000000 Binary files a/.venv311/Scripts/tiny-agents.exe and /dev/null differ diff --git a/.venv311/Scripts/tqdm.exe b/.venv311/Scripts/tqdm.exe deleted file mode 100644 index f204330fb..000000000 Binary files a/.venv311/Scripts/tqdm.exe and /dev/null differ diff --git a/.venv311/Scripts/ttx.exe b/.venv311/Scripts/ttx.exe deleted file mode 100644 index 13dfa7047..000000000 Binary files a/.venv311/Scripts/ttx.exe and /dev/null differ diff --git a/.venv311/Scripts/typer.exe b/.venv311/Scripts/typer.exe deleted file mode 100644 index 349625e3e..000000000 Binary files a/.venv311/Scripts/typer.exe and /dev/null differ diff --git a/.venv311/Scripts/uvicorn.exe b/.venv311/Scripts/uvicorn.exe deleted file mode 100644 index 32a9ad693..000000000 Binary files a/.venv311/Scripts/uvicorn.exe and /dev/null differ diff --git a/.venv311/Scripts/watchfiles.exe b/.venv311/Scripts/watchfiles.exe deleted file mode 100644 index a68daa818..000000000 Binary files a/.venv311/Scripts/watchfiles.exe and /dev/null differ diff --git a/.venv311/Scripts/websockets.exe b/.venv311/Scripts/websockets.exe deleted file mode 100644 index d34f47e90..000000000 Binary files a/.venv311/Scripts/websockets.exe and /dev/null differ diff --git a/.venv311/Scripts/wheel.exe b/.venv311/Scripts/wheel.exe deleted file mode 100644 index 90e13abb2..000000000 Binary files a/.venv311/Scripts/wheel.exe and /dev/null differ diff --git a/.venv311/Scripts/wsdump.exe b/.venv311/Scripts/wsdump.exe deleted file mode 100644 index c0f7590ce..000000000 Binary files a/.venv311/Scripts/wsdump.exe and /dev/null differ diff --git a/.venv311/pyvenv.cfg b/.venv311/pyvenv.cfg deleted file mode 100644 index 9eb1a3dfd..000000000 --- a/.venv311/pyvenv.cfg +++ /dev/null @@ -1,5 +0,0 @@ -home = C:\Users\Administrator\AppData\Local\Programs\Python\Python311 -include-system-site-packages = false -version = 3.11.9 -executable = C:\Users\Administrator\AppData\Local\Programs\Python\Python311\python.exe -command = C:\Users\Administrator\AppData\Local\Programs\Python\Python311\python.exe -m venv D:\code\MoFox_Bot\.venv311 diff --git a/.venv311/share/man/man1/isympy.1 b/.venv311/share/man/man1/isympy.1 deleted file mode 100644 index 0ff966158..000000000 --- a/.venv311/share/man/man1/isympy.1 +++ /dev/null @@ -1,188 +0,0 @@ -'\" -*- coding: us-ascii -*- -.if \n(.g .ds T< \\FC -.if \n(.g .ds T> \\F[\n[.fam]] -.de URL -\\$2 \(la\\$1\(ra\\$3 -.. -.if \n(.g .mso www.tmac -.TH isympy 1 2007-10-8 "" "" -.SH NAME -isympy \- interactive shell for SymPy -.SH SYNOPSIS -'nh -.fi -.ad l -\fBisympy\fR \kx -.if (\nx>(\n(.l/2)) .nr x (\n(.l/5) -'in \n(.iu+\nxu -[\fB-c\fR | \fB--console\fR] [\fB-p\fR ENCODING | \fB--pretty\fR ENCODING] [\fB-t\fR TYPE | \fB--types\fR TYPE] [\fB-o\fR ORDER | \fB--order\fR ORDER] [\fB-q\fR | \fB--quiet\fR] [\fB-d\fR | \fB--doctest\fR] [\fB-C\fR | \fB--no-cache\fR] [\fB-a\fR | \fB--auto\fR] [\fB-D\fR | \fB--debug\fR] [ --- | PYTHONOPTIONS] -'in \n(.iu-\nxu -.ad b -'hy -'nh -.fi -.ad l -\fBisympy\fR \kx -.if (\nx>(\n(.l/2)) .nr x (\n(.l/5) -'in \n(.iu+\nxu -[ -{\fB-h\fR | \fB--help\fR} -| -{\fB-v\fR | \fB--version\fR} -] -'in \n(.iu-\nxu -.ad b -'hy -.SH DESCRIPTION -isympy is a Python shell for SymPy. It is just a normal python shell -(ipython shell if you have the ipython package installed) that executes -the following commands so that you don't have to: -.PP -.nf -\*(T< ->>> from __future__ import division ->>> from sympy import * ->>> x, y, z = symbols("x,y,z") ->>> k, m, n = symbols("k,m,n", integer=True) - \*(T> -.fi -.PP -So starting isympy is equivalent to starting python (or ipython) and -executing the above commands by hand. It is intended for easy and quick -experimentation with SymPy. For more complicated programs, it is recommended -to write a script and import things explicitly (using the "from sympy -import sin, log, Symbol, ..." idiom). -.SH OPTIONS -.TP -\*(T<\fB\-c \fR\*(T>\fISHELL\fR, \*(T<\fB\-\-console=\fR\*(T>\fISHELL\fR -Use the specified shell (python or ipython) as -console backend instead of the default one (ipython -if present or python otherwise). - -Example: isympy -c python - -\fISHELL\fR could be either -\&'ipython' or 'python' -.TP -\*(T<\fB\-p \fR\*(T>\fIENCODING\fR, \*(T<\fB\-\-pretty=\fR\*(T>\fIENCODING\fR -Setup pretty printing in SymPy. By default, the most pretty, unicode -printing is enabled (if the terminal supports it). You can use less -pretty ASCII printing instead or no pretty printing at all. - -Example: isympy -p no - -\fIENCODING\fR must be one of 'unicode', -\&'ascii' or 'no'. -.TP -\*(T<\fB\-t \fR\*(T>\fITYPE\fR, \*(T<\fB\-\-types=\fR\*(T>\fITYPE\fR -Setup the ground types for the polys. By default, gmpy ground types -are used if gmpy2 or gmpy is installed, otherwise it falls back to python -ground types, which are a little bit slower. You can manually -choose python ground types even if gmpy is installed (e.g., for testing purposes). - -Note that sympy ground types are not supported, and should be used -only for experimental purposes. - -Note that the gmpy1 ground type is primarily intended for testing; it the -use of gmpy even if gmpy2 is available. - -This is the same as setting the environment variable -SYMPY_GROUND_TYPES to the given ground type (e.g., -SYMPY_GROUND_TYPES='gmpy') - -The ground types can be determined interactively from the variable -sympy.polys.domains.GROUND_TYPES inside the isympy shell itself. - -Example: isympy -t python - -\fITYPE\fR must be one of 'gmpy', -\&'gmpy1' or 'python'. -.TP -\*(T<\fB\-o \fR\*(T>\fIORDER\fR, \*(T<\fB\-\-order=\fR\*(T>\fIORDER\fR -Setup the ordering of terms for printing. The default is lex, which -orders terms lexicographically (e.g., x**2 + x + 1). You can choose -other orderings, such as rev-lex, which will use reverse -lexicographic ordering (e.g., 1 + x + x**2). - -Note that for very large expressions, ORDER='none' may speed up -printing considerably, with the tradeoff that the order of the terms -in the printed expression will have no canonical order - -Example: isympy -o rev-lax - -\fIORDER\fR must be one of 'lex', 'rev-lex', 'grlex', -\&'rev-grlex', 'grevlex', 'rev-grevlex', 'old', or 'none'. -.TP -\*(T<\fB\-q\fR\*(T>, \*(T<\fB\-\-quiet\fR\*(T> -Print only Python's and SymPy's versions to stdout at startup, and nothing else. -.TP -\*(T<\fB\-d\fR\*(T>, \*(T<\fB\-\-doctest\fR\*(T> -Use the same format that should be used for doctests. This is -equivalent to '\fIisympy -c python -p no\fR'. -.TP -\*(T<\fB\-C\fR\*(T>, \*(T<\fB\-\-no\-cache\fR\*(T> -Disable the caching mechanism. Disabling the cache may slow certain -operations down considerably. This is useful for testing the cache, -or for benchmarking, as the cache can result in deceptive benchmark timings. - -This is the same as setting the environment variable SYMPY_USE_CACHE -to 'no'. -.TP -\*(T<\fB\-a\fR\*(T>, \*(T<\fB\-\-auto\fR\*(T> -Automatically create missing symbols. Normally, typing a name of a -Symbol that has not been instantiated first would raise NameError, -but with this option enabled, any undefined name will be -automatically created as a Symbol. This only works in IPython 0.11. - -Note that this is intended only for interactive, calculator style -usage. In a script that uses SymPy, Symbols should be instantiated -at the top, so that it's clear what they are. - -This will not override any names that are already defined, which -includes the single character letters represented by the mnemonic -QCOSINE (see the "Gotchas and Pitfalls" document in the -documentation). You can delete existing names by executing "del -name" in the shell itself. You can see if a name is defined by typing -"'name' in globals()". - -The Symbols that are created using this have default assumptions. -If you want to place assumptions on symbols, you should create them -using symbols() or var(). - -Finally, this only works in the top level namespace. So, for -example, if you define a function in isympy with an undefined -Symbol, it will not work. -.TP -\*(T<\fB\-D\fR\*(T>, \*(T<\fB\-\-debug\fR\*(T> -Enable debugging output. This is the same as setting the -environment variable SYMPY_DEBUG to 'True'. The debug status is set -in the variable SYMPY_DEBUG within isympy. -.TP --- \fIPYTHONOPTIONS\fR -These options will be passed on to \fIipython (1)\fR shell. -Only supported when ipython is being used (standard python shell not supported). - -Two dashes (--) are required to separate \fIPYTHONOPTIONS\fR -from the other isympy options. - -For example, to run iSymPy without startup banner and colors: - -isympy -q -c ipython -- --colors=NoColor -.TP -\*(T<\fB\-h\fR\*(T>, \*(T<\fB\-\-help\fR\*(T> -Print help output and exit. -.TP -\*(T<\fB\-v\fR\*(T>, \*(T<\fB\-\-version\fR\*(T> -Print isympy version information and exit. -.SH FILES -.TP -\*(T<\fI${HOME}/.sympy\-history\fR\*(T> -Saves the history of commands when using the python -shell as backend. -.SH BUGS -The upstreams BTS can be found at \(lahttps://github.com/sympy/sympy/issues\(ra -Please report all bugs that you find in there, this will help improve -the overall quality of SymPy. -.SH "SEE ALSO" -\fBipython\fR(1), \fBpython\fR(1) diff --git a/.venv311/share/man/man1/ttx.1 b/.venv311/share/man/man1/ttx.1 deleted file mode 100644 index bba23b5e5..000000000 --- a/.venv311/share/man/man1/ttx.1 +++ /dev/null @@ -1,225 +0,0 @@ -.Dd May 18, 2004 -.\" ttx is not specific to any OS, but contrary to what groff_mdoc(7) -.\" seems to imply, entirely omitting the .Os macro causes 'BSD' to -.\" be used, so I give a zero-width space as its argument. -.Os \& -.\" The "FontTools Manual" argument apparently has no effect in -.\" groff 1.18.1. I think it is a bug in the -mdoc groff package. -.Dt TTX 1 "FontTools Manual" -.Sh NAME -.Nm ttx -.Nd tool for manipulating TrueType and OpenType fonts -.Sh SYNOPSIS -.Nm -.Bk -.Op Ar option ... -.Ek -.Bk -.Ar file ... -.Ek -.Sh DESCRIPTION -.Nm -is a tool for manipulating TrueType and OpenType fonts. It can convert -TrueType and OpenType fonts to and from an -.Tn XML Ns -based format called -.Tn TTX . -.Tn TTX -files have a -.Ql .ttx -extension. -.Pp -For each -.Ar file -argument it is given, -.Nm -detects whether it is a -.Ql .ttf , -.Ql .otf -or -.Ql .ttx -file and acts accordingly: if it is a -.Ql .ttf -or -.Ql .otf -file, it generates a -.Ql .ttx -file; if it is a -.Ql .ttx -file, it generates a -.Ql .ttf -or -.Ql .otf -file. -.Pp -By default, every output file is created in the same directory as the -corresponding input file and with the same name except for the -extension, which is substituted appropriately. -.Nm -never overwrites existing files; if necessary, it appends a suffix to -the output file name before the extension, as in -.Pa Arial#1.ttf . -.Ss "General options" -.Bl -tag -width ".Fl t Ar table" -.It Fl h -Display usage information. -.It Fl d Ar dir -Write the output files to directory -.Ar dir -instead of writing every output file to the same directory as the -corresponding input file. -.It Fl o Ar file -Write the output to -.Ar file -instead of writing it to the same directory as the -corresponding input file. -.It Fl v -Be verbose. Write more messages to the standard output describing what -is being done. -.It Fl a -Allow virtual glyphs ID's on compile or decompile. -.El -.Ss "Dump options" -The following options control the process of dumping font files -(TrueType or OpenType) to -.Tn TTX -files. -.Bl -tag -width ".Fl t Ar table" -.It Fl l -List table information. Instead of dumping the font to a -.Tn TTX -file, display minimal information about each table. -.It Fl t Ar table -Dump table -.Ar table . -This option may be given multiple times to dump several tables at -once. When not specified, all tables are dumped. -.It Fl x Ar table -Exclude table -.Ar table -from the list of tables to dump. This option may be given multiple -times to exclude several tables from the dump. The -.Fl t -and -.Fl x -options are mutually exclusive. -.It Fl s -Split tables. Dump each table to a separate -.Tn TTX -file and write (under the name that would have been used for the output -file if the -.Fl s -option had not been given) one small -.Tn TTX -file containing references to the individual table dump files. This -file can be used as input to -.Nm -as long as the referenced files can be found in the same directory. -.It Fl i -.\" XXX: I suppose OpenType programs (exist and) are also affected. -Don't disassemble TrueType instructions. When this option is specified, -all TrueType programs (glyph programs, the font program and the -pre-program) are written to the -.Tn TTX -file as hexadecimal data instead of -assembly. This saves some time and results in smaller -.Tn TTX -files. -.It Fl y Ar n -When decompiling a TrueType Collection (TTC) file, -decompile font number -.Ar n , -starting from 0. -.El -.Ss "Compilation options" -The following options control the process of compiling -.Tn TTX -files into font files (TrueType or OpenType): -.Bl -tag -width ".Fl t Ar table" -.It Fl m Ar fontfile -Merge the input -.Tn TTX -file -.Ar file -with -.Ar fontfile . -No more than one -.Ar file -argument can be specified when this option is used. -.It Fl b -Don't recalculate glyph bounding boxes. Use the values in the -.Tn TTX -file as is. -.El -.Sh "THE TTX FILE FORMAT" -You can find some information about the -.Tn TTX -file format in -.Pa documentation.html . -In particular, you will find in that file the list of tables understood by -.Nm -and the relations between TrueType GlyphIDs and the glyph names used in -.Tn TTX -files. -.Sh EXAMPLES -In the following examples, all files are read from and written to the -current directory. Additionally, the name given for the output file -assumes in every case that it did not exist before -.Nm -was invoked. -.Pp -Dump the TrueType font contained in -.Pa FreeSans.ttf -to -.Pa FreeSans.ttx : -.Pp -.Dl ttx FreeSans.ttf -.Pp -Compile -.Pa MyFont.ttx -into a TrueType or OpenType font file: -.Pp -.Dl ttx MyFont.ttx -.Pp -List the tables in -.Pa FreeSans.ttf -along with some information: -.Pp -.Dl ttx -l FreeSans.ttf -.Pp -Dump the -.Sq cmap -table from -.Pa FreeSans.ttf -to -.Pa FreeSans.ttx : -.Pp -.Dl ttx -t cmap FreeSans.ttf -.Sh NOTES -On MS\-Windows and MacOS, -.Nm -is available as a graphical application to which files can be dropped. -.Sh SEE ALSO -.Pa documentation.html -.Pp -.Xr fontforge 1 , -.Xr ftinfo 1 , -.Xr gfontview 1 , -.Xr xmbdfed 1 , -.Xr Font::TTF 3pm -.Sh AUTHORS -.Nm -was written by -.An -nosplit -.An "Just van Rossum" Aq just@letterror.com . -.Pp -This manual page was written by -.An "Florent Rougon" Aq f.rougon@free.fr -for the Debian GNU/Linux system based on the existing FontTools -documentation. It may be freely used, modified and distributed without -restrictions. -.\" For Emacs: -.\" Local Variables: -.\" fill-column: 72 -.\" sentence-end: "[.?!][]\"')}]*\\($\\| $\\| \\| \\)[ \n]*" -.\" sentence-end-double-space: t -.\" End: \ No newline at end of file diff --git a/bot.py b/bot.py index 97bb68f0c..da2391a0d 100644 --- a/bot.py +++ b/bot.py @@ -215,12 +215,6 @@ class ShutdownManager: logger.info("正在优雅关闭麦麦...") start_time = time.time() - # 停止WebUI开发服务(如果有) - try: - await WebUIManager.stop_dev_server() - except Exception as e: - logger.warning(f"停止WebUI开发服务时出错: {e}") - # 停止异步任务 tasks_stopped = await TaskManager.stop_async_tasks() @@ -361,169 +355,6 @@ class EasterEgg: logger.info(rainbow_text) -class WebUIManager: - """WebUI 开发服务器管理""" - - _process = None - _drain_task = None - - @staticmethod - async def start_dev_server(timeout: float = 60.0) -> bool: - """启动 ../webui 的 `npm run dev` 并在超时内检测是否启动成功。 - - 返回 True 表示检测到成功信号;False 表示失败/超时/进程退出。 - """ - try: - webui_dir = Path(__file__).resolve().parent.parent / "webui" - if not webui_dir.exists(): - logger.error(f"未找到 webui 目录: {webui_dir}") - return False - - if WebUIManager._process and WebUIManager._process.returncode is None: - logger.info("WebUI 开发服务器已在运行,跳过重复启动") - return True - - logger.info(f"正在启动 WebUI 开发服务器: npm run dev (cwd={webui_dir})") - npm_exe = "npm.cmd" if platform.system().lower() == "windows" else "npm" - proc = await asyncio.create_subprocess_exec( - npm_exe, - "run", - "dev", - cwd=str(webui_dir), - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.STDOUT, - ) - WebUIManager._process = proc - - success_keywords = [ - "compiled successfully", - "ready in", - "local:", - "listening on", - "running at:", - "started server", - "app running at:", - "ready - started server", - ] - failure_keywords = [ - "err!", - "error", - "eaddrinuse", - "address already in use", - "syntaxerror", - "fatal", - ] - - start_ts = time.time() - detected_success = False - - async def _drain_and_detect(): - nonlocal detected_success - try: - while True: - line = await proc.stdout.readline() - if not line: - break - text = line.decode(errors="ignore").rstrip() - logger.info(f"[webui] {text}") - low = text.lower() - if any(k in low for k in success_keywords): - detected_success = True - break - if any(k in low for k in failure_keywords): - detected_success = False - break - except Exception as e: - logger.debug(f"webui 输出读取异常: {e}") - - # 在检测窗口内读取输出判定成功/失败 - while True: - if proc.returncode is not None: - if proc.returncode != 0: - logger.error(f"WebUI 进程提前退出,退出码: {proc.returncode}") - else: - logger.warning("WebUI 进程已退出") - break - - # 使用短期读取以便及时检查超时 - try: - line = await asyncio.wait_for(proc.stdout.readline(), timeout=1.0) - except asyncio.TimeoutError: - line = b"" - - if line: - text = line.decode(errors="ignore").rstrip() - logger.info(f"[webui] {text}") - low = text.lower() - if any(k in low for k in success_keywords): - detected_success = True - break - if any(k in low for k in failure_keywords): - detected_success = False - break - - if time.time() - start_ts > timeout: - logger.warning("WebUI 启动检测超时") - break - - # 后台持续清空输出,避免缓冲区阻塞 - async def _drain_rest(): - try: - while True: - line = await proc.stdout.readline() - if not line: - break - text = line.decode(errors="ignore").rstrip() - logger.info(f"[webui] {text}") - except Exception as e: - logger.debug(f"webui 日志读取停止: {e}") - - WebUIManager._drain_task = asyncio.create_task(_drain_rest()) - - return bool(detected_success) - - except FileNotFoundError: - logger.error("未找到 npm,请确认已安装 Node.js 并将 npm 加入 PATH") - return False - except Exception as e: - logger.error(f"启动 WebUI 开发服务器失败: {e}") - return False - - @staticmethod - async def stop_dev_server(timeout: float = 5.0) -> bool: - """停止 WebUI 开发服务器(如果在运行)。""" - proc = WebUIManager._process - if not proc: - return True - try: - if proc.returncode is None: - try: - proc.terminate() - except ProcessLookupError: - pass - except Exception as e: - logger.debug(f"发送终止信号失败: {e}") - - try: - await asyncio.wait_for(proc.wait(), timeout=timeout) - except asyncio.TimeoutError: - try: - proc.kill() - except Exception: - pass - # 处理输出清空任务 - if WebUIManager._drain_task and not WebUIManager._drain_task.done(): - WebUIManager._drain_task.cancel() - try: - await WebUIManager._drain_task - except Exception: - pass - logger.info("WebUI 开发服务器已停止") - return True - finally: - WebUIManager._process = None - WebUIManager._drain_task = None - class MaiBotMain: """麦麦机器人主程序类""" @@ -624,13 +455,6 @@ async def main_async(): # 确保环境文件存在 ConfigManager.ensure_env_file() - # 启动 WebUI 开发服务器 - webui_ok = await WebUIManager.start_dev_server(timeout=60) - if webui_ok: - logger.info("WebUI 启动成功,继续下一步骤") - else: - logger.error("WebUI 启动失败,继续下一步骤") - # 创建主程序实例并执行初始化 maibot = MaiBotMain() main_system = await maibot.run_sync_init()