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
|
||||
*
|
||||
* 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').
|
||||
* Diferirlo causa CLS alto (0.954) por layout shifts.
|
||||
* CriticalBootstrapService queda disponible para futuras optimizaciones.
|
||||
*/
|
||||
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(
|
||||
'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'),
|
||||
'5.3.2',
|
||||
'5.3.2-subset',
|
||||
'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