perf(bootstrap): Reduce Bootstrap CSS de 227KB a 145KB con PurgeCSS
- Genera bootstrap-subset.min.css con solo clases usadas (36% reduccion) - Actualiza enqueue-scripts.php para usar el subset - Agrega scripts de build: npm run build:bootstrap - Mejora LCP al reducir tiempo de parseo CSS Impacto estimado: - Bootstrap: 227KB -> 145KB (-82KB) - Tiempo parseo CSS: ~800ms -> ~500ms - LCP: mejora esperada ~300-500ms 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
20
Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css
vendored
Normal file
20
Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -95,17 +95,22 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_fonts', 1);
|
|||||||
/**
|
/**
|
||||||
* Enqueue Bootstrap 5 styles and scripts
|
* Enqueue Bootstrap 5 styles and scripts
|
||||||
*
|
*
|
||||||
|
* OPTIMIZACIÓN LCP (PageSpeed Fase 5):
|
||||||
|
* - Usa bootstrap-subset.min.css (145KB) en lugar de bootstrap.min.css (227KB)
|
||||||
|
* - Reducción: 36% menos CSS para parsear
|
||||||
|
* - Generado con PurgeCSS: node build-bootstrap-subset.js
|
||||||
|
*
|
||||||
* NOTA: Bootstrap debe cargar BLOQUEANTE (media='all').
|
* NOTA: Bootstrap debe cargar BLOQUEANTE (media='all').
|
||||||
* Diferirlo causa CLS alto (0.954) por layout shifts.
|
* Diferirlo causa CLS alto (0.954) por layout shifts.
|
||||||
* CriticalBootstrapService queda disponible para futuras optimizaciones.
|
|
||||||
*/
|
*/
|
||||||
function roi_enqueue_bootstrap() {
|
function roi_enqueue_bootstrap() {
|
||||||
// Bootstrap CSS - BLOQUEANTE para evitar CLS
|
// Bootstrap CSS SUBSET - BLOQUEANTE para evitar CLS
|
||||||
|
// Original: 227KB -> Subset: 145KB (36% reducción)
|
||||||
wp_enqueue_style(
|
wp_enqueue_style(
|
||||||
'roi-bootstrap',
|
'roi-bootstrap',
|
||||||
get_template_directory_uri() . '/Assets/Vendor/Bootstrap/Css/bootstrap.min.css',
|
get_template_directory_uri() . '/Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css',
|
||||||
array('roi-fonts'),
|
array('roi-fonts'),
|
||||||
'5.3.2',
|
'5.3.2-subset',
|
||||||
'all' // Bloqueante - diferirlo causa CLS alto
|
'all' // Bloqueante - diferirlo causa CLS alto
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
290
build-bootstrap-subset.js
Normal file
290
build-bootstrap-subset.js
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* Build Bootstrap Subset Script
|
||||||
|
*
|
||||||
|
* Genera un subset de Bootstrap con SOLO las clases usadas en el tema.
|
||||||
|
*
|
||||||
|
* USO:
|
||||||
|
* node build-bootstrap-subset.js
|
||||||
|
*
|
||||||
|
* OUTPUT:
|
||||||
|
* Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { PurgeCSS } = require('purgecss');
|
||||||
|
const { globSync } = require('glob');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function buildBootstrapSubset() {
|
||||||
|
console.log('='.repeat(60));
|
||||||
|
console.log('Building Bootstrap Subset for ROI Theme');
|
||||||
|
console.log('='.repeat(60));
|
||||||
|
|
||||||
|
const themeDir = __dirname;
|
||||||
|
const inputFile = path.join(themeDir, 'Assets/Vendor/Bootstrap/Css/bootstrap.min.css');
|
||||||
|
const outputFile = path.join(themeDir, 'Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css');
|
||||||
|
|
||||||
|
// Verificar que existe el archivo de entrada
|
||||||
|
if (!fs.existsSync(inputFile)) {
|
||||||
|
console.error('ERROR: bootstrap.min.css not found at:', inputFile);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputSize = fs.statSync(inputFile).size;
|
||||||
|
console.log(`Input: bootstrap.min.css (${(inputSize / 1024).toFixed(2)} KB)`);
|
||||||
|
|
||||||
|
// Encontrar archivos PHP y JS manualmente
|
||||||
|
console.log('\nScanning for PHP and JS files...');
|
||||||
|
|
||||||
|
const patterns = [
|
||||||
|
'*.php',
|
||||||
|
'Public/**/*.php',
|
||||||
|
'Admin/**/*.php',
|
||||||
|
'Inc/**/*.php',
|
||||||
|
'Shared/**/*.php',
|
||||||
|
'template-parts/**/*.php',
|
||||||
|
'Assets/js/**/*.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
let contentFiles = [];
|
||||||
|
for (const pattern of patterns) {
|
||||||
|
const files = globSync(pattern, { cwd: themeDir, absolute: true });
|
||||||
|
contentFiles = contentFiles.concat(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Found ${contentFiles.length} files to analyze`);
|
||||||
|
|
||||||
|
if (contentFiles.length === 0) {
|
||||||
|
console.error('ERROR: No content files found. Check glob patterns.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostrar algunos archivos encontrados
|
||||||
|
console.log('\nSample files:');
|
||||||
|
contentFiles.slice(0, 5).forEach(f => console.log(' -', path.relative(themeDir, f)));
|
||||||
|
if (contentFiles.length > 5) {
|
||||||
|
console.log(` ... and ${contentFiles.length - 5} more`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const purgeCSSResult = await new PurgeCSS().purge({
|
||||||
|
css: [inputFile],
|
||||||
|
content: contentFiles,
|
||||||
|
|
||||||
|
// Safelist: Clases que SIEMPRE deben incluirse
|
||||||
|
safelist: {
|
||||||
|
standard: [
|
||||||
|
// Estados de navbar scroll (JavaScript)
|
||||||
|
'scrolled',
|
||||||
|
'navbar-scrolled',
|
||||||
|
|
||||||
|
// Bootstrap Collapse (JavaScript)
|
||||||
|
'show',
|
||||||
|
'showing',
|
||||||
|
'hiding',
|
||||||
|
'collapse',
|
||||||
|
'collapsing',
|
||||||
|
|
||||||
|
// Estados de dropdown
|
||||||
|
'dropdown-menu',
|
||||||
|
'dropdown-item',
|
||||||
|
'dropdown-toggle',
|
||||||
|
|
||||||
|
// Estados de form
|
||||||
|
'is-valid',
|
||||||
|
'is-invalid',
|
||||||
|
'was-validated',
|
||||||
|
|
||||||
|
// Visually hidden (accesibilidad)
|
||||||
|
'visually-hidden',
|
||||||
|
'visually-hidden-focusable',
|
||||||
|
|
||||||
|
// Screen reader
|
||||||
|
'sr-only',
|
||||||
|
|
||||||
|
// Container
|
||||||
|
'container',
|
||||||
|
'container-fluid',
|
||||||
|
|
||||||
|
// Row
|
||||||
|
'row',
|
||||||
|
|
||||||
|
// Display
|
||||||
|
'd-flex',
|
||||||
|
'd-none',
|
||||||
|
'd-block',
|
||||||
|
'd-inline-block',
|
||||||
|
'd-inline',
|
||||||
|
'd-grid',
|
||||||
|
|
||||||
|
// Common spacing
|
||||||
|
'mb-0', 'mb-1', 'mb-2', 'mb-3', 'mb-4', 'mb-5',
|
||||||
|
'mt-0', 'mt-1', 'mt-2', 'mt-3', 'mt-4', 'mt-5',
|
||||||
|
'me-0', 'me-1', 'me-2', 'me-3', 'me-4', 'me-5',
|
||||||
|
'ms-0', 'ms-1', 'ms-2', 'ms-3', 'ms-4', 'ms-5',
|
||||||
|
'mx-auto',
|
||||||
|
'py-0', 'py-1', 'py-2', 'py-3', 'py-4', 'py-5',
|
||||||
|
'px-0', 'px-1', 'px-2', 'px-3', 'px-4', 'px-5',
|
||||||
|
'p-0', 'p-1', 'p-2', 'p-3', 'p-4', 'p-5',
|
||||||
|
'gap-0', 'gap-1', 'gap-2', 'gap-3', 'gap-4', 'gap-5',
|
||||||
|
'g-0', 'g-1', 'g-2', 'g-3', 'g-4', 'g-5',
|
||||||
|
|
||||||
|
// Flex
|
||||||
|
'flex-wrap',
|
||||||
|
'flex-nowrap',
|
||||||
|
'flex-column',
|
||||||
|
'flex-row',
|
||||||
|
'justify-content-center',
|
||||||
|
'justify-content-between',
|
||||||
|
'justify-content-start',
|
||||||
|
'justify-content-end',
|
||||||
|
'align-items-center',
|
||||||
|
'align-items-start',
|
||||||
|
'align-items-end',
|
||||||
|
|
||||||
|
// Text
|
||||||
|
'text-center',
|
||||||
|
'text-start',
|
||||||
|
'text-end',
|
||||||
|
'text-white',
|
||||||
|
'text-muted',
|
||||||
|
'fw-bold',
|
||||||
|
'fw-normal',
|
||||||
|
'small',
|
||||||
|
|
||||||
|
// Images
|
||||||
|
'img-fluid',
|
||||||
|
|
||||||
|
// Border/rounded
|
||||||
|
'rounded',
|
||||||
|
'rounded-circle',
|
||||||
|
'border',
|
||||||
|
'border-0',
|
||||||
|
|
||||||
|
// Shadow
|
||||||
|
'shadow',
|
||||||
|
'shadow-sm',
|
||||||
|
'shadow-lg',
|
||||||
|
|
||||||
|
// Width
|
||||||
|
'w-100',
|
||||||
|
'w-auto',
|
||||||
|
'h-100',
|
||||||
|
'h-auto',
|
||||||
|
],
|
||||||
|
|
||||||
|
deep: [
|
||||||
|
// Grid responsive
|
||||||
|
/^col-/,
|
||||||
|
/^col$/,
|
||||||
|
|
||||||
|
// Display responsive
|
||||||
|
/^d-[a-z]+-/,
|
||||||
|
|
||||||
|
// Navbar responsive
|
||||||
|
/^navbar-expand/,
|
||||||
|
/^navbar-/,
|
||||||
|
|
||||||
|
// Responsive margins/padding
|
||||||
|
/^m[tbsexy]?-[a-z]+-/,
|
||||||
|
/^p[tbsexy]?-[a-z]+-/,
|
||||||
|
|
||||||
|
// Text responsive
|
||||||
|
/^text-[a-z]+-/,
|
||||||
|
|
||||||
|
// Flex responsive
|
||||||
|
/^flex-[a-z]+-/,
|
||||||
|
/^justify-content-[a-z]+-/,
|
||||||
|
/^align-items-[a-z]+-/,
|
||||||
|
],
|
||||||
|
|
||||||
|
greedy: [
|
||||||
|
// Form controls
|
||||||
|
/form-/,
|
||||||
|
/input-/,
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
/btn/,
|
||||||
|
|
||||||
|
// Cards
|
||||||
|
/card/,
|
||||||
|
|
||||||
|
// Navbar
|
||||||
|
/navbar/,
|
||||||
|
/nav-/,
|
||||||
|
|
||||||
|
// Tables
|
||||||
|
/table/,
|
||||||
|
|
||||||
|
// Alerts
|
||||||
|
/alert/,
|
||||||
|
|
||||||
|
// Badges
|
||||||
|
/badge/,
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
/list-/,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Mantener variables CSS de Bootstrap
|
||||||
|
variables: true,
|
||||||
|
|
||||||
|
// Mantener keyframes
|
||||||
|
keyframes: true,
|
||||||
|
|
||||||
|
// Mantener font-face
|
||||||
|
fontFace: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (purgeCSSResult.length === 0 || !purgeCSSResult[0].css) {
|
||||||
|
console.error('ERROR: PurgeCSS returned empty result');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agregar header al CSS generado
|
||||||
|
const header = `/**
|
||||||
|
* Bootstrap 5.3.2 Subset - ROI Theme
|
||||||
|
*
|
||||||
|
* Generado automáticamente con PurgeCSS
|
||||||
|
* Contiene SOLO las clases Bootstrap usadas en el tema.
|
||||||
|
*
|
||||||
|
* Original: ${(inputSize / 1024).toFixed(2)} KB
|
||||||
|
* Subset: ${(purgeCSSResult[0].css.length / 1024).toFixed(2)} KB
|
||||||
|
* Reduccion: ${(100 - (purgeCSSResult[0].css.length / inputSize * 100)).toFixed(1)}%
|
||||||
|
*
|
||||||
|
* Generado: ${new Date().toISOString()}
|
||||||
|
*
|
||||||
|
* Para regenerar:
|
||||||
|
* node build-bootstrap-subset.js
|
||||||
|
*/
|
||||||
|
`;
|
||||||
|
|
||||||
|
const outputCSS = header + purgeCSSResult[0].css;
|
||||||
|
|
||||||
|
// Escribir archivo
|
||||||
|
fs.writeFileSync(outputFile, outputCSS);
|
||||||
|
|
||||||
|
const outputSize = fs.statSync(outputFile).size;
|
||||||
|
const reduction = ((1 - outputSize / inputSize) * 100).toFixed(1);
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('SUCCESS!');
|
||||||
|
console.log('-'.repeat(60));
|
||||||
|
console.log(`Output: bootstrap-subset.min.css (${(outputSize / 1024).toFixed(2)} KB)`);
|
||||||
|
console.log(`Reduction: ${reduction}% smaller`);
|
||||||
|
console.log('-'.repeat(60));
|
||||||
|
console.log('');
|
||||||
|
console.log('Next steps:');
|
||||||
|
console.log('1. Update Inc/enqueue-scripts.php to use bootstrap-subset.min.css');
|
||||||
|
console.log('2. Test the theme thoroughly');
|
||||||
|
console.log('3. Run PageSpeed Insights to verify improvement');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('ERROR:', error.message);
|
||||||
|
console.error(error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildBootstrapSubset();
|
||||||
674
package-lock.json
generated
Normal file
674
package-lock.json
generated
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
{
|
||||||
|
"name": "roi-theme",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "roi-theme",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"glob": "^13.0.0",
|
||||||
|
"purgecss": "^7.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@isaacs/balanced-match": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@isaacs/brace-expansion": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@isaacs/balanced-match": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@isaacs/cliui": {
|
||||||
|
"version": "8.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
|
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"string-width": "^5.1.2",
|
||||||
|
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||||
|
"strip-ansi": "^7.0.1",
|
||||||
|
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
|
||||||
|
"wrap-ansi": "^8.1.0",
|
||||||
|
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-regex": {
|
||||||
|
"version": "6.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||||
|
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "6.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||||
|
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "12.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||||
|
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cross-spawn": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cssesc": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"cssesc": "bin/cssesc"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eastasianwidth": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/emoji-regex": {
|
||||||
|
"version": "9.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||||
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/foreground-child": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.6",
|
||||||
|
"signal-exit": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/glob": {
|
||||||
|
"version": "13.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
|
||||||
|
"integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"minimatch": "^10.1.1",
|
||||||
|
"minipass": "^7.1.2",
|
||||||
|
"path-scurry": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-fullwidth-code-point": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/jackspeak": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@isaacs/cliui": "^8.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lru-cache": {
|
||||||
|
"version": "11.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz",
|
||||||
|
"integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@isaacs/brace-expansion": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minipass": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16 || 14 >=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/package-json-from-dist": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0"
|
||||||
|
},
|
||||||
|
"node_modules/path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-scurry": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^11.0.0",
|
||||||
|
"minipass": "^7.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/picocolors": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/postcss": {
|
||||||
|
"version": "8.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||||
|
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.11",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"source-map-js": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postcss-selector-parser": {
|
||||||
|
"version": "6.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||||
|
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cssesc": "^3.0.0",
|
||||||
|
"util-deprecate": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/purgecss": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-4Ku8KoxNhOWi9X1XJ73XY5fv+I+hhTRedKpGs/2gaBKU8ijUiIKF/uyyIyh7Wo713bELSICF5/NswjcuOqYouQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^12.1.0",
|
||||||
|
"glob": "^11.0.0",
|
||||||
|
"postcss": "^8.4.47",
|
||||||
|
"postcss-selector-parser": "^6.1.2"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"purgecss": "bin/purgecss.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/purgecss/node_modules/glob": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BlueOak-1.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"foreground-child": "^3.3.1",
|
||||||
|
"jackspeak": "^4.1.1",
|
||||||
|
"minimatch": "^10.1.1",
|
||||||
|
"minipass": "^7.1.2",
|
||||||
|
"package-json-from-dist": "^1.0.0",
|
||||||
|
"path-scurry": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"glob": "dist/esm/bin.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/signal-exit": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string-width": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"eastasianwidth": "^0.2.0",
|
||||||
|
"emoji-regex": "^9.2.2",
|
||||||
|
"strip-ansi": "^7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string-width-cjs": {
|
||||||
|
"name": "string-width",
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string-width-cjs/node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/string-width-cjs/node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi-cjs": {
|
||||||
|
"name": "strip-ansi",
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/node-which"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^6.1.0",
|
||||||
|
"string-width": "^5.0.1",
|
||||||
|
"strip-ansi": "^7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs": {
|
||||||
|
"name": "wrap-ansi",
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^4.0.0",
|
||||||
|
"string-width": "^4.1.0",
|
||||||
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||||
|
"version": "4.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"emoji-regex": "^8.0.0",
|
||||||
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
|
"strip-ansi": "^6.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-regex": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
package.json
Normal file
26
package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "roi-theme",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "WordPress theme con Clean Architecture para analisisdepreciosunitarios.com",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build:bootstrap": "node build-bootstrap-subset.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/prime-leads-app/roi-theme.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/prime-leads-app/roi-theme/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/prime-leads-app/roi-theme#readme",
|
||||||
|
"description": "",
|
||||||
|
"devDependencies": {
|
||||||
|
"glob": "^13.0.0",
|
||||||
|
"purgecss": "^7.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
171
purgecss.config.js
Normal file
171
purgecss.config.js
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/**
|
||||||
|
* PurgeCSS Configuration for ROI Theme
|
||||||
|
*
|
||||||
|
* Genera un subset de Bootstrap con SOLO las clases usadas en el tema.
|
||||||
|
*
|
||||||
|
* USO:
|
||||||
|
* npx purgecss --config purgecss.config.js
|
||||||
|
*
|
||||||
|
* OUTPUT:
|
||||||
|
* Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css
|
||||||
|
*
|
||||||
|
* @see https://purgecss.com/configuration.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// CSS a procesar
|
||||||
|
css: ['Assets/Vendor/Bootstrap/Css/bootstrap.min.css'],
|
||||||
|
|
||||||
|
// Archivos a analizar para encontrar clases usadas
|
||||||
|
content: [
|
||||||
|
// Templates PHP principales
|
||||||
|
'*.php',
|
||||||
|
|
||||||
|
// Componentes Public (Renderers)
|
||||||
|
'Public/**/*.php',
|
||||||
|
|
||||||
|
// Componentes Admin (FormBuilders) - también usan Bootstrap
|
||||||
|
'Admin/**/*.php',
|
||||||
|
|
||||||
|
// Includes
|
||||||
|
'Inc/**/*.php',
|
||||||
|
|
||||||
|
// Templates parts
|
||||||
|
'template-parts/**/*.php',
|
||||||
|
|
||||||
|
// JavaScript (puede contener clases dinámicas)
|
||||||
|
'Assets/js/**/*.js',
|
||||||
|
],
|
||||||
|
|
||||||
|
// Output
|
||||||
|
output: 'Assets/Vendor/Bootstrap/Css/',
|
||||||
|
|
||||||
|
// Safelist: Clases que SIEMPRE deben incluirse aunque no se detecten
|
||||||
|
// (clases generadas dinámicamente, JavaScript, etc.)
|
||||||
|
safelist: {
|
||||||
|
// Clases exactas
|
||||||
|
standard: [
|
||||||
|
// Estados de navbar scroll (JavaScript)
|
||||||
|
'scrolled',
|
||||||
|
'navbar-scrolled',
|
||||||
|
|
||||||
|
// Bootstrap Collapse (JavaScript)
|
||||||
|
'show',
|
||||||
|
'showing',
|
||||||
|
'hiding',
|
||||||
|
'collapse',
|
||||||
|
'collapsing',
|
||||||
|
|
||||||
|
// Estados de dropdown
|
||||||
|
'dropdown-menu',
|
||||||
|
'dropdown-item',
|
||||||
|
'dropdown-toggle',
|
||||||
|
|
||||||
|
// Estados de form
|
||||||
|
'is-valid',
|
||||||
|
'is-invalid',
|
||||||
|
'was-validated',
|
||||||
|
|
||||||
|
// Visually hidden (accesibilidad)
|
||||||
|
'visually-hidden',
|
||||||
|
'visually-hidden-focusable',
|
||||||
|
|
||||||
|
// Screen reader
|
||||||
|
'sr-only',
|
||||||
|
],
|
||||||
|
|
||||||
|
// Patrones regex
|
||||||
|
deep: [
|
||||||
|
// Todas las variantes de col-* (grid responsive)
|
||||||
|
/^col-/,
|
||||||
|
|
||||||
|
// Todas las variantes de d-* (display)
|
||||||
|
/^d-/,
|
||||||
|
|
||||||
|
// Todas las variantes responsive de navbar
|
||||||
|
/^navbar-expand/,
|
||||||
|
|
||||||
|
// Margin/Padding responsive
|
||||||
|
/^m[tbsexy]?-/,
|
||||||
|
/^p[tbsexy]?-/,
|
||||||
|
|
||||||
|
// Gap utilities
|
||||||
|
/^gap-/,
|
||||||
|
/^g-/,
|
||||||
|
|
||||||
|
// Flex utilities
|
||||||
|
/^flex-/,
|
||||||
|
/^justify-/,
|
||||||
|
/^align-/,
|
||||||
|
|
||||||
|
// Text utilities
|
||||||
|
/^text-/,
|
||||||
|
/^fw-/,
|
||||||
|
/^fs-/,
|
||||||
|
|
||||||
|
// Background
|
||||||
|
/^bg-/,
|
||||||
|
|
||||||
|
// Border
|
||||||
|
/^border/,
|
||||||
|
/^rounded/,
|
||||||
|
|
||||||
|
// Shadow
|
||||||
|
/^shadow/,
|
||||||
|
|
||||||
|
// Width/Height
|
||||||
|
/^w-/,
|
||||||
|
/^h-/,
|
||||||
|
|
||||||
|
// Position
|
||||||
|
/^position-/,
|
||||||
|
/^top-/,
|
||||||
|
/^bottom-/,
|
||||||
|
/^start-/,
|
||||||
|
/^end-/,
|
||||||
|
|
||||||
|
// Overflow
|
||||||
|
/^overflow-/,
|
||||||
|
],
|
||||||
|
|
||||||
|
// Selectores con estos patrones en cualquier parte
|
||||||
|
greedy: [
|
||||||
|
// Form controls
|
||||||
|
/form-/,
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
/btn/,
|
||||||
|
|
||||||
|
// Cards
|
||||||
|
/card/,
|
||||||
|
|
||||||
|
// Navbar
|
||||||
|
/navbar/,
|
||||||
|
/nav-/,
|
||||||
|
|
||||||
|
// Tables
|
||||||
|
/table/,
|
||||||
|
|
||||||
|
// Alerts (usado en admin)
|
||||||
|
/alert/,
|
||||||
|
|
||||||
|
// Badges
|
||||||
|
/badge/,
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
/list-/,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Variables CSS de Bootstrap (mantener todas)
|
||||||
|
variables: true,
|
||||||
|
|
||||||
|
// Keyframes de animaciones
|
||||||
|
keyframes: true,
|
||||||
|
|
||||||
|
// Font faces
|
||||||
|
fontFace: true,
|
||||||
|
|
||||||
|
// Rejected (para debugging - genera archivo con clases eliminadas)
|
||||||
|
rejected: false,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user