Bower Cheatsheet¶
Bower - Administrador de paquetes para la Web (Legacy)
Bower es un gestor de paquetes para la web que fue creado por Twitter. Gestiona componentes que contienen HTML, CSS, JavaScript, fuentes y archivos de imagen. Mientras se deprecató a favor de npm y Yarn, Bower todavía se utiliza en muchos proyectos heredados y entender que es importante para mantener bases de código existentes.
Tabla de contenidos¶
- Instalación
- [Empezar] (Pruébalo)
- [Manejo de Paquetes]
- Configuración
- Bower.json
- [Paquetes de búsqueda] (paquetes de búsqueda)
- Gestión de la Versión
- [Paquetes privados] (paquetes privados)
- Integración
- [Estrategias de migración] (Estrategias de migración)
- [Troubleshooting] (#troubleshooting)
- [Mantenimiento del Proyecto Legislativo] (Mantenimiento del proyecto delegado)
- Alternativos
- [Prácticas mejores] (prácticas mejores)
Instalación¶
Global installation¶
# Install Bower globally (requires Node.js)
npm install -g bower
# Verify installation
bower --version
# Check Bower help
bower help
Requisitos del sistema¶
# Bower requires Node.js and npm
node --version # Should be >= 0.10.0
npm --version # Should be >= 1.4.3
# Git is also required for many packages
git --version
Project Setup¶
# Create project directory
mkdir my-bower-project
cd my-bower-project
# Initialize bower.json
bower init
# Create typical project structure
mkdir -p {css,js,images}
touch index.html
Bower Configuration¶
# Create .bowerrc configuration file
echo '{
"directory": "bower_components",
"analytics": false,
"timeout": 120000,
"registry": {
"search": [
"https://registry.bower.io"
]
}
}' > .bowerrc
Get Started¶
Basic Commands¶
# Install a package
bower install jquery
# Install specific version
bower install jquery#2.2.4
# Install and save to bower.json
bower install jquery --save
# Install dev dependencies
bower install jasmine --save-dev
# Install from different sources
bower install https://github.com/user/package.git
bower install user/repo
bower install http://example.com/script.js
Información del paquete¶
# List installed packages
bower list
# List with details
bower list --json
# Show package information
bower info jquery
# Search for packages
bower search jquery
# Lookup package details
bower lookup jquery
Estructura básica del proyecto¶
my-bower-project/
├── bower_components/ # Installed packages (auto-generated)
│ ├── jquery/
│ ├── bootstrap/
│ └── ...
├── css/ # Your CSS files
├── js/ # Your JavaScript files
├── images/ # Your images
├── bower.json # Bower configuration
├── .bowerrc # Bower settings
└── index.html # Main HTML file
Simple HTML Integration¶
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bower Project</title>
<!-- Bootstrap CSS from Bower -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<!-- Your custom CSS -->
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="container">
<h1>Hello Bower!</h1>
<button id="test-btn" class="btn btn-primary">Test jQuery</button>
</div>
<!-- jQuery from Bower -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap JS from Bower -->
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Your custom JavaScript -->
<script src="js/main.js"></script>
</body>
</html>
Package Management¶
Instalación de paquetes¶
# Install latest version
bower install angular
# Install specific version
bower install angular#1.6.10
# Install version range
bower install angular#~1.6.0 # Compatible with 1.6.x
bower install angular#^1.6.0 # Compatible with 1.x.x
# Install from Git
bower install https://github.com/angular/angular.js.git
# Install from Git with tag
bower install https://github.com/angular/angular.js.git#v1.6.10
# Install from shorthand
bower install angular/angular.js
# Install from URL
bower install https://code.jquery.com/jquery-3.6.0.min.js
# Install multiple packages
bower install jquery bootstrap angular
Saving Dependencies¶
# Save to dependencies
bower install jquery --save
# Save to devDependencies
bower install jasmine --save-dev
# Install all dependencies from bower.json
bower install
# Install production dependencies only
bower install --production
Updating Packages¶
# Update all packages
bower update
# Update specific package
bower update jquery
# Update to latest version (ignoring bower.json constraints)
bower install jquery#latest --save
# Check for outdated packages
bower list --json | grep -A 5 -B 5 "extraneous\|missing\|incompatible"
Removing Packages¶
# Uninstall package
bower uninstall jquery
# Uninstall and remove from bower.json
bower uninstall jquery --save
# Uninstall dev dependency
bower uninstall jasmine --save-dev
# Clean cache
bower cache clean
# Clean specific package cache
bower cache clean jquery
Configuración¶
.bowerrc Configuración¶
{
"directory": "bower_components",
"analytics": false,
"timeout": 120000,
"interactive": true,
"resolvers": [
"bower-npm-resolver"
],
"registry": {
"search": [
"https://registry.bower.io"
],
"register": "https://registry.bower.io",
"publish": "https://registry.bower.io"
},
"shorthand-resolver": "git://github.com/{{owner}}/{{package}}.git",
"proxy": "http://proxy.company.com:8080",
"https-proxy": "https://proxy.company.com:8080",
"ca": {
"search": [
"/path/to/certificate.pem"
]
},
"color": true,
"storage": {
"packages": "~/.bower/packages",
"registry": "~/.bower/registry",
"links": "~/.bower/links"
}
}
Configuración Global¶
# Set global configuration
bower config set directory public/vendor
# Get configuration value
bower config get directory
# List all configuration
bower config list
# Remove configuration
bower config delete directory
Environment Variables¶
# Set Bower configuration via environment variables
export bower_directory=public/vendor
export bower_analytics=false
export bower_timeout=120000
# HTTP proxy settings
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=https://proxy.company.com:8080
Custom Resolvers¶
Bower.json¶
Basic bower.json¶
{
"name": "my-project",
"description": "My awesome web project",
"version": "1.0.0",
"homepage": "https://github.com/user/my-project",
"authors": [
"John Doe <john@example.com>"
],
"main": [
"dist/my-project.js",
"dist/my-project.css"
],
"keywords": [
"web",
"frontend",
"javascript"
],
"license": "MIT",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"jquery": "^3.6.0",
"bootstrap": "^4.6.0",
"angular": "~1.6.0"
},
"devDependencies": {
"jasmine": "^3.6.0",
"qunit": "^2.14.0"
}
}
Advanced bower.json¶
{
"name": "advanced-project",
"version": "2.1.0",
"description": "Advanced Bower project configuration",
"main": [
"dist/advanced-project.js",
"dist/advanced-project.css"
],
"dependencies": {
"jquery": "^3.6.0",
"bootstrap": "^4.6.0",
"lodash": "^4.17.21",
"moment": "^2.29.0"
},
"devDependencies": {
"jasmine": "^3.6.0",
"sinon": "^11.1.0"
},
"overrides": {
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/js/bootstrap.js"
]
},
"font-awesome": {
"main": [
"css/font-awesome.css"
]
}
},
"resolutions": {
"jquery": "^3.6.0"
},
"moduleType": [
"amd",
"globals"
],
"keywords": [
"frontend",
"web",
"javascript",
"css"
],
"authors": [
"Development Team <dev@company.com>"
],
"license": "MIT",
"homepage": "https://company.com/project",
"repository": {
"type": "git",
"url": "git://github.com/company/project.git"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"src",
"gulpfile.js",
"package.json"
]
}
Package Overrides¶
{
"overrides": {
"bootstrap": {
"main": [
"dist/css/bootstrap.min.css",
"dist/js/bootstrap.min.js"
],
"dependencies": {
"jquery": "^3.0.0"
}
},
"font-awesome": {
"main": [
"css/font-awesome.min.css"
]
},
"chosen": {
"main": [
"chosen.jquery.min.js",
"chosen.min.css"
],
"dependencies": {
"jquery": ">=1.4"
}
}
}
}
Version Resolutions¶
Buscar paquetes¶
Search Commands¶
# Search for packages
bower search jquery
# Search with more details
bower search angular --json
# Search for specific functionality
bower search "date picker"
bower search carousel
bower search validation
# Popular searches
bower search bootstrap
bower search fontawesome
bower search moment
bower search lodash
Información del paquete¶
# Get package info
bower info jquery
# Get specific version info
bower info jquery#3.6.0
# Get detailed JSON info
bower info angular --json
# Check package versions
bower info bootstrap | grep "Available versions"
# Lookup package registry info
bower lookup jquery
Registry Browsing¶
# Browse packages online
# Visit: https://bower.io/search/
# Popular categories:
# - UI Frameworks: bootstrap, foundation, semantic-ui
# - JavaScript Libraries: jquery, lodash, underscore
# - MV* Frameworks: angular, backbone, ember
# - CSS Preprocessors: sass, less, stylus
# - Icon Fonts: font-awesome, glyphicons
# - Date/Time: moment, date-fns
# - Charts: d3, chart.js, highcharts
Version Management¶
Version Syntax¶
# Exact version
bower install jquery#3.6.0
# Range versions
bower install jquery#>=3.0.0
bower install jquery#>3.0.0 <4.0.0
# Tilde versions (patch-level changes)
bower install jquery#~3.6.0 # >=3.6.0 <3.7.0
# Caret versions (compatible changes)
bower install jquery#^3.6.0 # >=3.6.0 <4.0.0
# Latest version
bower install jquery#latest
# Prerelease versions
bower install angular#1.7.0-rc.0
Version Constraints¶
{
"dependencies": {
"jquery": "~3.6.0", // Patch updates only
"bootstrap": "^4.6.0", // Minor updates allowed
"angular": ">=1.6.0 <2.0.0", // Range specification
"lodash": "latest", // Always latest
"moment": "2.29.1" // Exact version
}
}
Checking Versions¶
# List installed versions
bower list
# Check for updates
bower list --json | grep -E "(update|latest)"
# Show version tree
bower list --paths
# Check specific package versions
bower info jquery versions --json
Version Conflicts¶
# Resolve conflicts interactively
bower install
# Force resolution
bower install --force-latest
# Use specific resolution
bower install jquery#3.6.0 --save
# Check resolution status
bower list --json | grep -A 5 -B 5 "incompatible"
Private Packages¶
Creación de paquetes privados¶
{
"name": "my-private-package",
"version": "1.0.0",
"private": true,
"main": [
"dist/my-package.js",
"dist/my-package.css"
],
"dependencies": {
"jquery": "^3.6.0"
}
}
Instalación de paquetes privados¶
# Install from private Git repository
bower install git@github.com:company/private-package.git
# Install from private Git with SSH key
bower install git+ssh://git@github.com:company/private-package.git
# Install from private URL
bower install https://private-registry.company.com/packages/my-package.tar.gz
# Install with authentication
bower install https://username:password@private-repo.com/package.git
Private Registry¶
{
"registry": {
"search": [
"https://private-registry.company.com",
"https://registry.bower.io"
],
"register": "https://private-registry.company.com",
"publish": "https://private-registry.company.com"
}
}
Authentication¶
# Set up Git credentials for private repos
git config --global credential.helper store
# Use SSH keys for private repositories
ssh-keygen -t rsa -b 4096 -C "your_email@company.com"
ssh-add ~/.ssh/id_rsa
# Configure Git to use SSH
git config --global url."git@github.com:".insteadOf "https://github.com/"
Integration¶
Grunt Integration¶
// Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
bower: {
install: {
options: {
targetDir: './public/vendor',
layout: 'byType',
install: true,
verbose: false,
cleanTargetDir: false,
cleanBowerDir: false,
bowerOptions: {}
}
}
},
// Copy bower components
copy: {
bower: {
files: [{
expand: true,
cwd: 'bower_components',
src: [
'jquery/dist/jquery.min.js',
'bootstrap/dist/css/bootstrap.min.css',
'bootstrap/dist/js/bootstrap.min.js'
],
dest: 'public/vendor',
flatten: true
}]
}
}
});
grunt.loadNpmTasks('grunt-bower-task');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['bower', 'copy:bower']);
};
Gulp Integration¶
// gulpfile.js
const gulp = require('gulp');
const bower = require('gulp-bower');
const mainBowerFiles = require('main-bower-files');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');
const cssmin = require('gulp-cssmin');
// Install bower dependencies
gulp.task('bower', function() {
return bower();
});
// Process bower files
gulp.task('bower-js', function() {
return gulp.src(mainBowerFiles('**/*.js'))
.pipe(concat('vendor.js'))
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
gulp.task('bower-css', function() {
return gulp.src(mainBowerFiles('**/*.css'))
.pipe(concat('vendor.css'))
.pipe(cssmin())
.pipe(gulp.dest('dist/css'));
});
// Copy bower fonts
gulp.task('bower-fonts', function() {
return gulp.src(mainBowerFiles('**/*.{eot,svg,ttf,woff,woff2}'))
.pipe(gulp.dest('dist/fonts'));
});
gulp.task('build', gulp.series('bower', 'bower-js', 'bower-css', 'bower-fonts'));
Integración de la Webpack¶
// webpack.config.js
const path = require('path');
module.exports = {
resolve: {
modules: [
path.resolve('./bower_components'),
path.resolve('./node_modules')
],
alias: {
'jquery': path.resolve('./bower_components/jquery/dist/jquery.min.js'),
'bootstrap': path.resolve('./bower_components/bootstrap/dist/js/bootstrap.min.js')
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
]
};
RequireJS Integración¶
// main.js
require.config({
baseUrl: '.',
paths: {
'jquery': 'bower_components/jquery/dist/jquery.min',
'bootstrap': 'bower_components/bootstrap/dist/js/bootstrap.min',
'lodash': 'bower_components/lodash/lodash.min',
'angular': 'bower_components/angular/angular.min'
},
shim: {
'bootstrap': {
deps: ['jquery']
},
'angular': {
exports: 'angular'
}
}
});
require(['jquery', 'bootstrap'], function($) {
$(document).ready(function() {
console.log('jQuery and Bootstrap loaded via RequireJS');
});
});
Migration Strategies¶
Migrando a npm¶
# 1. Analyze current bower dependencies
bower list --json > bower-dependencies.json
# 2. Find npm equivalents
# Many packages are available on both registries
npm search jquery
npm search bootstrap
npm search angular
# 3. Install npm equivalents
npm install jquery bootstrap angular --save
# 4. Update HTML references
# From: bower_components/jquery/dist/jquery.min.js
# To: node_modules/jquery/dist/jquery.min.js
# 5. Use bundler (webpack, parcel, etc.)
# Modern approach: import packages in JavaScript
Migration Script¶
// migrate-bower-to-npm.js
const fs = require('fs');
const { execSync } = require('child_process');
// Read bower.json
const bowerJson = JSON.parse(fs.readFileSync('bower.json', 'utf8'));
// Common package name mappings
const packageMappings = {
'angular': '@angular/core',
'jquery': 'jquery',
'bootstrap': 'bootstrap',
'lodash': 'lodash',
'moment': 'moment',
'font-awesome': '@fortawesome/fontawesome-free'
};
// Install npm equivalents
Object.keys(bowerJson.dependencies || {}).forEach(pkg => {
const npmPkg = packageMappings[pkg] || pkg;
const version = bowerJson.dependencies[pkg];
try {
console.log(`Installing ${npmPkg}...`);
execSync(`npm install ${npmPkg} --save`, { stdio: 'inherit' });
} catch (error) {
console.error(`Failed to install ${npmPkg}:`, error.message);
}
});
console.log('Migration complete. Please update your build process and HTML references.');
Webpack Migration¶
// webpack.config.js for migrated project
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'styles.css'
})
]
};
// src/index.js
import 'jquery';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import './styles.css';
console.log('Migrated from Bower to Webpack!');
Troubleshooting¶
Common Issues¶
# Issue: EACCES permission errors
sudo chown -R $(whoami) ~/.npm
sudo chown -R $(whoami) ~/.bower
# Issue: Git not found
# Install Git and add to PATH
git --version
# Issue: Network/proxy problems
bower config set proxy http://proxy.company.com:8080
bower config set https-proxy https://proxy.company.com:8080
# Issue: Registry connection problems
bower cache clean
bower config set registry.search https://registry.bower.io
# Issue: Version conflicts
bower install --force-latest
# Or manually resolve in bower.json resolutions
Debugging¶
# Verbose output
bower install jquery --verbose
# Debug mode
DEBUG=* bower install jquery
# Check configuration
bower config list
# Validate bower.json
bower install --dry-run
# Clear cache
bower cache clean
rm -rf bower_components
bower install
Network Issues¶
# Test registry connectivity
curl -I https://registry.bower.io
# Use different registry
bower config set registry.search https://bower.herokuapp.com/packages
# Increase timeout
bower config set timeout 300000
# Use HTTP instead of HTTPS (not recommended)
bower config set registry.search http://registry.bower.io
Git Issues¶
# Configure Git for Bower
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Fix SSH issues
ssh-keyscan github.com >> ~/.ssh/known_hosts
# Use HTTPS instead of SSH
git config --global url."https://github.com/".insteadOf git@github.com:
git config --global url."https://".insteadOf git://
Legacy Project Maintenance¶
Mantener los proyectos existentes¶
# Audit existing bower.json
bower list --json | jq '.dependencies'
# Check for security vulnerabilities
# (Note: Bower doesn't have built-in security audit)
# Manually check package versions against known vulnerabilities
# Update packages safely
bower update --save
# Lock versions for stability
# Use exact versions in bower.json
{
"dependencies": {
"jquery": "3.6.0",
"bootstrap": "4.6.0"
}
}
```_
### Documentation
```markdown
# Legacy Bower Project
## Setup
1. Install Node.js and npm
2. Install Bower globally: `npm install -g bower`
3. Install dependencies: `bower install`
## Dependencies
- jQuery 3.6.0 - DOM manipulation
- Bootstrap 4.6.0 - CSS framework
- Angular 1.6.10 - MV* framework
## Maintenance Notes
- This project uses Bower (deprecated)
- Consider migrating to npm/webpack for future development
- Security updates must be managed manually
Consideraciones de seguridad¶
# Regular dependency updates
bower update
# Monitor security advisories manually
# Check GitHub security advisories for each package
# Subscribe to security mailing lists
# Use Snyk or similar tools for vulnerability scanning
npm install -g snyk
snyk test --file=bower.json
Alternatives¶
Modern Package Managers¶
# npm (recommended)
npm install jquery bootstrap
# Yarn
yarn add jquery bootstrap
# pnpm
pnpm add jquery bootstrap
# Comparison:
# - npm: Standard Node.js package manager
# - Yarn: Fast, reliable, secure dependency management
# - pnpm: Efficient disk space usage with hard links
Herramientas de construcción modernas¶
# Webpack
npm install --save-dev webpack webpack-cli
# Handles dependencies, bundling, and optimization
# Parcel
npm install --save-dev parcel
# Zero-configuration build tool
# Vite
npm create vite@latest my-project
# Fast build tool with instant HMR
# Rollup
npm install --save-dev rollup
# Module bundler for libraries
CDN Alternativas¶
<!-- Use CDNs instead of local package management -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Or use ES modules -->
<script type="module">
import { createApp } from 'https://unpkg.com/vue@next/dist/vue.esm-browser.js'
// Your code here
</script>
```_
#### Module Bundlers
```javascript
// Modern approach with ES modules
import $ from 'jquery';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap';
// Your application code
$('#myButton').click(() => {
console.log('Button clicked!');
});
Buenas prácticas¶
Project Organization¶
project/
├── bower_components/ # Bower packages (gitignored)
├── src/ # Source files
│ ├── css/
│ ├── js/
│ └── images/
├── dist/ # Built files
├── bower.json # Bower configuration
├── .bowerrc # Bower settings
├── .gitignore # Git ignore rules
└── README.md # Project documentation
.gitignore for Bower Projects¶
# Bower components
bower_components/
# Build outputs
dist/
build/
# Logs
*.log
# OS generated files
.DS_Store
Thumbs.db
# IDE files
.vscode/
.idea/
*.swp
*.swo
Version Management¶
{
"dependencies": {
"jquery": "~3.6.0", // Patch updates only
"bootstrap": "^4.6.0", // Minor updates allowed
"angular": "1.6.10" // Exact version for stability
},
"resolutions": {
"jquery": "3.6.0" // Force specific version
}
}
Performance Optimization¶
# Minimize bower_components size
bower install --production
# Use main files only
# Configure build tools to use only necessary files
# Example: bootstrap/dist/css/bootstrap.min.css instead of entire package
Seguridad Buenas Prácticas¶
** Actualizaciones periódicas**: Mantener las dependencias actualizadas - # Version Pinning # Utilizar versiones exactas para dependencias críticas - * Auditoría manual* Comprobación regular para asesorías de seguridad * Dependencias mínimas* Sólo instala lo que necesitas - ** Planificación de la migración**: Planificar la migración a herramientas modernas
Recomendaciones de migración¶
- Audit Current Dependencies: Document all Bower package
- Encontrar npm Equivalentes: La mayoría de los paquetes están disponibles en npm
- Actualizar el proceso de construcción: Migrar a Webpack, Parcel o Vite
- Test Thoroughly: Garantizar la funcionalidad después de la migración
- Actualizar documentación: Documentar el nuevo proceso de configuración
-...
Summary¶
Bower fue un importante gestor de paquetes para el desarrollo de frontend que sirvió a la comunidad web bien antes de que Npm se convirtió en el estándar. Mientras se deprecató, entender Bower es crucial para:
Mantenimiento del proyecto de ley: Muchos proyectos existentes todavía utilizan Bower Contexto histórico: Comprender la evolución de la herramienta de frontend - ** Planificación de la Migración**: Saber emigrar a alternativas modernas
Key Bower Concepts: - ** Árbol de dependencia ausente**: Evita las dependencias anidadas - A base de datos: Paquetes almacenados en los repositorios de Git focado en la web: Diseñado específicamente para activos de frontend - Configuración sencilla: Inclinación fácil. json setup
** Alternativas modernas:** - npm: Standard Node.js package manager - Arn: Gestión rápida y fiable de la dependencia CDNs: Inclusión directa de las redes de distribución de contenidos - ES Módulos: Soporte del módulo del navegador nativo
Para nuevos proyectos, utilice Npm, Yarn o herramientas de construcción modernas como Webpack, Vite o Parcel. Para los proyectos existentes de Bower, planifique una migración gradual manteniendo la funcionalidad actual.
__HTML_TAG_71_ copia de la funciónToClipboard() {} comandos const = document.querySelectorAll('code'); que todos losCommands = '; comandos. paraCada(cmd = confianza allCommands += cmd.textContent + '\n'); navigator.clipboard.writeText(allCommands); alerta ('Todos los comandos copiados a portapapeles!'); }
función generaPDF() { ventana.print(); }