📦 添加虚拟环境和启动脚本

新增:
- backend/venv/ - Python 虚拟环境
- backend/start.sh - 启动脚本(使用虚拟环境)
- backend/requirements.txt - 依赖列表
- .gitignore - 忽略虚拟环境和缓存文件

说明:
- 每个项目使用独立虚拟环境
- 避免依赖冲突
- 启动脚本自动创建和激活虚拟环境
This commit is contained in:
2026-04-04 18:28:31 +08:00
parent 9ab279e1fe
commit 96f6318101
32058 changed files with 3949495 additions and 22 deletions

171
frontend/node_modules/cssnano/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,171 @@
'use strict';
const path = require('path');
/** @type {any} */
const postcss = require('postcss');
const yaml = require('yaml');
const { lilconfigSync } = require('lilconfig');
const cssnano = 'cssnano';
/** @typedef {{preset?: any, plugins?: any[], configFile?: string}} Options */
/**
* @param {string} moduleId
* @returns {boolean}
*/
function isResolvable(moduleId) {
try {
require.resolve(moduleId);
return true;
} catch (e) {
return false;
}
}
/**
* preset can be one of four possibilities:
* preset = 'default'
* preset = ['default', {}]
* preset = function <- to be invoked
* preset = {plugins: []} <- already invoked function
*
* @param {any} preset
* @return {[import('postcss').PluginCreator<any>, boolean | Record<string, any> | undefined][]}}
*/
function resolvePreset(preset) {
let fn, options;
if (Array.isArray(preset)) {
fn = preset[0];
options = preset[1];
} else {
fn = preset;
options = {};
}
// For JS setups where we invoked the preset already
if (preset.plugins) {
return preset.plugins;
}
// Provide an alias for the default preset, as it is built-in.
if (fn === 'default') {
return require('cssnano-preset-default')(options).plugins;
}
// For non-JS setups; we'll need to invoke the preset ourselves.
if (typeof fn === 'function') {
return fn(options).plugins;
}
// Try loading a preset from node_modules
if (isResolvable(fn)) {
return require(fn)(options).plugins;
}
const sugar = `cssnano-preset-${fn}`;
// Try loading a preset from node_modules (sugar)
if (isResolvable(sugar)) {
return require(sugar)(options).plugins;
}
// If all else fails, we probably have a typo in the config somewhere
throw new Error(
`Cannot load preset "${fn}". Please check your configuration for errors and try again.`
);
}
/**
* cssnano will look for configuration firstly as options passed
* directly to it, and failing this it will use lilconfig to
* load an external file.
* @param {Options} options
*/
function resolveConfig(options) {
if (options.preset) {
return resolvePreset(options.preset);
}
/** @type {string | undefined} */
let searchPath = process.cwd();
let configPath = undefined;
if (options.configFile) {
searchPath = undefined;
configPath = path.resolve(process.cwd(), options.configFile);
}
const configExplorer = lilconfigSync(cssnano, {
searchPlaces: [
'package.json',
'.cssnanorc',
'.cssnanorc.json',
'.cssnanorc.yaml',
'.cssnanorc.yml',
'.cssnanorc.js',
'cssnano.config.js',
],
loaders: {
'.yaml': (filepath, content) => yaml.parse(content),
'.yml': (filepath, content) => yaml.parse(content),
},
});
const config = configPath
? configExplorer.load(configPath)
: configExplorer.search(searchPath);
if (config === null) {
return resolvePreset('default');
}
return resolvePreset(config.config.preset || config.config);
}
/**
* @type {import('postcss').PluginCreator<Options>}
* @param {Options=} options
* @return {import('postcss').Processor}
*/
function cssnanoPlugin(options = {}) {
if (Array.isArray(options.plugins)) {
if (!options.preset || !options.preset.plugins) {
options.preset = { plugins: [] };
}
options.plugins.forEach((plugin) => {
if (Array.isArray(plugin)) {
const [pluginDef, opts = {}] = plugin;
if (typeof pluginDef === 'string' && isResolvable(pluginDef)) {
options.preset.plugins.push([require(pluginDef), opts]);
} else {
options.preset.plugins.push([pluginDef, opts]);
}
} else if (typeof plugin === 'string' && isResolvable(plugin)) {
options.preset.plugins.push([require(plugin), {}]);
} else {
options.preset.plugins.push([plugin, {}]);
}
});
}
const plugins = [];
const nanoPlugins = resolveConfig(options);
for (const nanoPlugin of nanoPlugins) {
if (Array.isArray(nanoPlugin)) {
const [processor, opts] = nanoPlugin;
if (
typeof opts === 'undefined' ||
(typeof opts === 'object' && !opts.exclude) ||
(typeof opts === 'boolean' && opts === true)
) {
plugins.push(processor(opts));
}
} else {
plugins.push(nanoPlugin);
}
}
return postcss(plugins);
}
cssnanoPlugin.postcss = true;
module.exports = cssnanoPlugin;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long